From: terencehill Date: Sun, 13 Mar 2016 13:13:44 +0000 (+0100) Subject: Merge branch 'master' into terencehill/translate_colors_2 X-Git-Tag: xonotic-v0.8.2~935^2~3 X-Git-Url: https://git.xonotic.org/?a=commitdiff_plain;h=e0e847a336cdb7ab1fcb93d3cf3e1402b761a726;hp=bb56fe5f488da2f2707876a98cc13db379c6c91b;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'master' into terencehill/translate_colors_2 --- diff --git a/.gitignore b/.gitignore index 6ecb3d2eb..f4611af93 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ -csprogs.dat -menu.dat -progs.dat -*.lno +/*.dat +/*.lno + .DS_Store .idea/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 291548800..d638b6e00 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,7 +27,7 @@ test_sv_game: script: - wget -O data/g-23.pk3 http://beta.xonotic.org/autobuild-bsp/latest/g-23.pk3 - make - - EXPECT=4c308ac459a47a3641c8a1934d13667c + - EXPECT=44a15d27dcfb0bccddc73284e6d968e7 - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg | tee /dev/stderr | grep '^:' diff --git a/bal-wep-xonotic.cfg b/bal-wep-xonotic.cfg index 07005ccc3..7cb9d9f4c 100644 --- a/bal-wep-xonotic.cfg +++ b/bal-wep-xonotic.cfg @@ -219,7 +219,7 @@ set g_balance_electro_secondary_speed 1000 set g_balance_electro_secondary_speed_up 200 set g_balance_electro_secondary_speed_z 0 set g_balance_electro_secondary_spread 0.04 -set g_balance_electro_secondary_touchexplode 0 +set g_balance_electro_secondary_touchexplode 1 set g_balance_electro_switchdelay_drop 0.2 set g_balance_electro_switchdelay_raise 0.2 set g_balance_electro_weaponreplace "" @@ -242,7 +242,7 @@ set g_balance_crylink_primary_joinexplode_edgedamage 0 set g_balance_crylink_primary_joinexplode_force 0 set g_balance_crylink_primary_joinexplode_radius 0 set g_balance_crylink_primary_joinspread 0.2 -set g_balance_crylink_primary_linkexplode 1 +set g_balance_crylink_primary_linkexplode 0 set g_balance_crylink_primary_middle_fadetime 5 set g_balance_crylink_primary_middle_lifetime 5 set g_balance_crylink_primary_other_fadetime 5 @@ -725,7 +725,7 @@ 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_ammo 6 set g_balance_arc_beam_animtime 0.2 set g_balance_arc_beam_botaimlifetime 0 set g_balance_arc_beam_botaimspeed 0 @@ -736,20 +736,20 @@ 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_amax 0 set g_balance_arc_beam_healing_aps 50 set g_balance_arc_beam_healing_hmax 150 set g_balance_arc_beam_healing_hps 50 set g_balance_arc_cooldown 2.5 -set g_balance_arc_cooldown_release 1 +set g_balance_arc_cooldown_release 0 set g_balance_arc_overheat_max 5 set g_balance_arc_overheat_min 3 -set g_balance_arc_beam_heat 1 +set g_balance_arc_beam_heat 0.75 set g_balance_arc_burst_heat 4 set g_balance_arc_beam_maxangle 10 set g_balance_arc_beam_nonplayerdamage 80 set g_balance_arc_beam_range 1000 -set g_balance_arc_beam_refire 0.5 +set g_balance_arc_beam_refire 0.25 set g_balance_arc_beam_returnspeed 8 set g_balance_arc_beam_tightness 0.5 set g_balance_arc_bolt 0 @@ -757,19 +757,19 @@ set g_balance_arc_bolt_ammo 1 set g_balance_arc_bolt_damage 25 set g_balance_arc_bolt_damageforcescale 0 set g_balance_arc_bolt_edgedamage 12.5 -set g_balance_arc_bolt_force 100 +set g_balance_arc_bolt_force 120 set g_balance_arc_bolt_health 15 set g_balance_arc_bolt_lifetime 5 set g_balance_arc_bolt_radius 65 set g_balance_arc_bolt_refire 0.16667 set g_balance_arc_bolt_speed 2200 -set g_balance_arc_bolt_spread 0.03 +set g_balance_arc_bolt_spread 0 set g_balance_arc_burst_ammo 15 set g_balance_arc_burst_damage 250 set g_balance_arc_burst_healing_aps 100 set g_balance_arc_burst_healing_hps 100 -set g_balance_arc_switchdelay_drop 0.3 -set g_balance_arc_switchdelay_raise 0.3 +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 diff --git a/bal-wep-xpm.cfg b/bal-wep-xpm.cfg index 07005ccc3..7cb9d9f4c 100644 --- a/bal-wep-xpm.cfg +++ b/bal-wep-xpm.cfg @@ -219,7 +219,7 @@ set g_balance_electro_secondary_speed 1000 set g_balance_electro_secondary_speed_up 200 set g_balance_electro_secondary_speed_z 0 set g_balance_electro_secondary_spread 0.04 -set g_balance_electro_secondary_touchexplode 0 +set g_balance_electro_secondary_touchexplode 1 set g_balance_electro_switchdelay_drop 0.2 set g_balance_electro_switchdelay_raise 0.2 set g_balance_electro_weaponreplace "" @@ -242,7 +242,7 @@ set g_balance_crylink_primary_joinexplode_edgedamage 0 set g_balance_crylink_primary_joinexplode_force 0 set g_balance_crylink_primary_joinexplode_radius 0 set g_balance_crylink_primary_joinspread 0.2 -set g_balance_crylink_primary_linkexplode 1 +set g_balance_crylink_primary_linkexplode 0 set g_balance_crylink_primary_middle_fadetime 5 set g_balance_crylink_primary_middle_lifetime 5 set g_balance_crylink_primary_other_fadetime 5 @@ -725,7 +725,7 @@ 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_ammo 6 set g_balance_arc_beam_animtime 0.2 set g_balance_arc_beam_botaimlifetime 0 set g_balance_arc_beam_botaimspeed 0 @@ -736,20 +736,20 @@ 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_amax 0 set g_balance_arc_beam_healing_aps 50 set g_balance_arc_beam_healing_hmax 150 set g_balance_arc_beam_healing_hps 50 set g_balance_arc_cooldown 2.5 -set g_balance_arc_cooldown_release 1 +set g_balance_arc_cooldown_release 0 set g_balance_arc_overheat_max 5 set g_balance_arc_overheat_min 3 -set g_balance_arc_beam_heat 1 +set g_balance_arc_beam_heat 0.75 set g_balance_arc_burst_heat 4 set g_balance_arc_beam_maxangle 10 set g_balance_arc_beam_nonplayerdamage 80 set g_balance_arc_beam_range 1000 -set g_balance_arc_beam_refire 0.5 +set g_balance_arc_beam_refire 0.25 set g_balance_arc_beam_returnspeed 8 set g_balance_arc_beam_tightness 0.5 set g_balance_arc_bolt 0 @@ -757,19 +757,19 @@ set g_balance_arc_bolt_ammo 1 set g_balance_arc_bolt_damage 25 set g_balance_arc_bolt_damageforcescale 0 set g_balance_arc_bolt_edgedamage 12.5 -set g_balance_arc_bolt_force 100 +set g_balance_arc_bolt_force 120 set g_balance_arc_bolt_health 15 set g_balance_arc_bolt_lifetime 5 set g_balance_arc_bolt_radius 65 set g_balance_arc_bolt_refire 0.16667 set g_balance_arc_bolt_speed 2200 -set g_balance_arc_bolt_spread 0.03 +set g_balance_arc_bolt_spread 0 set g_balance_arc_burst_ammo 15 set g_balance_arc_burst_damage 250 set g_balance_arc_burst_healing_aps 100 set g_balance_arc_burst_healing_hps 100 -set g_balance_arc_switchdelay_drop 0.3 -set g_balance_arc_switchdelay_raise 0.3 +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 diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg index 7bc9466eb..8ef0f0da2 100644 --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@ -161,30 +161,23 @@ cl_bobfallcycle 3 "speed of the bobfall swing" cl_bobfallspeed 200 "necessary amount of speed for bob-falling to occur" cl_bobmodel 1 // whether to have gun model move around on screen when moving (only works if cl_bob is not 0), default is 1 cl_bobmodel_side 0.2 // amount the gun sways to the sides -cl_bobmodel_speed 5 // rate at which the gun sways +cl_bobmodel_speed 10 // rate at which the gun sways cl_bobmodel_up 0.1 // amount the gun sways up and down -cl_leanmodel 1 // enables weapon leaning effect when looking around -cl_leanmodel_side_speed 0.7 "gun leaning sideways speed" -cl_leanmodel_side_limit 35 "gun leaning sideways limit" -cl_leanmodel_side_highpass1 30 "gun leaning sideways pre-highpass in 1/s" -cl_leanmodel_side_highpass 3 "gun leaning sideways highpass in 1/s" -cl_leanmodel_side_lowpass 20 "gun leaning sideways lowpass in 1/s" -cl_leanmodel_up_speed 0.65 "gun leaning upward speed" -cl_leanmodel_up_limit 50 "gun leaning upward limit" -cl_leanmodel_up_highpass1 5 "gun leaning upward pre-highpass in 1/s" -cl_leanmodel_up_highpass 15 "gun leaning upward highpass in 1/s" -cl_leanmodel_up_lowpass 20 "gun leaning upward lowpass in 1/s" + cl_followmodel 1 // enables weapon pushing / pulling effect when walking -cl_followmodel_side_speed 0.25 "gun following sideways speed" -cl_followmodel_side_limit 6 "gun following sideways limit" -cl_followmodel_side_highpass1 30 "gun following sideways pre-highpass in 1/s" -cl_followmodel_side_highpass 5 "gun following sideways highpass in 1/s" -cl_followmodel_side_lowpass 10 "gun following sideways lowpass in 1/s" -cl_followmodel_up_speed 0.5 "gun following upward speed" -cl_followmodel_up_limit 5 "gun following upward limit" -cl_followmodel_up_highpass1 60 "gun following upward pre-highpass in 1/s" -cl_followmodel_up_highpass 2 "gun following upward highpass in 1/s" -cl_followmodel_up_lowpass 10 "gun following upward lowpass in 1/s" +seta cl_followmodel_speed 0.3 "gun following speed" +seta cl_followmodel_limit 135 "gun following limit" +seta cl_followmodel_velocity_absolute 0 "make the effect ignore velocity direction changes (side effect: it causes a glitch when teleporting / passing through a warpzone)" +seta cl_followmodel_velocity_lowpass 0.05 "gun following velocity lowpass averaging time" +seta cl_followmodel_highpass 0.05 "gun following highpass averaging time" +seta cl_followmodel_lowpass 0.03 "gun following lowpass averaging time" + +cl_leanmodel 1 // enables weapon leaning effect when looking around +seta cl_leanmodel_speed 0.3 "gun leaning speed" +seta cl_leanmodel_limit 30 "gun leaning limit" +seta cl_leanmodel_highpass1 0.2 "gun leaning pre-highpass averaging time" +seta cl_leanmodel_highpass 0.2 "gun leaning highpass averaging time" +seta cl_leanmodel_lowpass 0.05 "gun leaning lowpass averaging time" cl_rollangle 0 // amount of view tilt when strafing, default is 2.0 v_kicktime 0 // how long damage kicks of the view last, default is 0 seconds diff --git a/models/weapons/g_campingrifle.md3 b/models/weapons/g_campingrifle.md3 index 594e706f8..fd829833e 100644 Binary files a/models/weapons/g_campingrifle.md3 and b/models/weapons/g_campingrifle.md3 differ diff --git a/models/weapons/g_hagar.md3 b/models/weapons/g_hagar.md3 index 6e21ba9f8..2047627bf 100644 Binary files a/models/weapons/g_hagar.md3 and b/models/weapons/g_hagar.md3 differ diff --git a/models/weapons/h_hagar.iqm b/models/weapons/h_hagar.iqm index a51c6c4f5..fe87dac03 100644 Binary files a/models/weapons/h_hagar.iqm and b/models/weapons/h_hagar.iqm differ diff --git a/models/weapons/h_hagar.iqm.framegroups b/models/weapons/h_hagar.iqm.framegroups index 0a59625b6..e02cf0f64 100644 --- a/models/weapons/h_hagar.iqm.framegroups +++ b/models/weapons/h_hagar.iqm.framegroups @@ -1,4 +1,9 @@ -1 8 20 0 // fire -9 5 20 0 // fire2 -15 200 20 1 // idle -215 40 20 0 // reload +/* +Generated framegroups file for h_hagar +Used by DarkPlaces to simulate frame groups in DPM models. +*/ + +1 11 15 1 // h_hagar fire +12 9 60 1 // h_hagar fire2 +21 51 5 1 // h_hagar idle +72 21 30 1 // h_hagar reload diff --git a/models/weapons/v_campingrifle.md3 b/models/weapons/v_campingrifle.md3 index 251e79f75..e9990ebc3 100644 Binary files a/models/weapons/v_campingrifle.md3 and b/models/weapons/v_campingrifle.md3 differ diff --git a/models/weapons/v_hagar.md3 b/models/weapons/v_hagar.md3 index 19a245343..f1f08b010 100644 Binary files a/models/weapons/v_hagar.md3 and b/models/weapons/v_hagar.md3 differ diff --git a/monsters.cfg b/monsters.cfg index 2cb6c3e7d..f6eca00d0 100644 --- a/monsters.cfg +++ b/monsters.cfg @@ -20,7 +20,7 @@ set g_monster_spider_attack_web_speed 1300 set g_monster_spider_attack_web_speed_up 150 set g_monster_spider_damageforcescale 0.600000024 set g_monster_spider_health 180 -set g_monster_spider_speed_run 750 +set g_monster_spider_speed_run 500 set g_monster_spider_speed_stop 100 set g_monster_spider_speed_walk 400 // }}} diff --git a/mutators.cfg b/mutators.cfg index dd8d96a56..7e60304cc 100644 --- a/mutators.cfg +++ b/mutators.cfg @@ -182,6 +182,8 @@ set g_nades 0 "enable off-hand grenades" set g_nades_throw_offset "0 0 0" "nade throwing offset" set g_nades_spawn 1 "give nades right away when player spawns rather than delaying entire refire" set g_nades_client_select 0 "allow client side selection of nade type" +set g_nades_pickup 0 "allow picking up thrown nades (not your own)" +set g_nades_pickup_time 2 "time until picked up nade explodes" set g_nades_nade_lifetime 3.5 set g_nades_nade_minforce 400 set g_nades_nade_maxforce 2000 @@ -214,6 +216,7 @@ set g_nades_bonus_type 2 "Type of the bonus grenade. 1:normal 2:napalm 3:ice 4:t set g_nades_bonus_onstrength 1 "Always give bonus grenades to players that have the strength powerup" set g_nades_bonus_max 3 "Maximum number of bonus grenades" set g_nades_bonus_only 0 "Disallow regular nades, only bonus nades can be used" +set g_nades_nade_small 0 "Use smaller nade size, makes shooting them harder, legacy setting" // Bonus score set g_nades_bonus_score_max 120 "Score value that will give a bonus nade" set g_nades_bonus_score_minor 5 "Score given for minor actions (pickups, regular frags etc.)" @@ -403,7 +406,7 @@ set g_breakablehook_owner 0 "allow owner to break their own hook" // =========== // multijump // =========== -seta cl_multijump 0 "allow multijump mutator" +seta cl_multijump 1 "allow multijump mutator" set g_multijump 0 "Number of multiple jumps to allow (jumping again in the air), -1 allows for infinite jumps" set g_multijump_add 0 "0 = make the current z velocity equal to jumpvelocity, 1 = add jumpvelocity to the current z velocity" set g_multijump_speed -999999 "Minimum vertical speed a player must have in order to jump again" diff --git a/notifications.cfg b/notifications.cfg index 513263b71..2ee0a4084 100644 --- a/notifications.cfg +++ b/notifications.cfg @@ -20,6 +20,9 @@ seta notification_ANNCE_ACHIEVEMENT_ELECTROBITCH "2" "0 = disabled, 1 = enabled seta notification_ANNCE_ACHIEVEMENT_IMPRESSIVE "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_ACHIEVEMENT_YODA "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_BEGIN "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" +seta notification_ANNCE_INSTAGIB_LASTSECOND "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" +seta notification_ANNCE_INSTAGIB_NARROWLY "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" +seta notification_ANNCE_INSTAGIB_TERMINATED "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_KILLSTREAK_03 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_KILLSTREAK_05 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_KILLSTREAK_10 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" @@ -27,11 +30,9 @@ seta notification_ANNCE_KILLSTREAK_15 "1" "0 = disabled, 1 = enabled if gentle m seta notification_ANNCE_KILLSTREAK_20 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_KILLSTREAK_25 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_KILLSTREAK_30 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -seta notification_ANNCE_INSTAGIB_LASTSECOND "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -seta notification_ANNCE_INSTAGIB_NARROWLY "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -seta notification_ANNCE_INSTAGIB_TERMINATED "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_MULTIFRAG "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" +seta notification_ANNCE_NUM_10 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_2 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_3 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_4 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" @@ -40,8 +41,8 @@ seta notification_ANNCE_NUM_6 "2" "0 = disabled, 1 = enabled if gentle mode is o seta notification_ANNCE_NUM_7 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_8 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_9 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -seta notification_ANNCE_NUM_10 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_GAMESTART_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" +seta notification_ANNCE_NUM_GAMESTART_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_GAMESTART_2 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_GAMESTART_3 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_GAMESTART_4 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" @@ -50,8 +51,8 @@ seta notification_ANNCE_NUM_GAMESTART_6 "0" "0 = disabled, 1 = enabled if gentle seta notification_ANNCE_NUM_GAMESTART_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_GAMESTART_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_GAMESTART_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -seta notification_ANNCE_NUM_GAMESTART_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_IDLE_1 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" +seta notification_ANNCE_NUM_IDLE_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_IDLE_2 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_IDLE_3 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_IDLE_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" @@ -60,8 +61,8 @@ seta notification_ANNCE_NUM_IDLE_6 "0" "0 = disabled, 1 = enabled if gentle mode seta notification_ANNCE_NUM_IDLE_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_IDLE_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_IDLE_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -seta notification_ANNCE_NUM_IDLE_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_KILL_1 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" +seta notification_ANNCE_NUM_KILL_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_KILL_2 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_KILL_3 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_KILL_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" @@ -70,8 +71,8 @@ seta notification_ANNCE_NUM_KILL_6 "0" "0 = disabled, 1 = enabled if gentle mode seta notification_ANNCE_NUM_KILL_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_KILL_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_KILL_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -seta notification_ANNCE_NUM_KILL_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_RESPAWN_1 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" +seta notification_ANNCE_NUM_RESPAWN_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_RESPAWN_2 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_RESPAWN_3 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_RESPAWN_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" @@ -80,8 +81,8 @@ seta notification_ANNCE_NUM_RESPAWN_6 "0" "0 = disabled, 1 = enabled if gentle m seta notification_ANNCE_NUM_RESPAWN_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_RESPAWN_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_RESPAWN_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -seta notification_ANNCE_NUM_RESPAWN_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_ROUNDSTART_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" +seta notification_ANNCE_NUM_ROUNDSTART_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_ROUNDSTART_2 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_ROUNDSTART_3 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_ROUNDSTART_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" @@ -90,7 +91,6 @@ seta notification_ANNCE_NUM_ROUNDSTART_6 "0" "0 = disabled, 1 = enabled if gentl seta notification_ANNCE_NUM_ROUNDSTART_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_ROUNDSTART_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_NUM_ROUNDSTART_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -seta notification_ANNCE_NUM_ROUNDSTART_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_PREPARE "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_REMAINING_FRAG_1 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_REMAINING_FRAG_2 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" @@ -102,79 +102,77 @@ seta notification_ANNCE_VOTE_ACCEPT "2" "0 = disabled, 1 = enabled if gentle mod seta notification_ANNCE_VOTE_CALL "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" seta notification_ANNCE_VOTE_FAIL "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" -// MSG_INFO notifications (count = 315): -seta notification_INFO_CONNECTING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +// MSG_INFO notifications (count = 316): +seta notification_INFO_CA_JOIN_LATE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CA_LEAVE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CHAT_NOSPECTATORS "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_CAPTURE_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_COINTOSS "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CONNECTING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_CAPTURE_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_CAPTURE_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_CAPTURE_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_CAPTURE_BROKEN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_CAPTURE_BROKEN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_CAPTURE_BROKEN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_CAPTURE_BROKEN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_CAPTURE_BROKEN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_CAPTURE_BROKEN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_CAPTURE_NEUTRAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_CAPTURE_TIME_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_CAPTURE_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_CAPTURE_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_CAPTURE_TIME_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_CAPTURE_TIME_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_CAPTURE_TIME_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_CAPTURE_UNBROKEN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_CAPTURE_TIME_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_CAPTURE_TIME_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_CAPTURE_UNBROKEN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_CAPTURE_UNBROKEN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_CAPTURE_UNBROKEN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_CAPTURE_UNBROKEN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_CAPTURE_UNBROKEN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_CAPTURE_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_DAMAGED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_DAMAGED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_DAMAGED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_DAMAGED_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_DROPPED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_DAMAGED_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_DAMAGED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_DAMAGED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_DROPPED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_DROPPED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_DROPPED_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_DROPPED_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_DROPPED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_DROPPED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_LOST_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_LOST_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_LOST_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_LOST_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_LOST_NEUTRAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_PICKUP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_LOST_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_LOST_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_LOST_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_PICKUP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_PICKUP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_PICKUP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_PICKUP_NEUTRAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_RETURN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_PICKUP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_PICKUP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_PICKUP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_RETURN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_RETURN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_RETURN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_RETURN_MONSTER_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_RETURN_MONSTER_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CTF_RETURN_MONSTER_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_CTF_RETURN_MONSTER_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_COINTOSS "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_JETPACK_NOFUEL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_SUPERSPEC_MISSING_UID "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CA_JOIN_LATE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_CA_LEAVE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_RETURN_MONSTER_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_RETURN_MONSTER_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_RETURN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_RETURN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_CTF_RETURN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_BUFF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_CHEAT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_DROWN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" @@ -183,10 +181,10 @@ seta notification_INFO_DEATH_MURDER_FIRE "1" "0 = off, 1 = print to console, 2 = seta notification_INFO_DEATH_MURDER_LAVA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_MONSTER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_NADE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_DEATH_MURDER_NADE_NAPALM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_DEATH_MURDER_NADE_HEAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_NADE_ICE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_NADE_ICE_FREEZE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_DEATH_MURDER_NADE_HEAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_DEATH_MURDER_NADE_NAPALM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_SHOOTING_STAR "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_SLIME "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_MURDER_SWAMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" @@ -224,10 +222,10 @@ seta notification_INFO_DEATH_SELF_MON_WYVERN "1" "0 = off, 1 = print to console, seta notification_INFO_DEATH_SELF_MON_ZOMBIE_JUMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_SELF_MON_ZOMBIE_MELEE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_SELF_NADE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_DEATH_SELF_NADE_NAPALM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_DEATH_SELF_NADE_HEAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_SELF_NADE_ICE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_SELF_NADE_ICE_FREEZE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_DEATH_SELF_NADE_HEAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_DEATH_SELF_NADE_NAPALM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_SELF_NOAMMO "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_SELF_ROT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_SELF_SHOOTING_STAR "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" @@ -258,79 +256,74 @@ seta notification_INFO_DEATH_SELF_VH_SPID_ROCKET "1" "0 = off, 1 = print to cons seta notification_INFO_DEATH_SELF_VH_WAKI_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_SELF_VH_WAKI_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_SELF_VOID "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_DEATH_TEAMKILL_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_TEAMKILL_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_DEATH_TEAMKILL_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DEATH_TEAMKILL_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_DEATH_TEAMKILL_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_DEATH_TEAMKILL_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_DOMINATION_CAPTURE_TIME "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_FREEZETAG_AUTO_REVIVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_FREEZETAG_FREEZE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_FREEZETAG_REVIVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_FREEZETAG_REVIVED_FALL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_FREEZETAG_REVIVED_NADE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_FREEZETAG_AUTO_REVIVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ROUND_TEAM_WIN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ROUND_TEAM_WIN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ROUND_TEAM_WIN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ROUND_TEAM_WIN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ROUND_PLAYER_WIN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ROUND_TIED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ROUND_OVER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_FREEZETAG_SELF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_GODMODE_OFF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ITEM_BUFF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ITEM_BUFF_LOST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ITEM_BUFF_DROP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ITEM_BUFF_GOT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ITEM_BUFF_LOST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ITEM_WEAPON_DONTHAVE "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ITEM_WEAPON_DROP "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ITEM_WEAPON_GOT "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ITEM_WEAPON_NOAMMO "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ITEM_WEAPON_PRIMORSEC "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ITEM_WEAPON_UNAVAILABLE "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_JETPACK_NOFUEL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_JOIN_CONNECT "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_JOIN_CONNECT_TEAM_RED "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_JOIN_CONNECT_TEAM_BLUE "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_JOIN_CONNECT_TEAM_YELLOW "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_JOIN_CONNECT_TEAM_PINK "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_JOIN_CONNECT_TEAM_RED "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_JOIN_CONNECT_TEAM_YELLOW "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_JOIN_PLAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_JOIN_PLAY_TEAM_RED "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_JOIN_PLAY_TEAM_BLUE "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_JOIN_PLAY_TEAM_YELLOW "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_JOIN_PLAY_TEAM_PINK "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_JOIN_PLAY_TEAM_RED "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_JOIN_PLAY_TEAM_YELLOW "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEEPAWAY_DROPPED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEEPAWAY_PICKUP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_KEYHUNT_CAPTURE_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEYHUNT_CAPTURE_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_KEYHUNT_CAPTURE_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEYHUNT_CAPTURE_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_KEYHUNT_DROP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_KEYHUNT_CAPTURE_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_KEYHUNT_CAPTURE_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEYHUNT_DROP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_KEYHUNT_DROP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEYHUNT_DROP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_KEYHUNT_LOST_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_KEYHUNT_DROP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_KEYHUNT_DROP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEYHUNT_LOST_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_KEYHUNT_LOST_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEYHUNT_LOST_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_KEYHUNT_PICKUP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_KEYHUNT_LOST_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_KEYHUNT_LOST_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEYHUNT_PICKUP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_KEYHUNT_PICKUP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_KEYHUNT_PICKUP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_KEYHUNT_PICKUP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_KEYHUNT_PICKUP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_LMS_FORFEIT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_LMS_NOLIVES "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_MINIGAME_INVITE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_MONSTERS_DISABLED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ONSLAUGHT_CAPTURE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ONSLAUGHT_CPDESTROYED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ONSLAUGHT_CPDESTROYED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ONSLAUGHT_CPDESTROYED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ONSLAUGHT_CPDESTROYED_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ONSLAUGHT_GENDESTROYED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ONSLAUGHT_CPDESTROYED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ONSLAUGHT_CPDESTROYED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ONSLAUGHT_GENDESTROYED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ONSLAUGHT_GENDESTROYED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ONSLAUGHT_GENDESTROYED_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ONSLAUGHT_GENDESTROYED_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ONSLAUGHT_GENDESTROYED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ONSLAUGHT_GENDESTROYED_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_POWERUP_INVISIBILITY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_POWERUP_SHIELD "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_POWERUP_SPEED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" @@ -347,12 +340,19 @@ seta notification_INFO_RACE_NEW_BROKEN "1" "0 = off, 1 = print to console, 2 = p seta notification_INFO_RACE_NEW_IMPROVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_RACE_NEW_MISSING_UID "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_RACE_NEW_SET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_MINIGAME_INVITE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_SCORES_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ROUND_OVER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ROUND_PLAYER_WIN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ROUND_TEAM_WIN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ROUND_TEAM_WIN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ROUND_TEAM_WIN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ROUND_TEAM_WIN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_ROUND_TIED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_SCORES_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" -seta notification_INFO_SCORES_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_SCORES_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_SCORES_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_SCORES_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_SPECTATE_WARNING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_SUPERSPEC_MISSING_UID "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_SUPERWEAPON_PICKUP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_TEAMCHANGE_LARGERTEAM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_TEAMCHANGE_NOTALLOWED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" @@ -363,6 +363,7 @@ seta notification_INFO_WATERMARK "1" "0 = off, 1 = print to console, 2 = print t seta notification_INFO_WEAPON_ACCORDEON_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_WEAPON_ACCORDEON_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_WEAPON_ARC_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" +seta notification_INFO_WEAPON_ARC_MURDER_SPRAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_WEAPON_BLASTER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_WEAPON_BLASTER_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" seta notification_INFO_WEAPON_CRYLINK_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" @@ -419,71 +420,69 @@ 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 = 222): +// MSG_CENTER notifications (count = 224): 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" +seta notification_CENTER_CAMPCHECK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_COINTOSS "1" "0 = off, 1 = centerprint" seta notification_CENTER_COUNTDOWN_BEGIN "1" "0 = off, 1 = centerprint" seta notification_CENTER_COUNTDOWN_GAMESTART "1" "0 = off, 1 = centerprint" seta notification_CENTER_COUNTDOWN_ROUNDSTART "1" "0 = off, 1 = centerprint" seta notification_CENTER_COUNTDOWN_ROUNDSTOP "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ROUND_TIED "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ROUND_OVER "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CAMPCHECK "1" "0 = off, 1 = centerprint" -seta notification_CENTER_COINTOSS "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_CAPTURESHIELD_FREE "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_CAPTURESHIELD_INACTIVE "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_CAPTURESHIELD_SHIELDED "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_CAPTURE_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_CAPTURE_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_CAPTURE_YELLOW "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_CAPTURE_PINK "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_CAPTURE_NEUTRAL "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_CAPTURE_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_CAPTURE_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_CAPTURE_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_FLAG_THROW_PUNISH "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PASS_OTHER_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PASS_OTHER_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PASS_OTHER_YELLOW "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PASS_OTHER_PINK "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PASS_OTHER_NEUTRAL "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PASS_RECEIVED_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PASS_OTHER_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PASS_OTHER_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PASS_OTHER_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PASS_RECEIVED_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PASS_RECEIVED_YELLOW "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PASS_RECEIVED_PINK "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PASS_RECEIVED_NEUTRAL "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PASS_RECEIVED_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PASS_RECEIVED_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PASS_RECEIVED_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PASS_REQUESTED "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PASS_REQUESTING "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PASS_SENT_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PASS_SENT_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PASS_SENT_YELLOW "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PASS_SENT_PINK "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PASS_SENT_NEUTRAL "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PASS_SENT_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PASS_SENT_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PASS_SENT_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_YELLOW "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_PINK "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_NEUTRAL "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_TEAM "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_TEAM_ENEMY "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_ENEMY "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_ENEMY_VERBOSE "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_ENEMY_NEUTRAL "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_ENEMY_TEAM "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_TEAM_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PICKUP_ENEMY_VERBOSE "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PICKUP_NEUTRAL "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PICKUP_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PICKUP_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PICKUP_TEAM "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_TEAM_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_TEAM_YELLOW "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PICKUP_TEAM_ENEMY "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PICKUP_TEAM_NEUTRAL "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_TEAM_PINK "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PICKUP_TEAM_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_YELLOW "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_PINK "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_PICKUP_TEAM_NEUTRAL "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_RETURN_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE_PINK "1" "0 = off, 1 = centerprint" +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_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_RETURN_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_CTF_RETURN_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_RETURN_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_RETURN_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_CTF_RETURN_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_STALEMATE_CARRIER "1" "0 = off, 1 = centerprint" seta notification_CENTER_CTF_STALEMATE_OTHER "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_MURDER_FRAG "1" "0 = off, 1 = centerprint" @@ -494,8 +493,6 @@ seta notification_CENTER_DEATH_MURDER_TYPEFRAG "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_NADE_THROW "1" "0 = off, 1 = centerprint" -seta notification_CENTER_NADE_BONUS "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_AUTOTEAMCHANGE "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_BETRAYAL "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_CAMP "1" "0 = off, 1 = centerprint" @@ -508,9 +505,9 @@ seta notification_CENTER_DEATH_SELF_GENERIC "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_LAVA "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_MONSTER "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_NADE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_DEATH_SELF_NADE_NAPALM "1" "0 = off, 1 = centerprint" -seta notification_CENTER_DEATH_SELF_NADE_ICE_FREEZE "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_NADE_HEAL "1" "0 = off, 1 = centerprint" +seta notification_CENTER_DEATH_SELF_NADE_ICE_FREEZE "1" "0 = off, 1 = centerprint" +seta notification_CENTER_DEATH_SELF_NADE_NAPALM "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_NOAMMO "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_ROT "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_SELF_SHOOTING_STAR "1" "0 = off, 1 = centerprint" @@ -534,27 +531,28 @@ seta notification_CENTER_DEATH_SELF_VOID "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_TEAMKILL_FRAG "1" "0 = off, 1 = centerprint" seta notification_CENTER_DEATH_TEAMKILL_FRAGGED "1" "0 = off, 1 = centerprint" seta notification_CENTER_DISCONNECT_IDLING "1" "0 = off, 1 = centerprint" -seta notification_CENTER_DOOR_LOCKED_NEED "1" "0 = off, 1 = centerprint" seta notification_CENTER_DOOR_LOCKED_ALSONEED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_DOOR_LOCKED_NEED "1" "0 = off, 1 = centerprint" seta notification_CENTER_DOOR_UNLOCKED "1" "0 = off, 1 = centerprint" seta notification_CENTER_EXTRALIVES "1" "0 = off, 1 = centerprint" +seta notification_CENTER_FREEZETAG_AUTO_REVIVED "1" "0 = off, 1 = centerprint" seta notification_CENTER_FREEZETAG_FREEZE "1" "0 = off, 1 = centerprint" seta notification_CENTER_FREEZETAG_FROZEN "1" "0 = off, 1 = centerprint" seta notification_CENTER_FREEZETAG_REVIVE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_FREEZETAG_REVIVE_SELF "1" "0 = off, 1 = centerprint" seta notification_CENTER_FREEZETAG_REVIVED "1" "0 = off, 1 = centerprint" -seta notification_CENTER_FREEZETAG_AUTO_REVIVED "1" "0 = off, 1 = centerprint" -seta notification_CENTER_GENERATOR_UNDERATTACK "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ROUND_TEAM_WIN_RED "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ROUND_TEAM_WIN_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ROUND_TEAM_WIN_YELLOW "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ROUND_TEAM_WIN_PINK "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ROUND_PLAYER_WIN "1" "0 = off, 1 = centerprint" +seta notification_CENTER_FREEZETAG_REVIVE_SELF "1" "0 = off, 1 = centerprint" seta notification_CENTER_FREEZETAG_SELF "1" "0 = off, 1 = centerprint" seta notification_CENTER_FREEZETAG_SPAWN_LATE "1" "0 = off, 1 = centerprint" +seta notification_CENTER_GENERATOR_UNDERATTACK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_INSTAGIB_DOWNGRADE "1" "0 = off, 1 = centerprint" +seta notification_CENTER_INSTAGIB_FINDAMMO "1" "0 = off, 1 = centerprint" +seta notification_CENTER_INSTAGIB_FINDAMMO_FIRST "1" "0 = off, 1 = centerprint" +seta notification_CENTER_INSTAGIB_LIVES_REMAINING "1" "0 = off, 1 = centerprint" seta notification_CENTER_INVASION_SUPERMONSTER "1" "0 = off, 1 = centerprint" seta notification_CENTER_ITEM_BUFF_DROP "1" "0 = off, 1 = centerprint" seta notification_CENTER_ITEM_BUFF_GOT "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ITEM_FUELREGEN_GOT "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ITEM_JETPACK_GOT "1" "0 = off, 1 = centerprint" seta notification_CENTER_ITEM_WEAPON_DONTHAVE "1" "0 = off, 1 = centerprint" seta notification_CENTER_ITEM_WEAPON_DROP "1" "0 = off, 1 = centerprint" seta notification_CENTER_ITEM_WEAPON_GOT "1" "0 = off, 1 = centerprint" @@ -563,49 +561,48 @@ seta notification_CENTER_ITEM_WEAPON_PRIMORSEC "1" "0 = off, 1 = centerprint" seta notification_CENTER_ITEM_WEAPON_UNAVAILABLE "1" "0 = off, 1 = centerprint" seta notification_CENTER_JOIN_NOSPAWNS "1" "0 = off, 1 = centerprint" seta notification_CENTER_JOIN_PREVENT "1" "0 = off, 1 = centerprint" +seta notification_CENTER_JOIN_PREVENT_MINIGAME "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEEPAWAY_DROPPED "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEEPAWAY_PICKUP "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEEPAWAY_PICKUP_SELF "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEEPAWAY_WARN "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEYHUNT_HELP "1" "0 = off, 1 = centerprint" -seta notification_CENTER_KEYHUNT_INTERFERE_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEYHUNT_INTERFERE_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_KEYHUNT_INTERFERE_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEYHUNT_INTERFERE_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_KEYHUNT_INTERFERE_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_KEYHUNT_INTERFERE_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEYHUNT_MEET "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEYHUNT_ROUNDSTART "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEYHUNT_SCAN "1" "0 = off, 1 = centerprint" -seta notification_CENTER_KEYHUNT_START_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEYHUNT_START_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_KEYHUNT_START_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_KEYHUNT_START_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_KEYHUNT_START_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_KEYHUNT_START_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_LMS_NOLIVES "1" "0 = off, 1 = centerprint" -seta notification_CENTER_MISSING_TEAMS "1" "0 = off, 1 = centerprint" seta notification_CENTER_MISSING_PLAYERS "1" "0 = off, 1 = centerprint" -seta notification_CENTER_INSTAGIB_DOWNGRADE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_INSTAGIB_FINDAMMO "1" "0 = off, 1 = centerprint" -seta notification_CENTER_INSTAGIB_FINDAMMO_FIRST "1" "0 = off, 1 = centerprint" -seta notification_CENTER_INSTAGIB_LIVES_REMAINING "1" "0 = off, 1 = centerprint" +seta notification_CENTER_MISSING_TEAMS "1" "0 = off, 1 = centerprint" seta notification_CENTER_MOTD "1" "0 = off, 1 = centerprint" +seta notification_CENTER_NADE "1" "0 = off, 1 = centerprint" +seta notification_CENTER_NADE_BONUS "1" "0 = off, 1 = centerprint" +seta notification_CENTER_NADE_THROW "1" "0 = off, 1 = centerprint" seta notification_CENTER_NIX_COUNTDOWN "1" "0 = off, 1 = centerprint" seta notification_CENTER_NIX_NEWWEAPON "1" "0 = off, 1 = centerprint" -seta notification_CENTER_NADE "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_CAPTURE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ONS_CAPTURE_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_CAPTURE_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ONS_CAPTURE_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_CAPTURE_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ONS_CAPTURE_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ONS_CAPTURE_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_CONTROLPOINT_SHIELDED "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_GENERATOR_SHIELDED "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ONS_NOTSHIELDED_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_NOTSHIELDED_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_ONS_NOTSHIELDED_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_NOTSHIELDED_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ONS_NOTSHIELDED_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_NOTSHIELDED_TEAM "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ONS_NOTSHIELDED_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_TELEPORT "1" "0 = off, 1 = centerprint" seta notification_CENTER_ONS_TELEPORT_ANTISPAM "1" "0 = off, 1 = centerprint" -seta notification_CENTER_OVERTIME_FRAG "1" "0 = off, 1 = centerprint" seta notification_CENTER_OVERTIME_CONTROLPOINT "1" "0 = off, 1 = centerprint" +seta notification_CENTER_OVERTIME_FRAG "1" "0 = off, 1 = centerprint" seta notification_CENTER_OVERTIME_TIME "1" "0 = off, 1 = centerprint" seta notification_CENTER_PORTO_CREATED_IN "1" "0 = off, 1 = centerprint" seta notification_CENTER_PORTO_CREATED_OUT "1" "0 = off, 1 = centerprint" @@ -619,6 +616,13 @@ seta notification_CENTER_POWERUP_SHIELD "1" "0 = off, 1 = centerprint" seta notification_CENTER_POWERUP_SPEED "1" "0 = off, 1 = centerprint" seta notification_CENTER_POWERUP_STRENGTH "1" "0 = off, 1 = centerprint" seta notification_CENTER_RACE_FINISHLAP "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ROUND_OVER "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ROUND_PLAYER_WIN "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ROUND_TEAM_WIN_BLUE "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ROUND_TEAM_WIN_PINK "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ROUND_TEAM_WIN_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ROUND_TEAM_WIN_YELLOW "1" "0 = off, 1 = centerprint" +seta notification_CENTER_ROUND_TIED "1" "0 = off, 1 = centerprint" seta notification_CENTER_SECONDARY_NODAMAGE "1" "0 = off, 1 = centerprint" seta notification_CENTER_SEQUENCE_COMPLETED "1" "0 = off, 1 = centerprint" seta notification_CENTER_SEQUENCE_COUNTER "1" "0 = off, 1 = centerprint" @@ -626,16 +630,15 @@ seta notification_CENTER_SEQUENCE_COUNTER_FEWMORE "1" "0 = off, 1 = centerprint" seta notification_CENTER_SUPERWEAPON_BROKEN "1" "0 = off, 1 = centerprint" seta notification_CENTER_SUPERWEAPON_LOST "1" "0 = off, 1 = centerprint" seta notification_CENTER_SUPERWEAPON_PICKUP "1" "0 = off, 1 = centerprint" -seta notification_CENTER_TEAMCHANGE_RED "1" "0 = off, 1 = centerprint" +seta notification_CENTER_TEAMCHANGE_AUTO "1" "0 = off, 1 = centerprint" seta notification_CENTER_TEAMCHANGE_BLUE "1" "0 = off, 1 = centerprint" -seta notification_CENTER_TEAMCHANGE_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_TEAMCHANGE_PINK "1" "0 = off, 1 = centerprint" -seta notification_CENTER_TEAMCHANGE_AUTO "1" "0 = off, 1 = centerprint" +seta notification_CENTER_TEAMCHANGE_RED "1" "0 = off, 1 = centerprint" seta notification_CENTER_TEAMCHANGE_SPECTATE "1" "0 = off, 1 = centerprint" seta notification_CENTER_TEAMCHANGE_SUICIDE "1" "0 = off, 1 = centerprint" +seta notification_CENTER_TEAMCHANGE_YELLOW "1" "0 = off, 1 = centerprint" seta notification_CENTER_TIMEOUT_BEGINNING "1" "0 = off, 1 = centerprint" seta notification_CENTER_TIMEOUT_ENDING "1" "0 = off, 1 = centerprint" -seta notification_CENTER_JOIN_PREVENT_MINIGAME "1" "0 = off, 1 = centerprint" seta notification_CENTER_VEHICLE_ENTER "1" "0 = off, 1 = centerprint" seta notification_CENTER_VEHICLE_ENTER_GUNNER "1" "0 = off, 1 = centerprint" seta notification_CENTER_VEHICLE_ENTER_STEAL "1" "0 = off, 1 = centerprint" @@ -643,7 +646,7 @@ seta notification_CENTER_VEHICLE_STEAL "1" "0 = off, 1 = centerprint" seta notification_CENTER_VEHICLE_STEAL_SELF "1" "0 = off, 1 = centerprint" seta notification_CENTER_WEAPON_MINELAYER_LIMIT "1" "0 = off, 1 = centerprint" -// MSG_MULTI notifications (count = 152): +// MSG_MULTI notifications (count = 153): seta notification_DEATH_MURDER_BUFF "1" "Enable this multiple notification" seta notification_DEATH_MURDER_CHEAT "1" "Enable this multiple notification" seta notification_DEATH_MURDER_DROWN "1" "Enable this multiple notification" @@ -652,10 +655,10 @@ seta notification_DEATH_MURDER_FIRE "1" "Enable this multiple notification" seta notification_DEATH_MURDER_LAVA "1" "Enable this multiple notification" seta notification_DEATH_MURDER_MONSTER "1" "Enable this multiple notification" seta notification_DEATH_MURDER_NADE "1" "Enable this multiple notification" -seta notification_DEATH_MURDER_NADE_NAPALM "1" "Enable this multiple notification" +seta notification_DEATH_MURDER_NADE_HEAL "1" "Enable this multiple notification" seta notification_DEATH_MURDER_NADE_ICE "1" "Enable this multiple notification" seta notification_DEATH_MURDER_NADE_ICE_FREEZE "1" "Enable this multiple notification" -seta notification_DEATH_MURDER_NADE_HEAL "1" "Enable this multiple notification" +seta notification_DEATH_MURDER_NADE_NAPALM "1" "Enable this multiple notification" seta notification_DEATH_MURDER_SHOOTING_STAR "1" "Enable this multiple notification" seta notification_DEATH_MURDER_SLIME "1" "Enable this multiple notification" seta notification_DEATH_MURDER_SWAMP "1" "Enable this multiple notification" @@ -693,10 +696,10 @@ seta notification_DEATH_SELF_MON_WYVERN "1" "Enable this multiple notification" seta notification_DEATH_SELF_MON_ZOMBIE_JUMP "1" "Enable this multiple notification" seta notification_DEATH_SELF_MON_ZOMBIE_MELEE "1" "Enable this multiple notification" seta notification_DEATH_SELF_NADE "1" "Enable this multiple notification" -seta notification_DEATH_SELF_NADE_NAPALM "1" "Enable this multiple notification" +seta notification_DEATH_SELF_NADE_HEAL "1" "Enable this multiple notification" seta notification_DEATH_SELF_NADE_ICE "1" "Enable this multiple notification" seta notification_DEATH_SELF_NADE_ICE_FREEZE "1" "Enable this multiple notification" -seta notification_DEATH_SELF_NADE_HEAL "1" "Enable this multiple notification" +seta notification_DEATH_SELF_NADE_NAPALM "1" "Enable this multiple notification" seta notification_DEATH_SELF_NOAMMO "1" "Enable this multiple notification" seta notification_DEATH_SELF_ROT "1" "Enable this multiple notification" seta notification_DEATH_SELF_SHOOTING_STAR "1" "Enable this multiple notification" @@ -741,6 +744,7 @@ seta notification_MULTI_INSTAGIB_FINDAMMO "1" "Enable this multiple notification seta notification_WEAPON_ACCORDEON_MURDER "1" "Enable this multiple notification" seta notification_WEAPON_ACCORDEON_SUICIDE "1" "Enable this multiple notification" seta notification_WEAPON_ARC_MURDER "1" "Enable this multiple notification" +seta notification_WEAPON_ARC_MURDER_SPRAY "1" "Enable this multiple notification" seta notification_WEAPON_BLASTER_MURDER "1" "Enable this multiple notification" seta notification_WEAPON_BLASTER_SUICIDE "1" "Enable this multiple notification" seta notification_WEAPON_CRYLINK_MURDER "1" "Enable this multiple notification" @@ -798,46 +802,46 @@ seta notification_WEAPON_VAPORIZER_MURDER "1" "Enable this multiple notification seta notification_WEAPON_VORTEX_MURDER "1" "Enable this multiple notification" // MSG_CHOICE notifications (count = 24): -seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_CAPTURE_BROKEN_YELLOW "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_CAPTURE_BROKEN_YELLOW_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_CTF_CAPTURE_BROKEN_PINK "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_CTF_CAPTURE_BROKEN_PINK_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_CAPTURE_TIME_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_CAPTURE_TIME_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_CAPTURE_BROKEN_YELLOW "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_CAPTURE_BROKEN_YELLOW_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_CAPTURE_TIME_YELLOW "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_CAPTURE_TIME_YELLOW_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_CTF_CAPTURE_TIME_PINK "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_CTF_CAPTURE_TIME_PINK_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_CAPTURE_TIME_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_CAPTURE_TIME_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_CAPTURE_TIME_YELLOW "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_CAPTURE_TIME_YELLOW_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_YELLOW "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_YELLOW_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_PINK "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_PINK_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_PICKUP_TEAM_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_PICKUP_TEAM_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_PICKUP_TEAM_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_PICKUP_TEAM_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_PICKUP_TEAM_YELLOW "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_PICKUP_TEAM_YELLOW_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_PICKUP_TEAM_PINK "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_PICKUP_TEAM_PINK_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" -seta notification_CHOICE_CTF_PICKUP_TEAM_NEUTRAL "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" -seta notification_CHOICE_CTF_PICKUP_TEAM_NEUTRAL_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_YELLOW "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_YELLOW_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_CTF_PICKUP_ENEMY "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_CTF_PICKUP_ENEMY_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_CTF_PICKUP_ENEMY_NEUTRAL "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_CTF_PICKUP_ENEMY_NEUTRAL_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_CTF_PICKUP_ENEMY_TEAM "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_CTF_PICKUP_ENEMY_TEAM_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_PICKUP_TEAM_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_PICKUP_TEAM_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_PICKUP_TEAM_NEUTRAL "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_PICKUP_TEAM_NEUTRAL_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_PICKUP_TEAM_PINK "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_PICKUP_TEAM_PINK_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_PICKUP_TEAM_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_PICKUP_TEAM_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" +seta notification_CHOICE_CTF_PICKUP_TEAM_YELLOW "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" +seta notification_CHOICE_CTF_PICKUP_TEAM_YELLOW_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_FRAG "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" seta notification_CHOICE_FRAG_ALLOWED "1" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" seta notification_CHOICE_FRAGGED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message" @@ -864,4 +868,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 = 802): MSG_ANNCE = 89, MSG_INFO = 315, MSG_CENTER = 222, MSG_MULTI = 152, MSG_CHOICE = 24 +// Notification counts (total = 806): MSG_ANNCE = 89, MSG_INFO = 316, MSG_CENTER = 224, MSG_MULTI = 153, MSG_CHOICE = 24 diff --git a/qcsrc/.gitignore b/qcsrc/.gitignore index 79fce6a59..07a5db11e 100644 --- a/qcsrc/.gitignore +++ b/qcsrc/.gitignore @@ -1,3 +1,3 @@ -html/ -qccversion* -*.d +/html/ +/qccversion* +/*.pk3 diff --git a/qcsrc/Makefile b/qcsrc/Makefile index f6c67bbeb..f6cdc7c20 100644 --- a/qcsrc/Makefile +++ b/qcsrc/Makefile @@ -1,13 +1,29 @@ -SCM := $(shell if [ -d .svn ]; then echo svn; elif [ -d ../.git ]; then echo git; fi) -PERL ?= perl -QCCFLAGS_WATERMARK ?= $(shell git describe) CPP := cc -xc -E QCC ?= gmqcc -NDEBUG ?= 1 + PROGS_OUT ?= $(CURDIR)/.. +WORKDIR ?= ../.tmp + +QCCFLAGS_WATERMARK ?= $(shell git describe --tags --dirty='*') +VER = $(QCCFLAGS_WATERMARK) +NDEBUG ?= 1 BUILD_MOD ?= 0 -QCCVERSIONFILE := qccversion.$(shell (cd server && $(QCC) --version) > qccversion.txt && git hash-object qccversion.txt) +ifndef ZIP + ifneq ($(shell which zip),) + ZIP := zip -9 + endif + ifneq ($(shell which 7z),) + ZIP := 7z a -tzip -mx=9 + endif + ifneq ($(shell which 7za),) + ZIP := 7za a -tzip -mx=9 + endif + ifndef ZIP + $(warning "No zip in ($(PATH))") + ZIP := : zip_not_found + endif +endif # We eventually need to get rid of these QCCFLAGS_WTFS ?= \ @@ -30,48 +46,68 @@ QCCFLAGS ?= \ -frelaxed-switch -freturn-assignments \ $(QCCFLAGS_EXTRA) -# xonotic build system overrides this by command line argument to turn off the update-cvarcount step -XON_BUILDSYSTEM = + .PHONY: all -all: qc +all: qc pk3 -.PHONY: qc -qc: $(PROGS_OUT)/menu.dat $(PROGS_OUT)/progs.dat $(PROGS_OUT)/csprogs.dat +$(WORKDIR): + @mkdir -p $@ .PHONY: clean -clean: - rm -f $(PROGS_OUT)/csprogs.dat - rm -f $(PROGS_OUT)/progs.dat - rm -f $(PROGS_OUT)/menu.dat - rm -f ../.tmp/*.qc - rm -f ../.tmp/*.d - rm -f ../.tmp/*.txt - -$(QCCVERSIONFILE): - $(RM) qccversion.* - echo This file intentionally left blank. > $@ +clean: | $(WORKDIR) + $(RM) $(PROGS_OUT)/csprogs.dat + $(RM) $(PROGS_OUT)/menu.dat + $(RM) $(PROGS_OUT)/progs.dat + $(RM) $(WORKDIR)/*.d + $(RM) $(WORKDIR)/*.qc + $(RM) $(WORKDIR)/*.txt + +.PHONY: qc +qc: $(PROGS_OUT)/csprogs.dat $(PROGS_OUT)/menu.dat $(PROGS_OUT)/progs.dat + +.PHONY: pk3 +pk3: csprogs-$(VER).pk3 + + + + + +%-$(VER).pk3: $(PROGS_OUT)/%.dat + $(eval PROG=$*) + $(eval PK3=$(PROG)-$(VER).pk3) + $(eval TXT=$(PROG)-$(VER).txt) + $(eval DAT=$(PROG)-$(VER).dat) + $(eval LNO=$(PROG)-$(VER).lno) + @ echo "http://xonotic.org" > $(TXT) + @ ln -f $(PROGS_OUT)/$(PROG).dat $(DAT) + @ ln -f $(PROGS_OUT)/$(PROG).lno $(LNO) + @ $(RM) *.pk3 + $(ZIP) $(PK3) $(TXT) $(DAT) $(LNO) + @ $(RM) $(TXT) $(DAT) $(LNO) + +QCCVERSION := $(shell cd lib && $(QCC) --version) +QCCVERSIONFILE := $(WORKDIR)/qccversion.$(shell echo ${QCCVERSION} | git hash-object --stdin) +$(QCCVERSIONFILE): | $(WORKDIR) + @ $(RM) $(WORKDIR)/qccversion.* + @ echo $(QCCVERSION) > $@ -export QCC export CPP +export QCC export QCCDEFS export QCCFLAGS -$(PROGS_OUT)/csprogs.dat: client/progs.inc $(QCCVERSIONFILE) - @echo make[1]: Entering directory \`$(PWD)/client\' - sh ./qcc.sh client $@ $< --include ../.tmp/client.d - -$(PROGS_OUT)/progs.dat: server/progs.inc $(QCCVERSIONFILE) - @echo make[1]: Entering directory \`$(PWD)/server\' - sh ./qcc.sh server $@ $< --include ../.tmp/server.d +$(PROGS_OUT)/csprogs.dat: client/progs.inc $(QCCVERSIONFILE) | $(WORKDIR) + @ echo make[1]: Entering directory \`$(CURDIR)/client\' + @ ./qcc.sh client $@ $< +-include $(WORKDIR)/client.d -$(PROGS_OUT)/menu.dat: menu/progs.inc $(QCCVERSIONFILE) - @echo make[1]: Entering directory \`$(PWD)/menu\' - sh ./qcc.sh menu $@ $< --include ../.tmp/menu.d +$(PROGS_OUT)/progs.dat: server/progs.inc $(QCCVERSIONFILE) | $(WORKDIR) + @ echo make[1]: Entering directory \`$(CURDIR)/server\' + @ ./qcc.sh server $@ $< +-include $(WORKDIR)/server.d -.PHONY: testcase -testcase: - cd testcase && $(QCC) $(QCCDEFS) $(QCCFLAGS) -DTESTCASE="$$TESTCASE" +$(PROGS_OUT)/menu.dat: menu/progs.inc $(QCCVERSIONFILE) | $(WORKDIR) + @ echo make[1]: Entering directory \`$(CURDIR)/menu\' + @ ./qcc.sh menu $@ $< +-include $(WORKDIR)/menu.d diff --git a/qcsrc/client/announcer.qc b/qcsrc/client/announcer.qc index 680060cdb..12d07d150 100644 --- a/qcsrc/client/announcer.qc +++ b/qcsrc/client/announcer.qc @@ -2,7 +2,7 @@ #include "mutators/events.qh" -#include +#include #include bool announcer_1min; @@ -81,7 +81,7 @@ void Announcer_Gamestart() { if(announcer_countdown) { - centerprint_kill(CPID_ROUND); + centerprint_kill(ORDINAL(CPID_ROUND)); if(announcer_countdown) { remove(announcer_countdown); diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index 49cafb896..d48fb6333 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -72,6 +72,8 @@ bool autocvar_cl_spawn_event_particles; bool autocvar_cl_spawn_event_sound = 1; // float autocvar_cl_spawn_point_model; bool autocvar_cl_spawn_point_particles; +float autocvar_cl_spawn_point_dist_min = 1200; +float autocvar_cl_spawn_point_dist_max = 1600; bool autocvar_cl_spawnzoom = 1; float autocvar_cl_spawnzoom_speed = 1; float autocvar_cl_spawnzoom_factor = 2; @@ -193,7 +195,7 @@ float autocvar_hud_dock_alpha; string autocvar_hud_dock_color; bool autocvar_hud_dock_color_team; bool autocvar_hud_panel_ammo; -bool autocvar_hud_panel_ammo_iconalign; // TODO: check if this should be turned into an int +bool autocvar_hud_panel_ammo_iconalign; int autocvar_hud_panel_ammo_maxammo; bool autocvar_hud_panel_ammo_onlycurrent; float autocvar_hud_panel_ammo_noncurrent_alpha = 0.7; @@ -205,8 +207,8 @@ bool autocvar_hud_panel_ammo_text; string autocvar_hud_panel_bg; float autocvar_hud_panel_bg_alpha; float autocvar_hud_panel_bg_border; -vector autocvar_hud_panel_bg_color; // TODO: int? -float autocvar_hud_panel_bg_color_team; // ^ +vector autocvar_hud_panel_bg_color; +float autocvar_hud_panel_bg_color_team; float autocvar_hud_panel_bg_padding; bool autocvar_hud_panel_centerprint; float autocvar_hud_panel_centerprint_align; diff --git a/qcsrc/client/commands/cl_cmd.qc b/qcsrc/client/commands/cl_cmd.qc index 873cef258..b512ba53a 100644 --- a/qcsrc/client/commands/cl_cmd.qc +++ b/qcsrc/client/commands/cl_cmd.qc @@ -395,29 +395,6 @@ void LocalCommand_mv_download(int request, int argc) } } -void LocalCommand_find(int request, int argc) -{ - switch (request) - { - case CMD_REQUEST_COMMAND: - { - FOREACH_ENTITY_CLASS(argv(1), true, LAMBDA(LOG_INFO(etos(it), "\n"))); - return; - } - - default: - { - LOG_INFO("Incorrect parameters for ^2find^7\n"); - } - case CMD_REQUEST_USAGE: - { - LOG_INFO("\nUsage:^3 cl_cmd find classname\n"); - LOG_INFO(" Where 'classname' is the classname to search for.\n"); - return; - } - } -} - void LocalCommand_sendcvar(int request, int argc) { switch (request) @@ -490,38 +467,37 @@ CLIENT_COMMAND(debugmodel, "Spawn a debug model manually") { LocalCommand_debugm CLIENT_COMMAND(handlevote, "System to handle selecting a vote or option") { LocalCommand_handlevote(request, arguments); } CLIENT_COMMAND(hud, "Commands regarding/controlling the HUD system") { LocalCommand_hud(request, arguments); } CLIENT_COMMAND(localprint, "Create your own centerprint sent to yourself") { LocalCommand_localprint(request, arguments); } -CLIENT_COMMAND(find, "Search through entities for matching classname") { LocalCommand_find(request, arguments); } CLIENT_COMMAND(mv_download, "Retrieve mapshot picture from the server") { LocalCommand_mv_download(request, arguments); } CLIENT_COMMAND(sendcvar, "Send a cvar to the server (like weaponpriority)") { LocalCommand_sendcvar(request, arguments); } void LocalCommand_macro_help() { - FOREACH(CLIENT_COMMANDS, true, LAMBDA(LOG_INFOF(" ^2%s^7: %s\n", it.m_name, it.m_description))); + FOREACH(CLIENT_COMMANDS, true, LOG_INFOF(" ^2%s^7: %s\n", it.m_name, it.m_description)); } bool LocalCommand_macro_command(int argc, string command) { string c = strtolower(argv(0)); - FOREACH(CLIENT_COMMANDS, it.m_name == c, LAMBDA( + FOREACH(CLIENT_COMMANDS, it.m_name == c, { it.m_invokecmd(CMD_REQUEST_COMMAND, NULL, argc, command); return true; - )); + }); return false; } bool LocalCommand_macro_usage(int argc) { string c = strtolower(argv(1)); - FOREACH(CLIENT_COMMANDS, it.m_name == c, LAMBDA( + FOREACH(CLIENT_COMMANDS, it.m_name == c, { it.m_invokecmd(CMD_REQUEST_USAGE, NULL, argc, ""); return true; - )); + }); return false; } void LocalCommand_macro_write_aliases(int fh) { - FOREACH(CLIENT_COMMANDS, true, LAMBDA(CMD_Write_Alias("qc_cmd_cl", it.m_name, it.m_description))); + FOREACH(CLIENT_COMMANDS, true, CMD_Write_Alias("qc_cmd_cl", it.m_name, it.m_description)); } diff --git a/qcsrc/client/commands/cl_cmd.qh b/qcsrc/client/commands/cl_cmd.qh index 23d72ff60..d53d1b6a6 100644 --- a/qcsrc/client/commands/cl_cmd.qh +++ b/qcsrc/client/commands/cl_cmd.qh @@ -21,7 +21,7 @@ REGISTRY_SORT(CLIENT_COMMANDS) METHOD(clientcommand_##id, m_invokecmd, void(int request, entity caller, int arguments, string command)) STATIC_INIT(CLIENT_COMMANDS_aliases) { - FOREACH(CLIENT_COMMANDS, true, LAMBDA(localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_cl")))); + FOREACH(CLIENT_COMMANDS, true, localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_cl"))); } #endif diff --git a/qcsrc/client/hud/panel/radar.qc b/qcsrc/client/hud/panel/radar.qc index 4e4f90126..b4986e5e3 100644 --- a/qcsrc/client/hud/panel/radar.qc +++ b/qcsrc/client/hud/panel/radar.qc @@ -332,11 +332,9 @@ void HUD_Radar() draw_teamradar_background(hud_panel_radar_foreground_alpha); - FOREACH_ENTITY_CLASS("radarlink", true, LAMBDA( - draw_teamradar_link(it.origin, it.velocity, it.team); - )); + FOREACH_ENTITY_CLASS("radarlink", true, draw_teamradar_link(it.origin, it.velocity, it.team)); - FOREACH_ENTITY_FLAGS(teamradar_icon, 0xFFFFFF, LAMBDA( + FOREACH_ENTITY_FLAGS(teamradar_icon, 0xFFFFFF, { if ( hud_panel_radar_mouse ) if ( it.health > 0 ) if ( it.team == myteam+1 || gametype == MAPINFO_TYPE_RACE ) @@ -353,13 +351,13 @@ void HUD_Radar() } entity icon = RadarIcons_from(it.teamradar_icon); draw_teamradar_icon(it.origin, icon, it, spritelookupcolor(it, icon.netname, it.teamradar_color), panel_fg_alpha); - )); - AL_EACH(_entcs, e, it != NULL, LAMBDA( + }); + AL_EACH(_entcs, e, it != NULL, { if (!it.m_entcs_private) continue; if (entcs_is_self(it)) continue; color2 = entcs_GetTeam(it.sv_entnum); draw_teamradar_player(it.origin, it.angles, Team_ColorRGB(color2)); - )); + }); draw_teamradar_player(view_origin, view_angles, '1 1 1'); drawresetcliparea(); diff --git a/qcsrc/client/hud/panel/weapons.qc b/qcsrc/client/hud/panel/weapons.qc index 19cfb551c..6e9f13dac 100644 --- a/qcsrc/client/hud/panel/weapons.qc +++ b/qcsrc/client/hud/panel/weapons.qc @@ -76,7 +76,7 @@ void HUD_Weapons() weaponorder_cmp_str = strcat(" ", weaponorder_byimpulse, " "); weapon_cnt = 0; - FOREACH(Weapons, it != WEP_Null && it.impulse >= 0, LAMBDA(weaponorder[weapon_cnt++] = it)); + FOREACH(Weapons, it != WEP_Null && it.impulse >= 0, weaponorder[weapon_cnt++] = it); for(i = weapon_cnt; i < Weapons_MAX; ++i) weaponorder[i] = NULL; heapsort(weapon_cnt, weaponorder_swap, weaponorder_cmp, NULL); @@ -131,10 +131,10 @@ void HUD_Weapons() // get the all-weapons layout int nHidden = 0; WepSet weapons_stat = WepSet_GetFromStat(); - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { if (weapons_stat & it.m_wepset) continue; if (it.spawnflags & WEP_FLAG_MUTATORBLOCKED) nHidden += 1; - )); + }); vector table_size = HUD_GetTableSize_BestItemAR((Weapons_COUNT - 1) - nHidden, padded_panel_size, aspect); columns = table_size.x; rows = table_size.y; diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index aa490aa50..ded6d5b32 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -127,7 +127,7 @@ void CSQC_Init() registercvar("cl_jumpspeedcap_min", ""); registercvar("cl_jumpspeedcap_max", ""); - registercvar("cl_multijump", "0"); + registercvar("cl_multijump", "1"); registercvar("cl_spawn_near_teammate", "1"); @@ -202,6 +202,8 @@ void Shutdown() if(autocvar_chase_active < 0) cvar_set("chase_active", "0"); + cvar_set("slowmo", cvar_defstring("slowmo")); // reset it back to 'default' + if (!isdemo()) { if (!(calledhooks & HOOK_START)) @@ -313,8 +315,7 @@ void Playerchecker_Think() // player connected if (!e) { - playerslots[i] = e = new(playerslot); - make_pure(e); + playerslots[i] = e = new_pure(playerslot); } e.sv_entnum = i; e.ping = 0; @@ -331,16 +332,13 @@ void Playerchecker_Think() this.nextthink = time + 0.2; } -void Porto_Init(); void TrueAim_Init(); void PostInit() { - entity playerchecker = new(playerchecker); - make_pure(playerchecker); + entity playerchecker = new_pure(playerchecker); playerchecker.think = Playerchecker_Think; playerchecker.nextthink = time + 0.2; - Porto_Init(); TrueAim_Init(); postinit = true; @@ -432,8 +430,7 @@ NET_HANDLE(ENT_CLIENT_SCORES, bool isnew) o = playerslots[this.sv_entnum]; if (!o) { - o = playerslots[this.sv_entnum] = new(playerslot); - make_pure(o); + o = playerslots[this.sv_entnum] = new_pure(playerslot); } this.owner = o; o.sv_entnum = this.sv_entnum; @@ -674,13 +671,29 @@ void Spawn_Draw(entity this) __pointparticles(this.cnt, this.origin + '0 0 28', '0 0 2', bound(0, frametime, 0.1)); } +void Spawn_PreDraw(entity this) +{ + float alph; + vector org = getpropertyvec(VF_ORIGIN); + if(this.fade_start) + alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1); + else + alph = 1; + //printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs)); + this.alpha = alph; + if(alph <= 0) + this.drawmask = 0; + else + this.drawmask = MASK_NORMAL; +} + NET_HANDLE(ENT_CLIENT_SPAWNPOINT, bool is_new) { float teamnum = (ReadByte() - 1); vector spn_origin; - spn_origin.x = ReadShort(); - spn_origin.y = ReadShort(); - spn_origin.z = ReadShort(); + spn_origin.x = ReadCoord(); + spn_origin.y = ReadCoord(); + spn_origin.z = ReadCoord(); //if(is_new) //{ @@ -714,6 +727,9 @@ NET_HANDLE(ENT_CLIENT_SPAWNPOINT, bool is_new) else { this.cnt = particleeffectnum(EFFECT_SPAWNPOINT_NEUTRAL); } this.draw = Spawn_Draw; + setpredraw(this, Spawn_PreDraw); + this.fade_start = autocvar_cl_spawn_point_dist_min; + this.fade_end = autocvar_cl_spawn_point_dist_max; } //} @@ -730,9 +746,9 @@ NET_HANDLE(ENT_CLIENT_SPAWNEVENT, bool is_new) if(entnum) { - this.origin_x = ReadShort(); - this.origin_y = ReadShort(); - this.origin_z = ReadShort(); + this.origin_x = ReadCoord(); + this.origin_y = ReadCoord(); + this.origin_z = ReadCoord(); if(is_new) { @@ -816,13 +832,13 @@ void CSQC_Ent_Update(bool isnew) #endif this.enttype = t; bool done = false; - FOREACH(LinkedEntities, it.m_id == t, LAMBDA( + FOREACH(LinkedEntities, it.m_id == t, { if (isnew) this.classname = it.netname; 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); break; - )); + }); time = savetime; if (!done) { @@ -906,11 +922,11 @@ bool CSQC_Parse_TempEntity() // Acquire TE ID int nTEID = ReadByte(); - FOREACH(TempEntities, it.m_id == nTEID, LAMBDA( + FOREACH(TempEntities, it.m_id == nTEID, { if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_TempEntity() nTEID=%s (%d)\n", it.netname, nTEID); return it.m_read(NULL, NULL, true); - )); + }); if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID); @@ -919,7 +935,6 @@ bool CSQC_Parse_TempEntity() return false; } -/** TODO somehow thwart prvm_globalset client ... */ string forcefog; void Fog_Force() { diff --git a/qcsrc/client/miscfunctions.qc b/qcsrc/client/miscfunctions.qc index 0c262604b..fd83aa2d1 100644 --- a/qcsrc/client/miscfunctions.qc +++ b/qcsrc/client/miscfunctions.qc @@ -124,8 +124,7 @@ entity GetTeam(int Team, bool add) return teamslots[num]; if (!add) return world; - entity tm = new(team); - make_pure(tm); + entity tm = new_pure(team); tm.team = Team; teamslots[num] = tm; RegisterTeam(tm); diff --git a/qcsrc/client/scoreboard.qc b/qcsrc/client/scoreboard.qc index cd8df72f6..3204af9f0 100644 --- a/qcsrc/client/scoreboard.qc +++ b/qcsrc/client/scoreboard.qc @@ -1001,13 +1001,13 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size) WepSet weapons_inmap = WepSet_GetFromStat_InMap(); float initial_posx = pos.x; int disownedcnt = 0; - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { int weapon_stats = weapon_accuracy[i - WEP_FIRST]; WepSet set = it.m_wepset; if (weapon_stats < 0 && !(weapons_stat & set || weapons_inmap & set)) ++disownedcnt; - )); + }); int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt; if (weapon_cnt <= 0) return pos; @@ -1061,7 +1061,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size) vector tmpos = pos; int column = 0; - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { int weapon_stats = weapon_accuracy[i - WEP_FIRST]; WepSet set = it.m_wepset; @@ -1100,7 +1100,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size) pos.y += height; } ++column; - )); + }); if (weapons_with_stats) average_accuracy = floor((average_accuracy * 100 / weapons_with_stats) + 0.5); diff --git a/qcsrc/client/shownames.qc b/qcsrc/client/shownames.qc index 826083bc1..fc36c4727 100644 --- a/qcsrc/client/shownames.qc +++ b/qcsrc/client/shownames.qc @@ -23,8 +23,7 @@ STATIC_INIT(shownames_ent) shownames_ent = LL_NEW(); for (int i = 0; i < maxclients; ++i) { - entity e = new(shownames_tag); - make_pure(e); + entity e = new_pure(shownames_tag); e.sv_entnum = i + 1; LL_PUSH(shownames_ent, e); } @@ -54,7 +53,7 @@ void Draw_ShowNames(entity this) if (autocvar_hud_shownames_antioverlap) { // fade tag out if another tag that is closer to you overlaps - LL_EACH(shownames_ent, it != this && entcs_receiver(i), LAMBDA( + LL_EACH(shownames_ent, it != this && entcs_receiver(i), { vector eo = project_3d_to_2d(it.origin); if (eo.z < 0 || eo.x < 0 || eo.y < 0 || eo.x > vid_conwidth || eo.y > vid_conheight) continue; eo.z = 0; @@ -64,7 +63,7 @@ void Draw_ShowNames(entity this) overlap = true; break; } - )); + }); } bool onscreen = (o.z >= 0 && o.x >= 0 && o.y >= 0 && o.x <= vid_conwidth && o.y <= vid_conheight); if (autocvar_hud_shownames_crosshairdistance) @@ -168,7 +167,7 @@ void Draw_ShowNames(entity this) void Draw_ShowNames_All() { if (!autocvar_hud_shownames) return; - LL_EACH(shownames_ent, true, LAMBDA( + LL_EACH(shownames_ent, true, { entity entcs = entcs_receiver(i); if (!entcs) { @@ -195,5 +194,5 @@ void Draw_ShowNames_All() if (!it.csqcmodel_isdead) setorigin(it, entcs.origin); it.csqcmodel_isdead = dead; Draw_ShowNames(it); - )); + }); } diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 7288f253e..70a4f2eeb 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -39,33 +39,24 @@ float autocvar_cl_bobmodel_side; float autocvar_cl_bobmodel_up; float autocvar_cl_followmodel; -float autocvar_cl_followmodel_side_speed; -float autocvar_cl_followmodel_side_highpass; -float autocvar_cl_followmodel_side_highpass1; -float autocvar_cl_followmodel_side_limit; -float autocvar_cl_followmodel_side_lowpass; -float autocvar_cl_followmodel_up_speed; -float autocvar_cl_followmodel_up_highpass; -float autocvar_cl_followmodel_up_highpass1; -float autocvar_cl_followmodel_up_limit; -float autocvar_cl_followmodel_up_lowpass; +float autocvar_cl_followmodel_speed = 0.3; +float autocvar_cl_followmodel_limit = 135; +float autocvar_cl_followmodel_velocity_lowpass = 0.05; +float autocvar_cl_followmodel_highpass = 0.05; +float autocvar_cl_followmodel_lowpass = 0.03; +bool autocvar_cl_followmodel_velocity_absolute; float autocvar_cl_leanmodel; -float autocvar_cl_leanmodel_side_speed; -float autocvar_cl_leanmodel_side_highpass; -float autocvar_cl_leanmodel_side_highpass1; -float autocvar_cl_leanmodel_side_lowpass; -float autocvar_cl_leanmodel_side_limit; -float autocvar_cl_leanmodel_up_speed; -float autocvar_cl_leanmodel_up_highpass; -float autocvar_cl_leanmodel_up_highpass1; -float autocvar_cl_leanmodel_up_lowpass; -float autocvar_cl_leanmodel_up_limit; +float autocvar_cl_leanmodel_speed = 0.3; +float autocvar_cl_leanmodel_limit = 30; +float autocvar_cl_leanmodel_highpass1 = 0.2; +float autocvar_cl_leanmodel_highpass = 0.2; +float autocvar_cl_leanmodel_lowpass = 0.05; +#define avg_factor(avg_time) (1 - exp(-frametime / max(0.001, avg_time))) #define lowpass(value, frac, ref_store, ret) MACRO_BEGIN \ { \ - float __frac = bound(0, frac, 1); \ - ret = ref_store = ref_store * (1 - __frac) + (value) * __frac; \ + ret = ref_store = ref_store * (1 - frac) + (value) * frac; \ } MACRO_END #define lowpass_limited(value, frac, limit, ref_store, ret) MACRO_BEGIN \ @@ -86,31 +77,42 @@ float autocvar_cl_leanmodel_up_limit; ret = (value) - __f; \ } MACRO_END -#define lowpass3(value, fracx, fracy, fracz, ref_store, ref_out) MACRO_BEGIN \ +#define lowpass2(value, frac, ref_store, ref_out) MACRO_BEGIN \ { \ - lowpass(value.x, fracx, ref_store.x, ref_out.x); \ - lowpass(value.y, fracy, ref_store.y, ref_out.y); \ - lowpass(value.z, fracz, ref_store.z, ref_out.z); \ + lowpass(value.x, frac, ref_store.x, ref_out.x); \ + lowpass(value.y, frac, ref_store.y, ref_out.y); \ } MACRO_END -#define highpass3(value, fracx, fracy, fracz, ref_store, ref_out) MACRO_BEGIN \ +#define highpass2(value, frac, ref_store, ref_out) MACRO_BEGIN \ { \ - highpass(value.x, fracx, ref_store.x, ref_out.x); \ - highpass(value.y, fracy, ref_store.y, ref_out.y); \ - highpass(value.z, fracz, ref_store.z, ref_out.z); \ + highpass(value.x, frac, ref_store.x, ref_out.x); \ + highpass(value.y, frac, ref_store.y, ref_out.y); \ } MACRO_END -#define highpass3_limited(value, fracx, limitx, fracy, limity, fracz, limitz, ref_store, ref_out) MACRO_BEGIN \ +#define highpass2_limited(value, frac, limit, ref_store, ref_out) MACRO_BEGIN \ { \ - highpass_limited(value.x, fracx, limitx, ref_store.x, ref_out.x); \ - highpass_limited(value.y, fracy, limity, ref_store.y, ref_out.y); \ - highpass_limited(value.z, fracz, limitz, ref_store.z, ref_out.z); \ + highpass_limited(value.x, frac, limit, ref_store.x, ref_out.x); \ + highpass_limited(value.y, frac, limit, ref_store.y, ref_out.y); \ +} MACRO_END + +#define lowpass3(value, frac, ref_store, ref_out) MACRO_BEGIN \ +{ \ + lowpass(value.x, frac, ref_store.x, ref_out.x); \ + lowpass(value.y, frac, ref_store.y, ref_out.y); \ + lowpass(value.z, frac, ref_store.z, ref_out.z); \ +} MACRO_END + +#define highpass3(value, frac, ref_store, ref_out) MACRO_BEGIN \ +{ \ + highpass(value.x, frac, ref_store.x, ref_out.x); \ + highpass(value.y, frac, ref_store.y, ref_out.y); \ + highpass(value.z, frac, ref_store.z, ref_out.z); \ } MACRO_END void viewmodel_animate(entity this) { static float prevtime; - float frametime = (time - prevtime) * STAT(MOVEVARS_TIMESCALE); + float frametime = (time - prevtime); prevtime = time; if (autocvar_chase_active) return; @@ -121,94 +123,102 @@ void viewmodel_animate(entity this) bool clonground = !(view.anim_implicit_state & ANIMIMPLICITSTATE_INAIR); static bool oldonground; static float hitgroundtime; - static float lastongroundtime; if (clonground) { float f = time; // cl.movecmd[0].time if (!oldonground) hitgroundtime = f; - lastongroundtime = f; } oldonground = clonground; - vector gunorg = '0 0 0', gunangles = '0 0 0'; - static vector gunorg_prev = '0 0 0', gunangles_prev = '0 0 0'; bool teleported = view.csqcmodel_teleported; - // 1. if we teleported, clear the frametime... the lowpass will recover the previous value then - if (teleported) + float frac; + if(autocvar_cl_followmodel) + { + vector gunorg = '0 0 0'; + static vector vel_average; + static vector gunorg_prev = '0 0 0'; + static vector gunorg_adjustment_highpass; + static vector gunorg_adjustment_lowpass; + + vector vel; + if(autocvar_cl_followmodel_velocity_absolute) + vel = view.velocity; + else + { + vector forward, right = '0 0 0', up = '0 0 0'; + MAKEVECTORS(makevectors, view_angles, forward, right, up); + vel.x = view.velocity * forward; + vel.y = view.velocity * right * -1; + vel.z = view.velocity * up; + } + + vel.x = bound(vel_average.x - autocvar_cl_followmodel_limit, vel.x, vel_average.x + autocvar_cl_followmodel_limit); + vel.y = bound(vel_average.y - autocvar_cl_followmodel_limit, vel.y, vel_average.y + autocvar_cl_followmodel_limit); + vel.z = bound(vel_average.z - autocvar_cl_followmodel_limit, vel.z, vel_average.z + autocvar_cl_followmodel_limit); + + frac = avg_factor(autocvar_cl_followmodel_velocity_lowpass); + lowpass3(vel, frac, vel_average, gunorg); + + gunorg *= -autocvar_cl_followmodel_speed * 0.042; + + // perform highpass/lowpass on the adjustment vectors (turning velocity into acceleration!) + // trick: we must do the lowpass LAST, so the lowpass vector IS the final vector! + frac = avg_factor(autocvar_cl_followmodel_highpass); + highpass3(gunorg, frac, gunorg_adjustment_highpass, gunorg); + frac = avg_factor(autocvar_cl_followmodel_lowpass); + lowpass3(gunorg, frac, gunorg_adjustment_lowpass, gunorg); + + if(autocvar_cl_followmodel_velocity_absolute) + { + vector fixed_gunorg; + vector forward, right = '0 0 0', up = '0 0 0'; + MAKEVECTORS(makevectors, view_angles, forward, right, up); + fixed_gunorg.x = gunorg * forward; + fixed_gunorg.y = gunorg * right * -1; + fixed_gunorg.z = gunorg * up; + gunorg = fixed_gunorg; + } + + this.origin += gunorg; + } + + if(autocvar_cl_leanmodel) { - // try to fix the first highpass; result is NOT - // perfect! TODO find a better fix + vector gunangles = '0 0 0'; + static vector gunangles_prev = '0 0 0'; + static vector gunangles_highpass = '0 0 0'; + static vector gunangles_adjustment_highpass; + static vector gunangles_adjustment_lowpass; + + if (teleported) + gunangles_prev = view_angles; + + // in the highpass, we _store_ the DIFFERENCE to the actual view angles... + gunangles_highpass += gunangles_prev; + PITCH(gunangles_highpass) += 360 * floor((PITCH(view_angles) - PITCH(gunangles_highpass)) / 360 + 0.5); + YAW(gunangles_highpass) += 360 * floor((YAW(view_angles) - YAW(gunangles_highpass)) / 360 + 0.5); + ROLL(gunangles_highpass) += 360 * floor((ROLL(view_angles) - ROLL(gunangles_highpass)) / 360 + 0.5); + frac = avg_factor(autocvar_cl_leanmodel_highpass1); + highpass2_limited(view_angles, frac, autocvar_cl_leanmodel_limit, gunangles_highpass, gunangles); gunangles_prev = view_angles; - gunorg_prev = view_origin; - } - - static vector gunorg_highpass = '0 0 0'; - - // 2. for the gun origin, only keep the high frequency (non-DC) parts, which is "somewhat like velocity" - gunorg_highpass += gunorg_prev; - highpass3_limited(view_origin, - frametime * autocvar_cl_followmodel_side_highpass1, autocvar_cl_followmodel_side_limit, - frametime * autocvar_cl_followmodel_side_highpass1, autocvar_cl_followmodel_side_limit, - frametime * autocvar_cl_followmodel_up_highpass1, autocvar_cl_followmodel_up_limit, - gunorg_highpass, gunorg); - gunorg_prev = view_origin; - gunorg_highpass -= gunorg_prev; - - static vector gunangles_highpass = '0 0 0'; - - // in the highpass, we _store_ the DIFFERENCE to the actual view angles... - gunangles_highpass += gunangles_prev; - PITCH(gunangles_highpass) += 360 * floor((PITCH(view_angles) - PITCH(gunangles_highpass)) / 360 + 0.5); - YAW(gunangles_highpass) += 360 * floor((YAW(view_angles) - YAW(gunangles_highpass)) / 360 + 0.5); - ROLL(gunangles_highpass) += 360 * floor((ROLL(view_angles) - ROLL(gunangles_highpass)) / 360 + 0.5); - highpass3_limited(view_angles, - frametime * autocvar_cl_leanmodel_up_highpass1, autocvar_cl_leanmodel_up_limit, - frametime * autocvar_cl_leanmodel_side_highpass1, autocvar_cl_leanmodel_side_limit, - 0, 0, - gunangles_highpass, gunangles); - gunangles_prev = view_angles; - gunangles_highpass -= gunangles_prev; - - // 3. calculate the RAW adjustment vectors - gunorg.x *= (autocvar_cl_followmodel ? -autocvar_cl_followmodel_side_speed : 0); - gunorg.y *= (autocvar_cl_followmodel ? -autocvar_cl_followmodel_side_speed : 0); - gunorg.z *= (autocvar_cl_followmodel ? -autocvar_cl_followmodel_up_speed : 0); - - PITCH(gunangles) *= (autocvar_cl_leanmodel ? -autocvar_cl_leanmodel_up_speed : 0); - YAW(gunangles) *= (autocvar_cl_leanmodel ? -autocvar_cl_leanmodel_side_speed : 0); - ROLL(gunangles) = 0; - - static vector gunorg_adjustment_highpass; - static vector gunorg_adjustment_lowpass; - static vector gunangles_adjustment_highpass; - static vector gunangles_adjustment_lowpass; - - // 4. perform highpass/lowpass on the adjustment vectors (turning velocity into acceleration!) - // trick: we must do the lowpass LAST, so the lowpass vector IS the final vector! - highpass3(gunorg, - frametime * autocvar_cl_followmodel_side_highpass, - frametime * autocvar_cl_followmodel_side_highpass, - frametime * autocvar_cl_followmodel_up_highpass, - gunorg_adjustment_highpass, gunorg); - lowpass3(gunorg, - frametime * autocvar_cl_followmodel_side_lowpass, - frametime * autocvar_cl_followmodel_side_lowpass, - frametime * autocvar_cl_followmodel_up_lowpass, - gunorg_adjustment_lowpass, gunorg); - // we assume here: PITCH = 0, YAW = 1, ROLL = 2 - highpass3(gunangles, - frametime * autocvar_cl_leanmodel_up_highpass, - frametime * autocvar_cl_leanmodel_side_highpass, - 0, - gunangles_adjustment_highpass, gunangles); - lowpass3(gunangles, - frametime * autocvar_cl_leanmodel_up_lowpass, - frametime * autocvar_cl_leanmodel_side_lowpass, - 0, - gunangles_adjustment_lowpass, gunangles); + gunangles_highpass -= gunangles_prev; + + PITCH(gunangles) *= -autocvar_cl_leanmodel_speed; + YAW(gunangles) *= -autocvar_cl_leanmodel_speed; + + // we assume here: PITCH = 0, YAW = 1, ROLL = 2 + frac = avg_factor(autocvar_cl_leanmodel_highpass); + highpass2(gunangles, frac, gunangles_adjustment_highpass, gunangles); + frac = avg_factor(autocvar_cl_leanmodel_lowpass); + lowpass2(gunangles, frac, gunangles_adjustment_lowpass, gunangles); + + gunangles.x = -gunangles.x; // pitch was inverted, now that actually matters + this.angles += gunangles; + } + float xyspeed = bound(0, vlen(vec2(view.velocity)), 400); // vertical view bobbing code @@ -226,42 +236,28 @@ void viewmodel_animate(entity this) { // calculate for swinging gun model // the gun bobs when running on the ground, but doesn't bob when you're in the air. - // Sajt: I tried to smooth out the transitions between bob and no bob, which works - // for the most part, but for some reason when you go through a message trigger or - // pick up an item or anything like that it will momentarily jolt the gun. - vector forward, right = '0 0 0', up = '0 0 0'; - float bspeed; - float t = 1; - float s = time * autocvar_cl_bobmodel_speed; + static float bobmodel_scale = 0; + static float time_ofs = 0; // makes the effect always restart in the same way if (clonground) { - if (time - hitgroundtime < 0.2) - { - // just hit the ground, speed the bob back up over the next 0.2 seconds - t = time - hitgroundtime; - t = bound(0, t, 0.2); - t *= 5; - } + if (time - hitgroundtime > 0.05) + bobmodel_scale = min(1, bobmodel_scale + frametime * 5); } else + bobmodel_scale = max(0, bobmodel_scale - frametime * 5); + if(bobmodel_scale && xyspeed) { - // recently left the ground, slow the bob down over the next 0.2 seconds - t = time - lastongroundtime; - t = 0.2 - bound(0, t, 0.2); - t *= 5; - } - bspeed = xyspeed * 0.01; - MAKEVECTORS(makevectors, view_angles, forward, right, up); - float bobr = bspeed * autocvar_cl_bobmodel_side * autocvar_cl_viewmodel_scale * sin(s) * t; - gunorg += bobr * right; - float bobu = bspeed * autocvar_cl_bobmodel_up * autocvar_cl_viewmodel_scale * cos(s * 2) * t; - gunorg += bobu * up; - } - vector v = rotate(gunorg, YAW(view_angles) * DEG2RAD); // rotate world coordinates to relative ones - v.z = gunorg.z; - this.origin += v; - gunangles.x = -gunangles.x; // pitch was inverted, now that actually matters - this.angles += gunangles; + float bspeed = xyspeed * 0.01 * autocvar_cl_viewmodel_scale * bobmodel_scale; + float s = (time - time_ofs) * autocvar_cl_bobmodel_speed; + vector gunorg = '0 0 0'; + gunorg.y = bspeed * autocvar_cl_bobmodel_side * sin(s); + gunorg.z = bspeed * autocvar_cl_bobmodel_up * cos(s * 2); + + this.origin += gunorg; + } + else + time_ofs = time; + } } .vector viewmodel_origin, viewmodel_angles; @@ -271,6 +267,8 @@ void viewmodel_animate(entity this) void viewmodel_draw(entity this) { + if(!activeweapon) + return; int mask = (intermission || (STAT(HEALTH) <= 0) || autocvar_chase_active) ? 0 : MASK_NORMAL; float a = this.alpha; static bool wasinvehicle; @@ -340,95 +338,77 @@ void viewmodel_draw(entity this) entity viewmodel; STATIC_INIT(viewmodel) { viewmodel = new(viewmodel); - make_pure(viewmodel); - viewmodel.draw = viewmodel_draw; } -entity porto; -vector polyline[16]; -void Porto_Draw(entity this) +void Porto_Draw(entity this); +STATIC_INIT(Porto) { - vector p, dir, ang, q, nextdir; - float portal_number, portal1_idx; - - if(activeweapon != WEP_PORTO || spectatee_status || gametype == MAPINFO_TYPE_NEXBALL) - return; - if(WEP_CVAR(porto, secondary)) - return; - if(intermission == 1) - return; - if(intermission == 2) - return; - if (STAT(HEALTH) <= 0) - return; + entity e = new_pure(porto); + e.draw = Porto_Draw; + e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP; +} - dir = view_forward; +const int polyline_length = 16; +vector polyline[polyline_length]; +void Porto_Draw(entity this) +{ + if (activeweapon != WEP_PORTO) return; + if (spectatee_status) return; + if (WEP_CVAR(porto, secondary)) return; + if (intermission == 1) return; + if (intermission == 2) return; + if (STAT(HEALTH) <= 0) return; - if(angles_held_status) + vector pos = view_origin; + vector dir = view_forward; + if (angles_held_status) { makevectors(angles_held); dir = v_forward; } - p = view_origin; - - polyline[0] = p; - int idx = 1; - portal_number = 0; - nextdir = dir; + polyline[0] = pos; - for (;;) + int portal_number = 0, portal1_idx = 1, portal_max = 2; + int n = 1 + 2; // 2 lines == 3 points + for (int idx = 0; idx < n && idx < polyline_length - 1; ) { - dir = nextdir; - traceline(p, p + 65536 * dir, true, porto); - if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) - return; - nextdir = dir - 2 * (dir * trace_plane_normal) * trace_plane_normal; // mirror dir at trace_plane_normal - p = trace_endpos; - polyline[idx] = p; - ++idx; - if(idx >= 16) - return; - if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP) - continue; - ++portal_number; - ang = vectoangles2(trace_plane_normal, dir); - ang.x = -ang.x; - makevectors(ang); - if(!CheckWireframeBox(porto, p - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward)) - return; - if(portal_number == 1) + traceline(pos, pos + 65536 * dir, true, this); + dir = reflect(dir, trace_plane_normal); + pos = trace_endpos; + polyline[++idx] = pos; + if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP) { - portal1_idx = idx; - if(portal_number >= 2) - break; + n += 1; + continue; } - } - - while(idx >= 2) - { - p = polyline[idx-2]; - q = polyline[idx-1]; - if(idx == 2) - p = p - view_up * 16; - if(idx-1 >= portal1_idx) + if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) { - Draw_CylindricLine(p, q, 4, "", 1, 0, '0 0 1', 0.5, DRAWFLAG_NORMAL, view_origin); + n = max(2, idx); + break; } - else + // check size { - Draw_CylindricLine(p, q, 4, "", 1, 0, '1 0 0', 0.5, DRAWFLAG_NORMAL, view_origin); + vector ang = vectoangles2(trace_plane_normal, dir); + ang.x = -ang.x; + makevectors(ang); + if (!CheckWireframeBox(this, pos - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward)) + { + n = max(2, idx); + break; + } } - --idx; + portal_number += 1; + if (portal_number >= portal_max) break; + if (portal_number == 1) portal1_idx = idx; + } + for (int idx = 0; idx < n - 1; ++idx) + { + vector p = polyline[idx], q = polyline[idx + 1]; + if (idx == 0) p -= view_up * 16; // line from player + vector rgb = (idx < portal1_idx) ? '1 0 0' : '0 0 1'; + Draw_CylindricLine(p, q, 4, "", 1, 0, rgb, 0.5, DRAWFLAG_NORMAL, view_origin); } -} - -void Porto_Init() -{ - porto = new(porto); - make_pure(porto); - porto.draw = Porto_Draw; - porto.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP; } float drawtime; @@ -593,12 +573,8 @@ const float SHOTTYPE_HITENEMY = 4; void TrueAim_Init() { - trueaim = new(trueaim); - make_pure(trueaim); - trueaim.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; - trueaim_rifle = new(trueaim_rifle); - make_pure(trueaim_rifle); - trueaim_rifle.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE; + (trueaim = new_pure(trueaim)).dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; + (trueaim_rifle = new_pure(trueaim_rifle)).dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE; } float EnemyHitCheck() @@ -1318,18 +1294,14 @@ void HUD_Crosshair() void HUD_Draw() { - vector rgb = '0 0 0'; - float a = 1; if (MUTATOR_CALLHOOK(HUD_Draw_overlay)) { - rgb = MUTATOR_ARGV(0, vector); - a = MUTATOR_ARGV(0, float); + drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, MUTATOR_ARGV(0, vector), autocvar_hud_colorflash_alpha * MUTATOR_ARGV(0, float), DRAWFLAG_ADDITIVE); } else if(STAT(FROZEN)) { - rgb = ((STAT(REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * STAT(REVIVE_PROGRESS)) + ('0 1 1' * STAT(REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'); + drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((STAT(REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * STAT(REVIVE_PROGRESS)) + ('0 1 1' * STAT(REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); } - drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, rgb, autocvar_hud_colorflash_alpha * a, DRAWFLAG_ADDITIVE); if(!intermission) if(STAT(NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death { @@ -1427,7 +1399,7 @@ void CSQC_UpdateView(float w, float h) if(myteam != prev_myteam) { myteamcolors = colormapPaletteColor(myteam, 1); - FOREACH(hud_panels, true, LAMBDA(it.update_time = time)); + FOREACH(hud_panels, true, it.update_time = time); prev_myteam = myteam; } @@ -1473,10 +1445,10 @@ void CSQC_UpdateView(float w, float h) if(ons_roundlost) { - FOREACH_ENTITY_CLASS("onslaught_generator", it.health <= 0, LAMBDA( + FOREACH_ENTITY_CLASS("onslaught_generator", it.health <= 0, { gen = it; break; - )); + }); if(!gen) ons_roundlost = false; // don't enforce the 3rd person camera if there is no dead generator to show } @@ -1658,6 +1630,10 @@ void CSQC_UpdateView(float w, float h) ov_enabled = false; } + // run viewmodel_draw before updating view_angles to the angles calculated by WarpZone_FixView + // viewmodel_draw needs to use the view_angles set by the engine on every CSQC_UpdateView call + viewmodel_draw(viewmodel); + // Render the Scene view_origin = getpropertyvec(VF_ORIGIN); view_angles = getpropertyvec(VF_ANGLES); @@ -1838,7 +1814,7 @@ void CSQC_UpdateView(float w, float h) mousepos = mousepos*0.5 + getmousepos(); */ - FOREACH_ENTITY(it.draw, LAMBDA(it.draw(it))); + FOREACH_ENTITY(it.draw, it.draw(it)); addentities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS); renderscene(); @@ -2168,7 +2144,7 @@ void CSQC_UpdateView(float w, float h) } else */ // draw 2D entities - FOREACH_ENTITY(it.draw2d, LAMBDA(it.draw2d(it))); + FOREACH_ENTITY(it.draw2d, it.draw2d(it)); Draw_ShowNames_All(); Debug_Draw(); diff --git a/qcsrc/common/_all.inc b/qcsrc/common/_all.inc index 9c888b91a..78d2373e2 100644 --- a/qcsrc/common/_all.inc +++ b/qcsrc/common/_all.inc @@ -7,6 +7,9 @@ #include "mapinfo.qc" #include "playerstats.qc" +#ifdef SVQC + #include "state.qc" +#endif #include "util.qc" #ifndef CSQC @@ -30,7 +33,7 @@ #include "deathtypes/all.qc" #include "effects/all.qc" #include "impulses/all.qc" -#include "notifications.qc" +#include "notifications/all.qc" #include "t_items.qc" #endif diff --git a/qcsrc/common/animdecide.qc b/qcsrc/common/animdecide.qc index 76921d662..f5adbe7b7 100644 --- a/qcsrc/common/animdecide.qc +++ b/qcsrc/common/animdecide.qc @@ -10,13 +10,10 @@ bool monsters_animoverride(entity this) { Monster monster_id = NULL; - FOREACH(Monsters, it != MON_Null, LAMBDA( - if(it.model == this.model) - { - monster_id = it; - break; - } - )); + FOREACH(Monsters, it != MON_Null && it.model == this.model, { + monster_id = it; + break; + }); if(!monster_id) { return false; } diff --git a/qcsrc/common/command/all.qh b/qcsrc/common/command/all.qh index efe9f7268..9bbce5e14 100644 --- a/qcsrc/common/command/all.qh +++ b/qcsrc/common/command/all.qh @@ -16,7 +16,7 @@ REGISTRY_SORT(GENERIC_COMMANDS) METHOD(genericcommand_##id, m_invokecmd, void(int request, entity caller, int arguments, string command)) STATIC_INIT(GENERIC_COMMANDS_aliases) { - FOREACH(GENERIC_COMMANDS, true, LAMBDA(localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_svmenu")))); + FOREACH(GENERIC_COMMANDS, true, localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_svmenu"))); } #include "generic.qh" diff --git a/qcsrc/common/command/generic.qc b/qcsrc/common/command/generic.qc index 5b5359283..50cc49076 100644 --- a/qcsrc/common/command/generic.qc +++ b/qcsrc/common/command/generic.qc @@ -6,7 +6,7 @@ #include "../mapinfo.qh" #ifndef MENUQC - #include "../notifications.qh" + #include "../notifications/all.qh" #endif #ifdef CSQC @@ -27,19 +27,6 @@ // Last updated: February 19th, 2012 // ========================================================= -// used by generic commands for better help/usage information -string GetProgramCommandPrefix() -{ - #ifdef SVQC - return "sv_cmd"; - #endif - #ifdef CSQC - return "cl_cmd"; - #endif - #ifdef MENUQC - return "menu_cmd"; - #endif -} // used by curl command void Curl_URI_Get_Callback(int id, float status, string data) @@ -388,6 +375,11 @@ void GenericCommand_restartnotifs(float request) case CMD_REQUEST_COMMAND: { #ifndef MENUQC + int NOTIF_ANNCE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_ANNCE, { ++NOTIF_ANNCE_COUNT; }); + int NOTIF_INFO_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_INFO, { ++NOTIF_INFO_COUNT; }); + int NOTIF_CENTER_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CENTER, { ++NOTIF_CENTER_COUNT; }); + int NOTIF_MULTI_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_MULTI, { ++NOTIF_MULTI_COUNT; }); + int NOTIF_CHOICE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CHOICE, { ++NOTIF_CHOICE_COUNT; }); LOG_INFOF( strcat( "Restart_Notifications(): Restarting %d notifications... ", @@ -545,32 +537,32 @@ GENERIC_COMMAND(runtest, "Run unit tests") { GenericCommand_runtest(request, arg void GenericCommand_macro_help() { - FOREACH(GENERIC_COMMANDS, true, LAMBDA(LOG_INFOF(" ^2%s^7: %s\n", it.m_name, it.m_description))); + FOREACH(GENERIC_COMMANDS, true, LOG_INFOF(" ^2%s^7: %s\n", it.m_name, it.m_description)); } float GenericCommand_macro_command(float argc, string command) { string c = strtolower(argv(0)); - FOREACH(GENERIC_COMMANDS, it.m_name == c, LAMBDA( + FOREACH(GENERIC_COMMANDS, it.m_name == c, { it.m_invokecmd(CMD_REQUEST_COMMAND, NULL, argc, command); return true; - )); + }); return false; } float GenericCommand_macro_usage(float argc) { string c = strtolower(argv(1)); - FOREACH(GENERIC_COMMANDS, it.m_name == c, LAMBDA( + FOREACH(GENERIC_COMMANDS, it.m_name == c, { it.m_invokecmd(CMD_REQUEST_USAGE, NULL, argc, ""); return true; - )); + }); return false; } void GenericCommand_macro_write_aliases(float fh) { - FOREACH(GENERIC_COMMANDS, true, LAMBDA(CMD_Write_Alias("qc_cmd_svmenu", it.m_name, it.m_description))); + FOREACH(GENERIC_COMMANDS, true, CMD_Write_Alias("qc_cmd_svmenu", it.m_name, it.m_description)); } diff --git a/qcsrc/common/command/generic.qh b/qcsrc/common/command/generic.qh index be84c407c..63e1dce83 100644 --- a/qcsrc/common/command/generic.qh +++ b/qcsrc/common/command/generic.qh @@ -22,7 +22,13 @@ void GenericCommand_macro_write_aliases(float fh); float GenericCommand(string command); // Returns command prefix specific for whatever program it is compiled in -string GetProgramCommandPrefix(); +#ifdef SVQC + #define GetProgramCommandPrefix() "sv_cmd" +#elif defined(CSQC) + #define GetProgramCommandPrefix() "cl_cmd" +#elif defined(MENUQC) + #define GetProgramCommandPrefix() "menu_cmd" +#endif // used by common/command/generic.qc:GenericCommand_dumpcommands to list all commands into a .txt file #define CMD_Write(s) fputs(fh, s) diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index b0445abf1..28db23dc1 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -1,31 +1,6 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -// COMMIT-TODO: Update if necessary before committing -// Revision 1: additional statistics sent (flag caps, returns, deaths) -// Revision 2: Mapvote preview pictures -// Revision 3: optimized map vote protocol -// Revision 4: CSQC config var system -// Revision 5: mapvote time fix -// Revision 6: more robust against packet loss/delays, also show not yet connected clients -// Revision 7: packet loss column -// Revision 8: race -// Revision 9: race delta -// Revision 10: scoreboard force -// Revision 11: scoreboard unforce; spectator support beginning -// Revision 12: smaller scores updates (SERVER: requires new engine) -// Revision 13: pointparticles -// Revision 14: laser -// Revision 15: zoom -// Revision 16: multi-weapons -// Revision 17: multi-weaponimpulses -// Revision 18: warmup -// Revision 19: fog -// Revision 20: naggers -// Revision 21: entcs for players optimized (position data down from 12 to 7 bytes); waypointsprites in csqc for team radar -// Revision 22: hook shot origin -#define CSQC_REVISION 22 - REGISTER_NET_TEMP(TE_CSQC_PICTURE) REGISTER_NET_TEMP(TE_CSQC_RACE) REGISTER_NET_TEMP(TE_CSQC_TEAMNAGGER) @@ -50,7 +25,7 @@ const int RANKINGS_CNT = 15; REGISTER_NET_LINKED(_ENT_CLIENT_INIT) #ifdef CSQC -NET_HANDLE(_ENT_CLIENT_INIT, bool isnew) { return true; } +NET_HANDLE(_ENT_CLIENT_INIT, bool isnew) { make_pure(this); return true; } #endif /** Sent as a temp entity from a persistent linked entity */ REGISTER_NET_TEMP(ENT_CLIENT_INIT) diff --git a/qcsrc/common/csqcmodel_settings.qh b/qcsrc/common/csqcmodel_settings.qh index da2661b9c..ff890afec 100644 --- a/qcsrc/common/csqcmodel_settings.qh +++ b/qcsrc/common/csqcmodel_settings.qh @@ -69,7 +69,7 @@ CSQCMODEL_PROPERTY(BIT(14), TAG_VIEWLOC_TYPE, ReadShort, WriteEntity, TAG_VIEWLOC_NAME) \ CSQCMODEL_PROPERTY(BIT(15), int, ReadByte, WriteByte, multijump_count) \ CSQCMODEL_PROPERTY(BIT(16), int, ReadByte, WriteByte, MOVETYPE_NAME) -// TODO get rid of colormod/glowmod here, find good solution for vortex charge glowmod hack; also get rid of some useless properties on non-players that only exist for CopyBody +// TODO get rid of colormod/glowmod here; also get rid of some useless properties on non-players that only exist for CopyBody // add hook function calls here #define CSQCPLAYER_HOOK_POSTCAMERASETUP() \ diff --git a/qcsrc/common/deathtypes/all.inc b/qcsrc/common/deathtypes/all.inc index 32d063180..9e0f53a31 100644 --- a/qcsrc/common/deathtypes/all.inc +++ b/qcsrc/common/deathtypes/all.inc @@ -1,16 +1,16 @@ -REGISTER_DEATHTYPE(AUTOTEAMCHANGE, DEATH_SELF_AUTOTEAMCHANGE, NO_MSG, "") -REGISTER_DEATHTYPE(BUFF, NO_MSG, DEATH_MURDER_BUFF, "") -REGISTER_DEATHTYPE(CAMP, DEATH_SELF_CAMP, NO_MSG, "") +REGISTER_DEATHTYPE(AUTOTEAMCHANGE, DEATH_SELF_AUTOTEAMCHANGE, NULL, "") +REGISTER_DEATHTYPE(BUFF, NULL, DEATH_MURDER_BUFF, "") +REGISTER_DEATHTYPE(CAMP, DEATH_SELF_CAMP, NULL, "") REGISTER_DEATHTYPE(CHEAT, DEATH_SELF_CHEAT, DEATH_MURDER_CHEAT, "") -REGISTER_DEATHTYPE(CUSTOM, DEATH_SELF_CUSTOM, NO_MSG, "") +REGISTER_DEATHTYPE(CUSTOM, DEATH_SELF_CUSTOM, NULL, "") REGISTER_DEATHTYPE(DROWN, DEATH_SELF_DROWN, DEATH_MURDER_DROWN, "") REGISTER_DEATHTYPE(FALL, DEATH_SELF_FALL, DEATH_MURDER_FALL, "") REGISTER_DEATHTYPE(FIRE, DEATH_SELF_FIRE, DEATH_MURDER_FIRE, "") -REGISTER_DEATHTYPE(GENERIC, DEATH_SELF_GENERIC, NO_MSG, "") +REGISTER_DEATHTYPE(GENERIC, DEATH_SELF_GENERIC, NULL, "") REGISTER_DEATHTYPE(HURTTRIGGER, DEATH_SELF_VOID, DEATH_MURDER_VOID, "") -REGISTER_DEATHTYPE(KILL, DEATH_SELF_SUICIDE, NO_MSG, "") +REGISTER_DEATHTYPE(KILL, DEATH_SELF_SUICIDE, NULL, "") REGISTER_DEATHTYPE(LAVA, DEATH_SELF_LAVA, DEATH_MURDER_LAVA, "") -REGISTER_DEATHTYPE(MIRRORDAMAGE, DEATH_SELF_BETRAYAL, NO_MSG, "") +REGISTER_DEATHTYPE(MIRRORDAMAGE, DEATH_SELF_BETRAYAL, NULL, "") REGISTER_DEATHTYPE(MONSTER_MAGE, DEATH_SELF_MON_MAGE, DEATH_MURDER_MONSTER, "monster") REGISTER_DEATHTYPE(MONSTER_SHAMBLER_CLAW, DEATH_SELF_MON_SHAMBLER_CLAW, DEATH_MURDER_MONSTER, "monster") REGISTER_DEATHTYPE(MONSTER_SHAMBLER_SMASH, DEATH_SELF_MON_SHAMBLER_SMASH, DEATH_MURDER_MONSTER, "monster") @@ -24,38 +24,38 @@ REGISTER_DEATHTYPE(NADE_NAPALM, DEATH_SELF_NADE_NAPALM, DEAT REGISTER_DEATHTYPE(NADE_ICE, DEATH_SELF_NADE_ICE, DEATH_MURDER_NADE_ICE, "") REGISTER_DEATHTYPE(NADE_ICE_FREEZE, DEATH_SELF_NADE_ICE_FREEZE, DEATH_MURDER_NADE_ICE_FREEZE, "") REGISTER_DEATHTYPE(NADE_HEAL, DEATH_SELF_NADE_HEAL, DEATH_MURDER_NADE_HEAL, "") -REGISTER_DEATHTYPE(NOAMMO, DEATH_SELF_NOAMMO, NO_MSG, "") -REGISTER_DEATHTYPE(ROT, DEATH_SELF_ROT, NO_MSG, "") +REGISTER_DEATHTYPE(NOAMMO, DEATH_SELF_NOAMMO, NULL, "") +REGISTER_DEATHTYPE(ROT, DEATH_SELF_ROT, NULL, "") REGISTER_DEATHTYPE(SHOOTING_STAR, DEATH_SELF_SHOOTING_STAR, DEATH_MURDER_SHOOTING_STAR, "") REGISTER_DEATHTYPE(SLIME, DEATH_SELF_SLIME, DEATH_MURDER_SLIME, "") REGISTER_DEATHTYPE(SWAMP, DEATH_SELF_SWAMP, DEATH_MURDER_SWAMP, "") -REGISTER_DEATHTYPE(TEAMCHANGE, DEATH_SELF_TEAMCHANGE, NO_MSG, "") -REGISTER_DEATHTYPE(TELEFRAG, NO_MSG, DEATH_MURDER_TELEFRAG, "") +REGISTER_DEATHTYPE(TEAMCHANGE, DEATH_SELF_TEAMCHANGE, NULL, "") +REGISTER_DEATHTYPE(TELEFRAG, NULL, DEATH_MURDER_TELEFRAG, "") REGISTER_DEATHTYPE(TOUCHEXPLODE, DEATH_SELF_TOUCHEXPLODE, DEATH_MURDER_TOUCHEXPLODE, "") -REGISTER_DEATHTYPE(TURRET, DEATH_SELF_TURRET, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_EWHEEL, DEATH_SELF_TURRET_EWHEEL, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_FLAC, DEATH_SELF_TURRET_FLAC, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_HELLION, DEATH_SELF_TURRET_HELLION, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_HK, DEATH_SELF_TURRET_HK, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_MACHINEGUN, DEATH_SELF_TURRET_MACHINEGUN, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_MLRS, DEATH_SELF_TURRET_MLRS, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_PHASER, DEATH_SELF_TURRET_PHASER, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_PLASMA, DEATH_SELF_TURRET_PLASMA, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_TESLA, DEATH_SELF_TURRET_TESLA, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_WALK_GUN, DEATH_SELF_TURRET_WALK_GUN, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_WALK_MELEE, DEATH_SELF_TURRET_WALK_MELEE, NO_MSG, "turret") -REGISTER_DEATHTYPE(TURRET_WALK_ROCKET, DEATH_SELF_TURRET_WALK_ROCKET, NO_MSG, "turret") +REGISTER_DEATHTYPE(TURRET, DEATH_SELF_TURRET, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_EWHEEL, DEATH_SELF_TURRET_EWHEEL, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_FLAC, DEATH_SELF_TURRET_FLAC, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_HELLION, DEATH_SELF_TURRET_HELLION, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_HK, DEATH_SELF_TURRET_HK, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_MACHINEGUN, DEATH_SELF_TURRET_MACHINEGUN, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_MLRS, DEATH_SELF_TURRET_MLRS, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_PHASER, DEATH_SELF_TURRET_PHASER, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_PLASMA, DEATH_SELF_TURRET_PLASMA, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_TESLA, DEATH_SELF_TURRET_TESLA, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_WALK_GUN, DEATH_SELF_TURRET_WALK_GUN, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_WALK_MELEE, DEATH_SELF_TURRET_WALK_MELEE, NULL, "turret") +REGISTER_DEATHTYPE(TURRET_WALK_ROCKET, DEATH_SELF_TURRET_WALK_ROCKET, NULL, "turret") REGISTER_DEATHTYPE(VH_BUMB_DEATH, DEATH_SELF_VH_BUMB_DEATH, DEATH_MURDER_VH_BUMB_DEATH, "vehicle") -REGISTER_DEATHTYPE(VH_BUMB_GUN, NO_MSG, DEATH_MURDER_VH_BUMB_GUN, "vehicle") +REGISTER_DEATHTYPE(VH_BUMB_GUN, NULL, DEATH_MURDER_VH_BUMB_GUN, "vehicle") REGISTER_DEATHTYPE(VH_CRUSH, DEATH_SELF_VH_CRUSH, DEATH_MURDER_VH_CRUSH, "vehicle") REGISTER_DEATHTYPE(VH_RAPT_BOMB, DEATH_SELF_VH_RAPT_BOMB, DEATH_MURDER_VH_RAPT_BOMB, "vehicle") -REGISTER_DEATHTYPE(VH_RAPT_CANNON, NO_MSG, DEATH_MURDER_VH_RAPT_CANNON, "vehicle") +REGISTER_DEATHTYPE(VH_RAPT_CANNON, NULL, DEATH_MURDER_VH_RAPT_CANNON, "vehicle") REGISTER_DEATHTYPE(VH_RAPT_DEATH, DEATH_SELF_VH_RAPT_DEATH, DEATH_MURDER_VH_RAPT_DEATH, "vehicle") REGISTER_DEATHTYPE(VH_RAPT_FRAGMENT, DEATH_SELF_VH_RAPT_BOMB, DEATH_MURDER_VH_RAPT_BOMB, "vehicle") REGISTER_DEATHTYPE(VH_SPID_DEATH, DEATH_SELF_VH_SPID_DEATH, DEATH_MURDER_VH_SPID_DEATH, "vehicle") -REGISTER_DEATHTYPE(VH_SPID_MINIGUN, NO_MSG, DEATH_MURDER_VH_SPID_MINIGUN, "vehicle") +REGISTER_DEATHTYPE(VH_SPID_MINIGUN, NULL, DEATH_MURDER_VH_SPID_MINIGUN, "vehicle") REGISTER_DEATHTYPE(VH_SPID_ROCKET, DEATH_SELF_VH_SPID_ROCKET, DEATH_MURDER_VH_SPID_ROCKET, "vehicle") REGISTER_DEATHTYPE(VH_WAKI_DEATH, DEATH_SELF_VH_WAKI_DEATH, DEATH_MURDER_VH_WAKI_DEATH, "vehicle") -REGISTER_DEATHTYPE(VH_WAKI_GUN, NO_MSG, DEATH_MURDER_VH_WAKI_GUN, "vehicle") +REGISTER_DEATHTYPE(VH_WAKI_GUN, NULL, DEATH_MURDER_VH_WAKI_GUN, "vehicle") REGISTER_DEATHTYPE(VH_WAKI_ROCKET, DEATH_SELF_VH_WAKI_ROCKET, DEATH_MURDER_VH_WAKI_ROCKET, "vehicle") -REGISTER_DEATHTYPE(WEAPON, NO_MSG, NO_MSG, "") +REGISTER_DEATHTYPE(WEAPON, NULL, NULL, "") diff --git a/qcsrc/common/deathtypes/all.qh b/qcsrc/common/deathtypes/all.qh index b662b7e76..ae40ed811 100644 --- a/qcsrc/common/deathtypes/all.qh +++ b/qcsrc/common/deathtypes/all.qh @@ -1,7 +1,7 @@ #ifndef DEATHTYPES_ALL_H #define DEATHTYPES_ALL_H -#include "../notifications.qh" +#include "../notifications/all.qh" REGISTRY(Deathtypes, BITS(8)) #define Deathtypes_from(i) _Deathtypes_from(i, NULL) @@ -19,8 +19,8 @@ int dt_identity(int i) { return i; } this.m_id += DT_FIRST; \ this.nent_name = #id; \ this.death_msgextra = extra; \ - if (msg_death != NO_MSG) this.death_msgself = msg_multi_notifs[dt_identity(msg_death - 1)]; \ - if (msg_death_by != NO_MSG) this.death_msgmurder = msg_multi_notifs[dt_identity(msg_death_by - 1)]; \ + this.death_msgself = msg_death; \ + this.death_msgmurder = msg_death_by; \ } const int DEATH_WEAPONMASK = BITS(8); diff --git a/qcsrc/common/debug.qh b/qcsrc/common/debug.qh index 4f60e9fe3..113019a7c 100644 --- a/qcsrc/common/debug.qh +++ b/qcsrc/common/debug.qh @@ -1,5 +1,4 @@ -#ifndef DEBUG_H -#define DEBUG_H +#pragma once #ifndef MENUQC .bool debug; @@ -32,9 +31,12 @@ REGISTER_NET_TEMP(net_debug) WriteHeader(channel, net_debug); WriteShort(channel, etof(this)); WriteByte(channel, is_pure(this)); - WriteCoord(channel, this.origin.x); - WriteCoord(channel, this.origin.y); - WriteCoord(channel, this.origin.z); + vector o = this.origin; + if (o == '0 0 0') // brushes + o = (this.absmin + this.absmax) / 2; + if (this.tag_entity) + o += this.tag_entity.origin; + WriteCoord(channel, o.x); WriteCoord(channel, o.y); WriteCoord(channel, o.z); WriteString(channel, this.classname); WriteString(channel, this.sourceLoc); return true; @@ -42,6 +44,15 @@ REGISTER_NET_TEMP(net_debug) #endif #ifndef MENUQC +/** + * 0: off + * 1: on + * 2: on (pure) + * 3: on (.entnum != 0) + * 4: on (.origin == '0 0 0') + * 5: on (.debug != 0), server only + * 6: on (.solid != 0) + */ bool autocvar_debugdraw; #endif @@ -55,80 +66,85 @@ bool autocvar_debugdraw; static int debugdraw_frame; ++debugdraw_frame; const int sz = 8; - FOREACH_ENTITY(true, LAMBDA( + FOREACH_ENTITY(true, { if (it.debugdraw_last == debugdraw_frame) continue; int ofs = 0; - for (entity e = findradius(it.origin, 100); e; e = e.chain) - { - if (e.debugdraw_last == debugdraw_frame) continue; - e.debugdraw_last = debugdraw_frame; - vector rgb = (e.debug) ? '0 0 1' : '1 0 0'; - if (autocvar_debugdraw_filterout != "" && strhasword(autocvar_debugdraw_filterout, e.classname)) continue; - if (autocvar_debugdraw_filter != "" && !strhasword(autocvar_debugdraw_filter, e.classname)) continue; + FOREACH_ENTITY_RADIUS(it.origin, 100, it.debugdraw_last != debugdraw_frame, { + it.debugdraw_last = debugdraw_frame; + vector rgb = (it.debug) ? '0 0 1' : '1 0 0'; + if (autocvar_debugdraw_filterout != "" && strhasword(autocvar_debugdraw_filterout, it.classname)) continue; + if (autocvar_debugdraw_filter != "" && !strhasword(autocvar_debugdraw_filter, it.classname)) continue; if (autocvar_debugdraw == 3) { - if (!e.entnum) continue; + if (!it.entnum) continue; } if (autocvar_debugdraw == 4) { - if (e.origin) continue; + if (it.origin) continue; + } + if (autocvar_debugdraw == 5) + { + if (!it.debug) continue; } - else if (autocvar_debugdraw > 4) + else if (autocvar_debugdraw > 5) { bool flag = true; do { -// if (e.modelindex) break; -// if (e.absmin) break; -// if (e.absmax) break; -// if (e.entnum) break; -// if (e.drawmask) break; -// if (e.predraw) break; -// if (e.movetype) break; - if (e.solid) break; -// if (e.origin) break; -// if (e.oldorigin) break; -// if (e.velocity) break; -// if (e.angles) break; -// if (e.avelocity) break; -// if (e.classname) break; -// if (e.model) break; -// if (e.frame) break; -// if (e.skin) break; -// if (e.effects) break; -// if (e.mins) break; -// if (e.maxs) break; -// if (e.size) break; -// if (e.touch) break; -// if (e.use) break; -// if (e.think) break; -// if (e.blocked) break; -// if (e.nextthink) break; -// if (e.chain) break; -// if (e.netname) break; -// if (e.enemy) break; -// if (e.flags) break; -// if (e.colormap) break; -// if (e.owner) break; +// if (it.modelindex) break; +// if (it.absmin) break; +// if (it.absmax) break; +// if (it.entnum) break; +// if (it.drawmask) break; +// if (it.predraw) break; +// if (it.movetype) break; + if (it.solid) break; +// if (it.origin) break; +// if (it.oldorigin) break; +// if (it.velocity) break; +// if (it.angles) break; +// if (it.avelocity) break; +// if (it.classname) break; +// if (it.model) break; +// if (it.frame) break; +// if (it.skin) break; +// if (it.effects) break; +// if (it.mins) break; +// if (it.maxs) break; +// if (it.size) break; +// if (it.touch) break; +// if (it.use) break; +// if (it.think) break; +// if (it.blocked) break; +// if (it.nextthink) break; +// if (it.chain) break; +// if (it.netname) break; +// if (it.enemy) break; +// if (it.flags) break; +// if (it.colormap) break; +// if (it.owner) break; flag = false; } while (0); if (!flag) continue; } - else if (is_pure(e)) + else if (is_pure(it)) { if (autocvar_debugdraw < 2) continue; rgb.y = 1; } - vector pos = project_3d_to_2d(e.origin); + vector o = it.origin; + if (it.tag_entity) + o += it.tag_entity.origin; + vector pos = project_3d_to_2d(o); if (pos.z < 0) continue; pos.z = 0; pos.y += ofs * sz; drawcolorcodedstring2(pos, - sprintf("%d: '%s'@%s", (e.debug ? e.sv_entnum : etof(e)), - e.classname, e.sourceLoc), + sprintf("%d: '%s'@%s", (it.debug ? it.sv_entnum : etof(it)), + it.classname, it.sourceLoc), sz * '1 1 0', rgb, 0.5, DRAWFLAG_NORMAL); ++ofs; - } - )); + }); + }); } #endif @@ -145,7 +161,7 @@ bool autocvar_debugdraw; for (entity e = NULL; (e = findfloat(e, debug, 0)) && rem > 0; ) { if (autocvar_debugdraw < 2 && is_pure(e)) continue; - debug_send(e, nextent(NULL), 0); + debug_send(e, caller, 0); e.debug = true; --rem; } @@ -169,8 +185,8 @@ GENERIC_COMMAND(bufstr_get, "Examine a string buffer object") { case CMD_REQUEST_COMMAND: { - int bufhandle = stof(argv(1)); - int string_index = stof(argv(2)); + int bufhandle = stof(argv(1)); + int string_index = stof(argv(2)); string s = bufstr_get(bufhandle, string_index); LOG_INFOF("%s\n", s); return; @@ -203,4 +219,101 @@ GENERIC_COMMAND(version, "Print the current version") } } +REGISTER_STAT(TRACE_ENT, int) +#ifdef SVQC +bool autocvar_debugtrace; + +REGISTER_MUTATOR(trace, autocvar_debugtrace); + +.bool debug_trace_button; +.int solid_prev; +MUTATOR_HOOKFUNCTION(trace, SV_StartFrame) +{ + FOREACH_CLIENT(true, { + bool skip = false; + bool btn = PHYS_INPUT_BUTTON_HOOK(it); + if (btn == it.debug_trace_button) skip = true; + it.debug_trace_button = btn; + if (!btn || skip) continue; + FOREACH_ENTITY(true, { + it.solid_prev = it.solid; + it.solid = SOLID_BBOX; + }); + vector forward; vector right; vector up; + MAKEVECTORS(makevectors, it.v_angle, forward, right, up); + vector pos = it.origin + it.view_ofs; + traceline(pos, pos + forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, it); + FOREACH_ENTITY(true, { + it.solid = it.solid_prev; + it.solid_prev = 0; + }); + entity e = trace_ent; + int i = etof(e); + STAT(TRACE_ENT, it) = i; + if (!e) continue; + setorigin(e, e.origin + '0 0 100'); + stuffcmd(it, sprintf("prvm_edict server %d\n", i)); + }); +} #endif +#ifdef CSQC +entity TRACE_ENT; +void Trace_draw2d(entity this) +{ + int e = STAT(TRACE_ENT); + if (!e) return; + vector pos = '0 0 0'; + pos.y += vid_conheight / 2; + drawstring(pos, sprintf("prvm_edict server %d", e), '10 10 0', '1 1 1', 1, DRAWFLAG_NORMAL); +} + +STATIC_INIT(TRACE_ENT) +{ + entity e = TRACE_ENT = new_pure(TRACE_ENT); + e.draw2d = Trace_draw2d; +} +#endif + +GENERIC_COMMAND(find, "Search through entities for matching classname") +{ + switch (request) + { + case CMD_REQUEST_COMMAND: + { + FOREACH_ENTITY_CLASS_ORDERED(argv(1), true, LOG_INFOF("%i (%s)\n", it, it.classname)); + return; + } + + default: + { + LOG_INFO("Incorrect parameters for ^2find^7\n"); + } + case CMD_REQUEST_USAGE: + { + LOG_INFO("\nUsage:^3 " GetProgramCommandPrefix() " find classname\n"); + LOG_INFO(" Where 'classname' is the classname to search for.\n"); + return; + } + } +} + +GENERIC_COMMAND(findat, "Search through entities for matching origin") +{ + switch (request) + { + case CMD_REQUEST_COMMAND: + { + vector match = stov(argv(1)); + FOREACH_ENTITY_ORDERED(it.origin == match, LOG_INFOF("%i (%s)\n", it, it.classname)); + return; + } + + default: + LOG_INFO("Incorrect parameters for ^2findat^7\n"); + case CMD_REQUEST_USAGE: + { + LOG_INFO("\nUsage:^3 " GetProgramCommandPrefix() " findat \"0 0 0\"\n"); + return; + } + } +} diff --git a/qcsrc/common/effects/all.qc b/qcsrc/common/effects/all.qc index 663526bcc..73f1fe65f 100644 --- a/qcsrc/common/effects/all.qc +++ b/qcsrc/common/effects/all.qc @@ -66,8 +66,7 @@ void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt) { if(!eff) { return; } if(!eff.eent_eff_trail && !eff_cnt) { return; } // effect has no count! - entity net_eff = new(net_effect); - make_pure(net_eff); + entity net_eff = new_pure(net_effect); net_eff.owner = eff; //net_eff.eent_broadcast = broadcast; net_eff.m_id = eff.m_id; @@ -76,17 +75,17 @@ void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt) net_eff.eent_net_count = eff_cnt; net_eff.eent_eff_trail = eff.eent_eff_trail; - FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA(Net_Write_Effect(net_eff, it, 0))); + FOREACH_CLIENT(IS_REAL_CLIENT(it), Net_Write_Effect(net_eff, it, 0)); remove(net_eff); } void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt) { // problem with this is, we might not have all the available effects for it - FOREACH(Effects, it.eent_eff_name == eff_name, LAMBDA( + FOREACH(Effects, it.eent_eff_name == eff_name, { Send_Effect(it, eff_loc, eff_vel, eff_cnt); return; - )); + }); // revert to engine handling __pointparticles(_particleeffectnum(eff_name), eff_loc, eff_vel, eff_cnt); } diff --git a/qcsrc/common/effects/qc/damageeffects.qc b/qcsrc/common/effects/qc/damageeffects.qc index 4d85ab909..ba60e51bd 100644 --- a/qcsrc/common/effects/qc/damageeffects.qc +++ b/qcsrc/common/effects/qc/damageeffects.qc @@ -43,7 +43,6 @@ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad deathtype |= 0x8000; e = new(damageinfo); - make_pure(e); setorigin(e, org); e.projectiledeathtype = deathtype; e.dmg = coredamage; @@ -179,7 +178,6 @@ void DamageEffect(vector hitorg, float thedamage, int type, int specnum) } e = new(damage); - make_pure(e); setmodel(e, MDL_Null); // necessary to attach and read origin setattachment(e, self, gettaginfo_name); // attach to the given bone e.owner = self; @@ -225,15 +223,10 @@ NET_HANDLE(ENT_CLIENT_DAMAGEINFO, bool isNew) else forcemul = 1; - for(entity e = findradius(w_org, rad + MAX_DAMAGEEXTRARADIUS); e; e = e.chain) - { - setself(e); - // attached ents suck - if(self.tag_entity) - continue; - + FOREACH_ENTITY_RADIUS(w_org, rad + MAX_DAMAGEEXTRARADIUS, !it.tag_entity, { + setself(it); vector nearest = NearestPointOnBox(self, w_org); - if(rad) + if (rad) { thisdmg = ((vlen (nearest - w_org) - bound(MIN_DAMAGEEXTRARADIUS, self.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad); if(thisdmg >= 1) @@ -277,7 +270,7 @@ NET_HANDLE(ENT_CLIENT_DAMAGEINFO, bool isNew) if(self.isplayermodel) hitplayer = true; // this impact damaged a player - } + }); setself(this); if(DEATH_ISVEHICLE(w_deathtype)) diff --git a/qcsrc/common/effects/qc/gibs.qc b/qcsrc/common/effects/qc/gibs.qc index 3d0da1b35..aec664035 100644 --- a/qcsrc/common/effects/qc/gibs.qc +++ b/qcsrc/common/effects/qc/gibs.qc @@ -43,7 +43,7 @@ void Violence_GibSplash_At(vector org, vector dir, float type, float amount, ent e.oldorigin_x = compressShortVector(e.velocity); - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA(Violence_GibSplash_SendEntity(e, it, 0))); + FOREACH_CLIENT(IS_REAL_CLIENT(it), Violence_GibSplash_SendEntity(e, it, 0)); remove(e); } diff --git a/qcsrc/common/effects/qc/globalsound.qc b/qcsrc/common/effects/qc/globalsound.qc index 061ec2c74..ae1ec7485 100644 --- a/qcsrc/common/effects/qc/globalsound.qc +++ b/qcsrc/common/effects/qc/globalsound.qc @@ -12,7 +12,11 @@ REGISTER_NET_TEMP(globalsound) REGISTER_NET_TEMP(playersound) + string GlobalSound_sample(string pair, float r); + #ifdef SVQC + /** Use new sound handling. TODO: use when sounds play correctly on clients */ + bool autocvar_g_debug_globalsounds = false; /** * @param from the source entity, its position is sent * @param gs the global sound def @@ -22,6 +26,18 @@ { assert(IS_PLAYER(from), eprint(from)); if (channel == MSG_ONE && !IS_REAL_CLIENT(msg_entity)) return; + if (!autocvar_g_debug_globalsounds) { + string sample = GlobalSound_sample(gs.m_globalsoundstr, r); + switch (channel) { + case MSG_ONE: + soundto(channel, from, chan, sample, vol, atten); + break; + case MSG_ALL: + _sound(from, chan, sample, vol, atten); + break; + } + return; + } WriteHeader(channel, globalsound); WriteByte(channel, gs.m_id); WriteByte(channel, r * 255); @@ -45,6 +61,20 @@ { assert(IS_PLAYER(from), eprint(from)); if (channel == MSG_ONE && !IS_REAL_CLIENT(msg_entity)) return; + if (!autocvar_g_debug_globalsounds) { + UpdatePlayerSounds(from); + string s = from.(ps.m_playersoundfld); + string sample = GlobalSound_sample(s, r); + switch (channel) { + case MSG_ONE: + soundto(channel, from, chan, sample, vol, atten); + break; + case MSG_ALL: + _sound(from, chan, sample, vol, atten); + break; + } + return; + } WriteHeader(channel, playersound); WriteByte(channel, ps.m_id); WriteByte(channel, r * 255); @@ -60,8 +90,6 @@ } #endif - string GlobalSound_sample(string pair, float r); - #ifdef CSQC NET_HANDLE(globalsound, bool isnew) @@ -164,22 +192,20 @@ entity GetVoiceMessage(string type) { - FOREACH(PlayerSounds, it.m_playersoundstr == type && it.instanceOfVoiceMessage == true, LAMBDA(return it)); + FOREACH(PlayerSounds, it.m_playersoundstr == type && it.instanceOfVoiceMessage == true, return it); return NULL; } entity GetPlayerSound(string type) { - FOREACH(PlayerSounds, it.m_playersoundstr == type && it.instanceOfVoiceMessage == false, LAMBDA(return it)); + FOREACH(PlayerSounds, it.m_playersoundstr == type && it.instanceOfVoiceMessage == false, return it); return NULL; } string allvoicesamples; STATIC_INIT(allvoicesamples) { - FOREACH(PlayerSounds, it.instanceOfVoiceMessage, LAMBDA( - allvoicesamples = strcat(allvoicesamples, " ", it.m_playersoundstr) - )); + FOREACH(PlayerSounds, it.instanceOfVoiceMessage, allvoicesamples = strcat(allvoicesamples, " ", it.m_playersoundstr)); allvoicesamples = strzone(substring(allvoicesamples, 1, -1)); } @@ -220,7 +246,7 @@ fclose(fh); } - #ifdef CSQC + //#ifdef CSQC .string GetPlayerSoundSampleField(string type) { @@ -229,14 +255,14 @@ void ClearPlayerSounds(entity this) { - FOREACH(PlayerSounds, true, LAMBDA( + FOREACH(PlayerSounds, true, { .string fld = it.m_playersoundfld; if (this.(fld)) - { - strunzone(this.(fld)); - this.(fld) = string_null; - } - )); + { + strunzone(this.(fld)); + this.(fld) = string_null; + } + }); } bool LoadPlayerSounds(entity this, string f, bool strict) @@ -290,12 +316,10 @@ LoadPlayerSounds(this, get_model_datafilename(this.model, 0, "sounds"), true); } - #endif + //#endif #ifdef SVQC - bool autocvar_g_debug_globalsounds; - void _GlobalSound(entity this, entity gs, entity ps, string sample, int chan, int voicetype, bool fake) { if (gs == NULL && ps == NULL && sample == "") return; @@ -343,10 +367,10 @@ if (fake) { msg_entity = this; X(); } else { - FOREACH_CLIENT(IS_REAL_CLIENT(it) && (!teamplay || msg_entity.team == this.team), LAMBDA( + FOREACH_CLIENT(IS_REAL_CLIENT(it) && (!teamplay || msg_entity.team == this.team), { msg_entity = it; X(); - )); + }); } #undef X break; @@ -370,13 +394,7 @@ ? bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, \ ATTEN_MAX) \ : ATTEN_NONE; \ - if (gs) \ - { \ - if(autocvar_g_debug_globalsounds) \ - globalsound(MSG_ONE, this, gs, r, chan, VOL_BASEVOICE, atten); \ - else \ - soundto(MSG_ONE, this, chan, GlobalSound_sample(gs.m_globalsoundstr, r), VOL_BASE, ATTEN_NORM); \ - } \ + 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); \ } \ @@ -388,10 +406,10 @@ } else { - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA( + FOREACH_CLIENT(IS_REAL_CLIENT(it), { msg_entity = it; X(); - )); + }); } #undef X break; @@ -407,13 +425,7 @@ } else { - if (gs) - { - if(autocvar_g_debug_globalsounds) - globalsound(MSG_ALL, this, gs, r, chan, VOL_BASE, ATTEN_NORM); - else - _sound(this, chan, GlobalSound_sample(gs.m_globalsoundstr, r), VOL_BASE, ATTEN_NORM); - } + 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); } diff --git a/qcsrc/common/effects/qc/globalsound.qh b/qcsrc/common/effects/qc/globalsound.qh index 1c2aa6461..64ef524ec 100644 --- a/qcsrc/common/effects/qc/globalsound.qh +++ b/qcsrc/common/effects/qc/globalsound.qh @@ -19,12 +19,10 @@ REGISTER_REGISTRY(PlayerSounds) REGISTRY_SORT(PlayerSounds) STATIC_INIT(PlayerSounds_renumber) { - FOREACH(PlayerSounds, true, LAMBDA(it.m_id = i)); + FOREACH(PlayerSounds, true, it.m_id = i); } REGISTRY_CHECK(PlayerSounds) -// TODO implement fall and falling - REGISTER_PLAYERSOUND(death) REGISTER_PLAYERSOUND(drown) REGISTER_PLAYERSOUND(fall) @@ -92,13 +90,13 @@ REGISTER_REGISTRY(GlobalSounds) REGISTRY_SORT(GlobalSounds) STATIC_INIT(GlobalSounds_renumber) { - FOREACH(GlobalSounds, true, LAMBDA(it.m_id = i)); + FOREACH(GlobalSounds, true, it.m_id = i); } REGISTRY_CHECK(GlobalSounds) void PrecacheGlobalSound(string samplestring); PRECACHE(GlobalSounds) { - FOREACH(GlobalSounds, true, LAMBDA(PrecacheGlobalSound(it.m_globalsoundstr))); + FOREACH(GlobalSounds, true, PrecacheGlobalSound(it.m_globalsoundstr)); } REGISTER_GLOBALSOUND(STEP, "misc/footstep0 6") @@ -108,13 +106,13 @@ REGISTER_GLOBALSOUND(FALL_METAL, "misc/metalhitground 4") bool GetPlayerSoundSampleField_notFound; void PrecachePlayerSounds(string f); -#ifdef CSQC +//#ifdef CSQC .string GetVoiceMessageSampleField(string type); .string GetPlayerSoundSampleField(string type); void ClearPlayerSounds(entity this); float LoadPlayerSounds(entity this, string f, bool strict); void UpdatePlayerSounds(entity this); -#endif +//#endif #ifdef SVQC diff --git a/qcsrc/common/effects/qc/modeleffects.qc b/qcsrc/common/effects/qc/modeleffects.qc index d7e437eb3..99272f8cc 100644 --- a/qcsrc/common/effects/qc/modeleffects.qc +++ b/qcsrc/common/effects/qc/modeleffects.qc @@ -114,7 +114,7 @@ void ModelEffect_Draw(entity this) NET_HANDLE(ENT_CLIENT_MODELEFFECT, bool isnew) { - make_pure(self); + make_pure(this); int f = ReadByte(); diff --git a/qcsrc/common/ent_cs.qc b/qcsrc/common/ent_cs.qc index dbadc9abb..148d3883f 100644 --- a/qcsrc/common/ent_cs.qc +++ b/qcsrc/common/ent_cs.qc @@ -98,21 +98,21 @@ i += 1; ENTCS_NETPROPS(X); #undef X + setorigin(this, this.origin); // relink } void entcs_attach(entity player) { entity e = player.entcs = new(entcs_sender); - make_pure(e); e.owner = player; e.think = entcs_think; e.nextthink = time; Net_LinkEntity(e, false, 0, entcs_send); if (!IS_REAL_CLIENT(player)) return; - FOREACH_CLIENT(true, LAMBDA( + FOREACH_CLIENT(true, { assert(it.entcs); _entcs_send(it.entcs, msg_entity = player, BITS(23), MSG_ONE); - )); + }); } void entcs_detach(entity player) diff --git a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc index d1ac1b40a..df062641a 100644 --- a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc +++ b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qc @@ -852,48 +852,51 @@ float ball_customize() return true; } - METHOD(BallStealer, wr_think, void(BallStealer thiswep, entity actor, .entity weaponentity, int fire)) - { - if(fire & 1) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, autocvar_g_balance_nexball_primary_refire)) - if(autocvar_g_nexball_basketball_meter) - { - if(self.ballcarried && !self.metertime) - self.metertime = time; - else - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); - } - else - { - W_Nexball_Attack(-1); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); - } - if(fire & 2) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_nexball_secondary_refire)) - { - W_Nexball_Attack2(); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_nexball_secondary_animtime, w_ready); - } +METHOD(BallStealer, wr_think, void(BallStealer thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(fire & 1) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, autocvar_g_balance_nexball_primary_refire)) + if(autocvar_g_nexball_basketball_meter) + { + if(self.ballcarried && !self.metertime) + self.metertime = time; + else + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); + } + else + { + W_Nexball_Attack(-1); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); + } + if(fire & 2) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_nexball_secondary_refire)) + { + W_Nexball_Attack2(); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_nexball_secondary_animtime, w_ready); + } + + if(!(fire & 1) && self.metertime && self.ballcarried) + { + W_Nexball_Attack(time - self.metertime); + // DropBall or stealing will set metertime back to 0 + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); + } +} - if(!(fire & 1) && self.metertime && self.ballcarried) - { - W_Nexball_Attack(time - self.metertime); - // DropBall or stealing will set metertime back to 0 - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready); - } - } - METHOD(BallStealer, wr_setup, void(BallStealer thiswep)) - { - //weapon_setup(WEP_PORTO.m_id); - } - METHOD(BallStealer, wr_checkammo1, bool(BallStealer thiswep)) - { - return true; - } - METHOD(BallStealer, wr_checkammo2, bool(BallStealer thiswep)) - { - return true; - } +METHOD(BallStealer, wr_setup, void(BallStealer thiswep)) +{ + //weapon_setup(WEP_PORTO.m_id); +} + +METHOD(BallStealer, wr_checkammo1, bool(BallStealer thiswep)) +{ + return true; +} + +METHOD(BallStealer, wr_checkammo2, bool(BallStealer thiswep)) +{ + return true; +} void nb_DropBall(entity player) { diff --git a/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc b/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc index 6f246d905..0b030b251 100644 --- a/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc +++ b/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc @@ -530,7 +530,7 @@ void ons_ControlPoint_Icon_Damage(entity this, entity inflictor, entity attacker { sound(this, CH_TRIGGER, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM); pointparticles(EFFECT_ROCKET_EXPLODE, this.origin, '0 0 0', 1); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(this.team, INFO_ONSLAUGHT_CPDESTROYED_), this.owner.message, attacker.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(this.team, INFO_ONSLAUGHT_CPDESTROYED), this.owner.message, attacker.netname); PlayerScore_Add(attacker, SP_ONS_TAKES, 1); PlayerScore_Add(attacker, SP_SCORE, 10); @@ -571,7 +571,7 @@ void ons_ControlPoint_Icon_Think() int _enemy_count = 0; int _friendly_count = 0; - FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), LAMBDA( + FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), { if(vdist(it.origin - self.origin, <, autocvar_g_onslaught_cp_proxydecap_distance)) { if(SAME_TEAM(it, self)) @@ -579,7 +579,7 @@ void ons_ControlPoint_Icon_Think() else ++_enemy_count; } - )); + }); _friendly_count = _friendly_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE); _enemy_count = _enemy_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE); @@ -665,7 +665,7 @@ void ons_ControlPoint_Icon_BuildThink() if(IS_PLAYER(self.owner.ons_toucher)) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ONSLAUGHT_CAPTURE, self.owner.ons_toucher.netname, self.owner.message); - Send_Notification(NOTIF_ALL_EXCEPT, self.owner.ons_toucher, MSG_CENTER, APP_TEAM_ENT_4(self.owner.ons_toucher, CENTER_ONS_CAPTURE_), self.owner.message); + Send_Notification(NOTIF_ALL_EXCEPT, self.owner.ons_toucher, MSG_CENTER, APP_TEAM_NUM(self.owner.ons_toucher.team, CENTER_ONS_CAPTURE), self.owner.message); Send_Notification(NOTIF_ONE, self.owner.ons_toucher, MSG_CENTER, CENTER_ONS_CAPTURE, self.owner.message); PlayerScore_Add(self.owner.ons_toucher, SP_ONS_CAPS, 1); PlayerTeamScore_AddScore(self.owner.ons_toucher, 10); @@ -976,7 +976,7 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d if (time > this.pain_finished) { this.pain_finished = time + 10; - FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && SAME_TEAM(it, this), LAMBDA(Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_GENERATOR_UNDERATTACK))); + FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && SAME_TEAM(it, this), Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_GENERATOR_UNDERATTACK)); play2team(this.team, SND(ONS_GENERATOR_UNDERATTACK)); } } @@ -992,10 +992,10 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d else { if (attacker == this) - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(this.team, INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(this.team, INFO_ONSLAUGHT_GENDESTROYED_OVERTIME)); else { - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(this.team, INFO_ONSLAUGHT_GENDESTROYED_)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(this.team, INFO_ONSLAUGHT_GENDESTROYED)); PlayerScore_Add(attacker, SP_SCORE, 100); } this.iscaptured = false; @@ -1043,15 +1043,15 @@ void ons_GeneratorThink() if(!self.isshielded && self.wait < time) { self.wait = time + 5; - FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA( + FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { if(SAME_TEAM(it, self)) { Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_ONS_NOTSHIELDED_TEAM); soundto(MSG_ONE, it, CHAN_AUTO, SND(KH_ALARM), VOL_BASE, ATTEN_NONE); // FIXME: unique sound? } else - Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_TEAM_NUM_4(self.team, CENTER_ONS_NOTSHIELDED_)); - )); + Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_TEAM_NUM(self.team, CENTER_ONS_NOTSHIELDED)); + }); } } } @@ -1254,8 +1254,8 @@ bool Onslaught_CheckWinner() if(winner_team > 0) { - Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_)); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_)); + Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN)); TeamScore_AddToTeam(winner_team, ST_ONS_CAPS, +1); } else if(winner_team == -1) @@ -1270,12 +1270,12 @@ bool Onslaught_CheckWinner() round_handler_Init(7, autocvar_g_onslaught_warmup, autocvar_g_onslaught_round_timelimit); - FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( + FOREACH_CLIENT(IS_PLAYER(it), { it.ons_roundlost = true; it.player_blocked = true; nades_Clear(it); - )); + }); return 1; } @@ -1288,7 +1288,7 @@ bool Onslaught_CheckPlayers() void Onslaught_RoundStart() { entity tmp_entity; - FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(it.player_blocked = false)); + FOREACH_CLIENT(IS_PLAYER(it), it.player_blocked = false); for(tmp_entity = ons_worldcplist; tmp_entity; tmp_entity = tmp_entity.ons_worldcpnext) tmp_entity.sprite.SendFlags |= 16; @@ -1316,11 +1316,11 @@ void havocbot_goalrating_ons_offenseitems(float ratingscale, vector org, float s // Needs weapons? c = 0; - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { if(self.weapons & (it.m_wepset)) if(++c >= 4) break; - )); + }); if(c<4) needweapons = true; @@ -1397,12 +1397,12 @@ void havocbot_goalrating_ons_controlpoints_attack(float ratingscale) // Count team mates interested in this control point // (easier and cleaner than keeping counters per cp and teams) - FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( + FOREACH_CLIENT(IS_PLAYER(it), { if(SAME_TEAM(it, self)) if(it.havocbot_role_flags & HAVOCBOT_ONS_ROLE_OFFENSE) if(it.havocbot_ons_target == cp2) ++c; - )); + }); // NOTE: probably decrease the cost of attackable control points cp2.wpcost = c; @@ -1772,11 +1772,11 @@ bool ons_Teleport(entity player, entity tele_target, float range, bool tele_effe MUTATOR_HOOKFUNCTION(ons, reset_map_global) {SELFPARAM(); - FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( + FOREACH_CLIENT(IS_PLAYER(it), { it.ons_roundlost = false; it.ons_deathloc = '0 0 0'; WITH(entity, self, it, PutClientInServer()); - )); + }); return false; } diff --git a/qcsrc/common/impulses/all.qh b/qcsrc/common/impulses/all.qh index 433f2318d..6780ac16d 100644 --- a/qcsrc/common/impulses/all.qh +++ b/qcsrc/common/impulses/all.qh @@ -6,7 +6,7 @@ REGISTER_REGISTRY(IMPULSES) REGISTRY_SORT(IMPULSES) STATIC_INIT(IMPULSES_renumber) { - FOREACH(IMPULSES, true, LAMBDA(it.m_id = i)); + FOREACH(IMPULSES, true, it.m_id = i); } REGISTRY_CHECK(IMPULSES) diff --git a/qcsrc/common/items/all.qc b/qcsrc/common/items/all.qc index 927b2ece2..62dc0fe27 100644 --- a/qcsrc/common/items/all.qc +++ b/qcsrc/common/items/all.qc @@ -6,9 +6,7 @@ void Dump_Items() { - FOREACH(Items, true, LAMBDA( - ITEM_HANDLE(Show, it); - )); + FOREACH(Items, true, ITEM_HANDLE(Show, it)); } string Item_Model(string item_mdl) diff --git a/qcsrc/common/items/all.qh b/qcsrc/common/items/all.qh index 1bd22f660..eea1de9a4 100644 --- a/qcsrc/common/items/all.qh +++ b/qcsrc/common/items/all.qh @@ -13,7 +13,7 @@ REGISTER_REGISTRY(Items) REGISTRY_SORT(Items) REGISTRY_CHECK(Items) -STATIC_INIT(Items) { FOREACH(Items, true, LAMBDA(it.m_id = i)); } +STATIC_INIT(Items) { FOREACH(Items, true, it.m_id = i); } void Dump_Items(); diff --git a/qcsrc/common/items/inventory.qh b/qcsrc/common/items/inventory.qh index f748dda88..7780a0054 100644 --- a/qcsrc/common/items/inventory.qh +++ b/qcsrc/common/items/inventory.qh @@ -18,12 +18,12 @@ NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew) { make_pure(this); const int bits = ReadInt24_t(); - FOREACH(Items, bits & BIT(it.m_id), LAMBDA( + FOREACH(Items, bits & BIT(it.m_id), { .int fld = inv_items[it.m_id]; int prev = this.(fld); int next = this.(fld) = ReadByte(); LOG_TRACEF("%s: %.0f -> %.0f\n", it.m_name, prev, next); - )); + }); return true; } #endif @@ -32,14 +32,14 @@ NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew) void Inventory_Write(Inventory data) { int bits = 0; - FOREACH(Items, true, LAMBDA( + FOREACH(Items, true, { .int fld = inv_items[it.m_id]; bits = BITSET(bits, BIT(it.m_id), data.inventory.(fld) != (data.inventory.(fld) = data.(fld))); - )); + }); WriteInt24_t(MSG_ENTITY, bits); - FOREACH(Items, bits & BIT(it.m_id), LAMBDA( + FOREACH(Items, bits & BIT(it.m_id), { WriteByte(MSG_ENTITY, data.inv_items[it.m_id]); - )); + }); } #endif @@ -56,8 +56,7 @@ bool Inventory_Send(entity this, entity to, int sf) void Inventory_new(entity e) { - Inventory inv = new(Inventory), bak = new(Inventory); - make_pure(inv); make_pure(bak); + Inventory inv = new_pure(Inventory), bak = new_pure(Inventory); inv.inventory = bak; inv.drawonlytoclient = e; Net_LinkEntity((inv.owner = e).inventory = inv, false, 0, Inventory_Send); diff --git a/qcsrc/common/items/item.qh b/qcsrc/common/items/item.qh index 0db0d0bea..ba21efd96 100644 --- a/qcsrc/common/items/item.qh +++ b/qcsrc/common/items/item.qh @@ -1,45 +1,42 @@ #ifndef GAMEITEM_H #define GAMEITEM_H -const int IT_UNLIMITED_WEAPON_AMMO = 1; // when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup. -const int IT_UNLIMITED_SUPERWEAPONS = 2; // when this bit is set, superweapons don't expire. Checkpoints can give this powerup. -const int IT_CTF_SHIELDED = 4; // set for the flag shield -const int IT_USING_JETPACK = 8; // confirmation that button is pressed -const int IT_JETPACK = 16; // actual item -const int IT_FUEL_REGEN = 32; // fuel regeneration trigger -// where is 64... ? -const int IT_FUEL = 128; -// -Wdouble-declaration -#define IT_SHELLS 256 -// -Wdouble-declaration -#define IT_NAILS 512 -// -Wdouble-declaration -#define IT_ROCKETS 1024 -// -Wdouble-declaration -#define IT_CELLS 2048 -const int IT_SUPERWEAPON = 4096; -const int IT_STRENGTH = 8192; -const int IT_INVINCIBLE = 16384; -const int IT_HEALTH = 32768; -const int IT_PLASMA = 65536; - -// shared value space (union): - // for items: - // -Wdouble-declaration - #define IT_KEY1 131072 - // -Wdouble-declaration - #define IT_KEY2 262144 -// end - -const int IT_5HP = 524288; -const int IT_25HP = 1048576; -const int IT_ARMOR_SHARD = 2097152; -const int IT_ARMOR = 4194304; +const int IT_UNLIMITED_WEAPON_AMMO = BIT(0); // when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup. +const int IT_UNLIMITED_SUPERWEAPONS = BIT(1); // when this bit is set, superweapons don't expire. Checkpoints can give this powerup. + +const int IT_JETPACK = BIT(2); // actual item +const int IT_USING_JETPACK = BIT(3); // confirmation that button is pressed +const int IT_FUEL_REGEN = BIT(4); // fuel regeneration trigger + +const int IT_FUEL = BIT(5); +const int IT_SHELLS = BIT(6); +const int IT_NAILS = BIT(7); +const int IT_ROCKETS = BIT(8); +const int IT_CELLS = BIT(9); +const int IT_PLASMA = BIT(10); + +const int IT_5HP = BIT(11); +const int IT_25HP = BIT(12); +const int IT_HEALTH = BIT(13); + +const int IT_ARMOR_SHARD = BIT(14); +const int IT_ARMOR = BIT(15); + +const int IT_KEY1 = BIT(16); +const int IT_KEY2 = BIT(17); + +const int IT_CTF_SHIELDED = BIT(18); // set for the flag shield + +// special colorblend meaning in engine +const int IT_INVISIBILITY = BIT(19); +const int IT_INVINCIBLE = BIT(20); +const int IT_SUPERWEAPON = BIT(21); // suit +const int IT_STRENGTH = BIT(22); // item masks -const int IT_AMMO = 3968; // IT_FUEL | IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS | IT_PLASMA; -const int IT_PICKUPMASK = 51; // IT_FUEL_REGEN | IT_JETPACK | IT_UNLIMITED_AMMO; // strength and invincible are handled separately -const int IT_UNLIMITED_AMMO = 3; // IT_UNLIMITED_SUPERWEAPONS | IT_UNLIMITED_WEAPON_AMMO; +const int IT_AMMO = IT_FUEL | IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS | IT_PLASMA; +const int IT_UNLIMITED_AMMO = IT_UNLIMITED_WEAPON_AMMO | IT_UNLIMITED_SUPERWEAPONS; +const int IT_PICKUPMASK = IT_UNLIMITED_AMMO | IT_JETPACK | IT_FUEL_REGEN; // strength and invincible are handled separately #define ITEM_HANDLE(signal, ...) __Item_Send_##signal(__VA_ARGS__) /** If you register a new item, make sure to add it to all.inc */ diff --git a/qcsrc/common/items/item/jetpack.qc b/qcsrc/common/items/item/jetpack.qc index 7ccbe8fa3..7fd29e299 100644 --- a/qcsrc/common/items/item/jetpack.qc +++ b/qcsrc/common/items/item/jetpack.qc @@ -5,6 +5,10 @@ #include "ammo.qh" #include "powerup.qh" +#ifndef SVQC +.int m_itemid; +#endif + #ifndef MENUQC MODEL(Jetpack_ITEM, Item_Model("g_jetpack.md3")); #endif @@ -12,6 +16,7 @@ MODEL(Jetpack_ITEM, Item_Model("g_jetpack.md3")); REGISTER_ITEM(Jetpack, Powerup) { #ifndef MENUQC this.m_model = MDL_Jetpack_ITEM; + this.m_itemid = IT_JETPACK; #endif this.m_name = "Jet pack"; this.m_icon = "jetpack"; @@ -20,7 +25,6 @@ REGISTER_ITEM(Jetpack, Powerup) { this.m_waypointblink = 2; #ifdef SVQC this.m_botvalue = BOT_PICKUP_RATING_LOW; - this.m_itemid = IT_JETPACK; this.m_pickupevalfunc = commodity_pickupevalfunc; #endif } diff --git a/qcsrc/common/items/item/powerup.qc b/qcsrc/common/items/item/powerup.qc index 7deba67df..375f958a1 100644 --- a/qcsrc/common/items/item/powerup.qc +++ b/qcsrc/common/items/item/powerup.qc @@ -1,9 +1,5 @@ #include "powerup.qh" -#ifndef SVQC -.int m_itemid; -#endif - #ifndef MENUQC MODEL(Strength_ITEM, Item_Model("g_strength.md3")); SOUND(Strength, "misc/powerup"); diff --git a/qcsrc/common/mapinfo.qc b/qcsrc/common/mapinfo.qc index 56dcce489..447e7730e 100644 --- a/qcsrc/common/mapinfo.qc +++ b/qcsrc/common/mapinfo.qc @@ -10,11 +10,6 @@ #include "mapinfo.qh" #endif -bool autocvar_developer_mapper; - -#define LOG_MAPWARN(...) MACRO_BEGIN { if (autocvar_developer_mapper) LOG_WARNING(__VA_ARGS__); } MACRO_END -#define LOG_MAPWARNF(...) MACRO_BEGIN { if (autocvar_developer_mapper) LOG_WARNINGF(__VA_ARGS__); } MACRO_END - // generic string stuff int _MapInfo_Cache_Active; @@ -602,13 +597,13 @@ void _MapInfo_Map_ApplyGametype(string s, int pWantedType, int pThisType, int lo string _MapInfo_GetDefaultEx(float t) { - FOREACH(Gametypes, it.items == t, LAMBDA(return it.model2)); + FOREACH(Gametypes, it.items == t, return it.model2); return ""; } float _MapInfo_GetTeamPlayBool(float t) { - FOREACH(Gametypes, it.items == t, LAMBDA(return it.team)); + FOREACH(Gametypes, it.items == t, return it.team); return false; } @@ -623,7 +618,7 @@ void _MapInfo_Map_ApplyGametypeEx(string s, int pWantedType, int pThisType) cvar_set("timelimit", cvar_defstring("timelimit")); cvar_set("leadlimit", cvar_defstring("leadlimit")); cvar_set("fraglimit", cvar_defstring("fraglimit")); - FOREACH(Gametypes, true, LAMBDA(it.m_parse_mapinfo(string_null, string_null))); + FOREACH(Gametypes, true, it.m_parse_mapinfo(string_null, string_null)); string fraglimit_normal = string_null; string fraglimit_teams = string_null; @@ -671,7 +666,7 @@ void _MapInfo_Map_ApplyGametypeEx(string s, int pWantedType, int pThisType) break; } } - FOREACH(Gametypes, true, LAMBDA(handled |= it.m_parse_mapinfo(k, v))); + FOREACH(Gametypes, true, handled |= it.m_parse_mapinfo(k, v)); if (!handled) LOG_MAPWARNF("Invalid gametype setting in mapinfo for gametype %s: %s\n", MapInfo_Type_ToString(pWantedType), sa); } @@ -690,7 +685,7 @@ void _MapInfo_Map_ApplyGametypeEx(string s, int pWantedType, int pThisType) Gametype MapInfo_Type(int t) { - FOREACH(Gametypes, it.items == t, LAMBDA(return it)); + FOREACH(Gametypes, it.items == t, return it); return NULL; } @@ -710,14 +705,14 @@ int MapInfo_Type_FromString(string t) deprecate(assault, as); deprecate(race, rc); if (t == "all") return MAPINFO_TYPE_ALL; - FOREACH(Gametypes, it.mdl == t, LAMBDA(return it.items)); + FOREACH(Gametypes, it.mdl == t, return it.items); return 0; #undef deprecate } string MapInfo_Type_Description(float t) { - FOREACH(Gametypes, it.items == t, LAMBDA(return it.gametype_description)); + FOREACH(Gametypes, it.items == t, return it.gametype_description); return ""; } @@ -725,13 +720,13 @@ string MapInfo_Type_ToString(float t) { if(t == MAPINFO_TYPE_ALL) return "all"; - FOREACH(Gametypes, it.items == t, LAMBDA(return it.mdl)); + FOREACH(Gametypes, it.items == t, return it.mdl); return ""; } string MapInfo_Type_ToText(float t) { - FOREACH(Gametypes, it.items == t, LAMBDA(return it.message)); + FOREACH(Gametypes, it.items == t, return it.message); /* xgettext:no-c-format */ return _("@!#%'n Tuba Throwing"); } @@ -1241,7 +1236,7 @@ int MapInfo_CurrentFeatures() int MapInfo_CurrentGametype() { int prev = cvar("gamecfg"); - FOREACH(Gametypes, cvar(it.netname) && it.items != prev, LAMBDA(return it.items)); + FOREACH(Gametypes, cvar(it.netname) && it.items != prev, return it.items); if (prev) return prev; return MAPINFO_TYPE_DEATHMATCH; } @@ -1267,9 +1262,7 @@ float MapInfo_CheckMap(string s) // returns 0 if the map can't be played with th void MapInfo_SwitchGameType(int t) { - FOREACH(Gametypes, true, LAMBDA( - cvar_set(it.netname, (it.items == t) ? "1" : "0") - )); + FOREACH(Gametypes, true, cvar_set(it.netname, (it.items == t) ? "1" : "0")); } void MapInfo_LoadMap(string s, float reinit) diff --git a/qcsrc/common/mapinfo.qh b/qcsrc/common/mapinfo.qh index 702798bbf..ab7233ef2 100644 --- a/qcsrc/common/mapinfo.qh +++ b/qcsrc/common/mapinfo.qh @@ -1,6 +1,11 @@ #ifndef MAPINFO_H #define MAPINFO_H +bool autocvar_developer_mapper; + +#define LOG_MAPWARN(...) MACRO_BEGIN { if (autocvar_developer_mapper) LOG_WARNING(__VA_ARGS__); } MACRO_END +#define LOG_MAPWARNF(...) MACRO_BEGIN { if (autocvar_developer_mapper) LOG_WARNINGF(__VA_ARGS__); } MACRO_END + #include "util.qh" CLASS(Gametype, Object) diff --git a/qcsrc/common/minigames/cl_minigames.qh b/qcsrc/common/minigames/cl_minigames.qh index a97cabbf9..596d9204c 100644 --- a/qcsrc/common/minigames/cl_minigames.qh +++ b/qcsrc/common/minigames/cl_minigames.qh @@ -121,7 +121,6 @@ REGISTRY_CHECK(Minigames) void name##_hud_status(vector, vector); \ int name##_client_event(entity, string, ...); \ REGISTER_INIT_POST(MINIGAME_##name) { \ - make_pure(this); \ this.netname = strzone(strtolower(#name)); \ this.message = nicename; \ this.minigame_hud_board = name##_hud_board; \ diff --git a/qcsrc/common/minigames/cl_minigames_hud.qc b/qcsrc/common/minigames/cl_minigames_hud.qc index 6a585e68e..50fd2bab5 100644 --- a/qcsrc/common/minigames/cl_minigames_hud.qc +++ b/qcsrc/common/minigames/cl_minigames_hud.qc @@ -213,15 +213,13 @@ void HUD_MinigameMenu_ClickCreate() { entity curr; entity prev = self; - FOREACH(Minigames, true, LAMBDA( - { - curr = HUD_MinigameMenu_SpawnSubEntry( - it.message, HUD_MinigameMenu_ClickCreate_Entry, self ); + FOREACH(Minigames, true, { + curr = HUD_MinigameMenu_SpawnSubEntry(it.message, HUD_MinigameMenu_ClickCreate_Entry, self); curr.netname = it.netname; curr.model = strzone(minigame_texture(strcat(it.netname,"/icon"))); HUD_MinigameMenu_InsertEntry( curr, prev ); prev = curr; - })); + }); } } @@ -685,7 +683,7 @@ void HUD_Minigame_Mouse() if ( HUD_MinigameMenu_IsOpened() && HUD_mouse_over(HUD_PANEL(MINIGAME_MENU)) ) HUD_MinigameMenu_MouseInput(); - draw_cursor_normal(mousepos-'8 4 0', '1 1 1', panel_fg_alpha); + draw_cursor_normal(mousepos, '1 1 1', panel_fg_alpha); } bool HUD_Minigame_Showpanels() diff --git a/qcsrc/common/minigames/minigames.qc b/qcsrc/common/minigames/minigames.qc index 2a632339c..71cf41a3a 100644 --- a/qcsrc/common/minigames/minigames.qc +++ b/qcsrc/common/minigames/minigames.qc @@ -4,12 +4,8 @@ REGISTER_NET_LINKED(ENT_CLIENT_MINIGAME) entity minigame_get_descriptor(string id) { - FOREACH(Minigames, true, LAMBDA( - { - if(it.netname == id) - return it; - })); - return world; + FOREACH(Minigames, it.netname == id, return it); + return NULL; } // Get letter index of a tile name diff --git a/qcsrc/common/minigames/sv_minigames.qc b/qcsrc/common/minigames/sv_minigames.qc index ca111e6c8..7c19c43dd 100644 --- a/qcsrc/common/minigames/sv_minigames.qc +++ b/qcsrc/common/minigames/sv_minigames.qc @@ -337,10 +337,7 @@ void ClientCommand_minigame(int request, int argc, string command) } else if ( minig_cmd == "list" ) { - FOREACH(Minigames, true, LAMBDA( - { - sprint(self,it.netname," (",it.message,") ","\n"); - })); + FOREACH(Minigames, true, sprint(self, it.netname, " (", it.message, ") ", "\n")); return; } else if ( minig_cmd == "list-sessions" ) diff --git a/qcsrc/common/minigames/sv_minigames.qh b/qcsrc/common/minigames/sv_minigames.qh index cde614416..ecef02856 100644 --- a/qcsrc/common/minigames/sv_minigames.qh +++ b/qcsrc/common/minigames/sv_minigames.qh @@ -54,7 +54,6 @@ REGISTRY_CHECK(Minigames) REGISTER(Minigames, MINIGAME_##name, m_id, new_pure(minigame_descriptor)); \ int name##_server_event(entity, string, ...); \ REGISTER_INIT_POST(MINIGAME_##name) { \ - make_pure(this); \ this.netname = strzone(strtolower(#name)); \ this.message = nicename; \ this.minigame_event = name##_server_event; \ diff --git a/qcsrc/common/models/all.qh b/qcsrc/common/models/all.qh index ac95c2c84..f3bfd64c7 100644 --- a/qcsrc/common/models/all.qh +++ b/qcsrc/common/models/all.qh @@ -11,10 +11,13 @@ REGISTER_REGISTRY(Models) string MDL_##name##_get() { return path; } \ REGISTER(Models, MDL, name, m_id, NEW(Model, MDL_##name##_get)) +STATIC_INIT(NULLMDL) +{ + precache_model("null"); +} + PRECACHE(Models) { - FOREACH(Models, true, LAMBDA({ - it.model_precache(it); - })); + FOREACH(Models, true, it.model_precache(it)); } MODEL(Null, "null"); diff --git a/qcsrc/common/monsters/monster/mage.qc b/qcsrc/common/monsters/monster/mage.qc index 37c6301fb..c71e8c911 100644 --- a/qcsrc/common/monsters/monster/mage.qc +++ b/qcsrc/common/monsters/monster/mage.qc @@ -408,81 +408,85 @@ spawnfunc(monster_mage) { Monster_Spawn(this, MON_MAGE.monsterid); } #endif // SVQC - #ifdef SVQC - METHOD(Mage, mr_think, bool(Mage thismon, entity actor)) - { - bool need_help = false; +#ifdef SVQC +METHOD(Mage, mr_think, bool(Mage thismon, entity actor)) +{ + bool need_help = false; - FOREACH_ENTITY_FLOAT(iscreature, true, - { - if(it != actor) - if(vdist(it.origin - actor.origin, <=, autocvar_g_monster_mage_heal_range)) - if(M_Mage_Defend_Heal_Check(actor, it)) - { - need_help = true; - break; - } - }); + FOREACH_ENTITY_FLOAT(iscreature, true, + { + if(it != actor) + if(vdist(it.origin - actor.origin, <=, autocvar_g_monster_mage_heal_range)) + if(M_Mage_Defend_Heal_Check(actor, it)) + { + need_help = true; + break; + } + }); + + if(actor.health < (autocvar_g_monster_mage_heal_minhealth) || need_help) + if(time >= actor.attack_finished_single[0]) + if(random() < 0.5) + M_Mage_Defend_Heal(actor); + + if(time >= actor.mage_shield_time && actor.armorvalue) + M_Mage_Defend_Shield_Remove(actor); + + if(actor.enemy) + if(actor.health < actor.max_health) + if(time >= actor.mage_shield_delay) + if(random() < 0.5) + M_Mage_Defend_Shield(actor); + + return true; +} - if(actor.health < (autocvar_g_monster_mage_heal_minhealth) || need_help) - if(time >= actor.attack_finished_single[0]) - if(random() < 0.5) - M_Mage_Defend_Heal(actor); +METHOD(Mage, mr_pain, bool(Mage thismon, entity actor)) +{ + return true; +} - if(time >= actor.mage_shield_time && actor.armorvalue) - M_Mage_Defend_Shield_Remove(actor); +METHOD(Mage, mr_death, bool(Mage thismon, entity actor)) +{ + setanim(actor, actor.anim_die1, false, true, true); + return true; +} - if(actor.enemy) - if(actor.health < actor.max_health) - if(time >= actor.mage_shield_delay) - if(random() < 0.5) - M_Mage_Defend_Shield(actor); +#endif +#ifndef MENUQC +METHOD(Mage, mr_anim, bool(Mage thismon, entity actor)) +{ + vector none = '0 0 0'; + actor.anim_die1 = animfixfps(actor, '4 1 0.5', none); // 2 seconds + actor.anim_walk = animfixfps(actor, '1 1 1', none); + actor.anim_idle = animfixfps(actor, '0 1 1', none); + actor.anim_pain1 = animfixfps(actor, '3 1 2', none); // 0.5 seconds + actor.anim_shoot = animfixfps(actor, '2 1 5', none); // analyze models and set framerate + actor.anim_run = animfixfps(actor, '5 1 1', none); + return true; +} +#endif +#ifdef SVQC +.float speed; +spawnfunc(item_health_large); +METHOD(Mage, mr_setup, bool(Mage thismon, entity actor)) +{ + if(!actor.health) actor.health = (autocvar_g_monster_mage_health); + if(!actor.speed) { actor.speed = (autocvar_g_monster_mage_speed_walk); } + if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_mage_speed_run); } + if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_mage_speed_stop); } + if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_mage_damageforcescale); } - return true; - } - METHOD(Mage, mr_pain, bool(Mage thismon, entity actor)) - { - return true; - } - METHOD(Mage, mr_death, bool(Mage thismon, entity actor)) - { - setanim(actor, actor.anim_die1, false, true, true); - return true; - } - #endif - #ifndef MENUQC - METHOD(Mage, mr_anim, bool(Mage thismon, entity actor)) - { - vector none = '0 0 0'; - actor.anim_die1 = animfixfps(actor, '4 1 0.5', none); // 2 seconds - actor.anim_walk = animfixfps(actor, '1 1 1', none); - actor.anim_idle = animfixfps(actor, '0 1 1', none); - actor.anim_pain1 = animfixfps(actor, '3 1 2', none); // 0.5 seconds - actor.anim_shoot = animfixfps(actor, '2 1 5', none); // analyze models and set framerate - actor.anim_run = animfixfps(actor, '5 1 1', none); - return true; - } - #endif - #ifdef SVQC - .float speed; - spawnfunc(item_health_large); - METHOD(Mage, mr_setup, bool(Mage thismon, entity actor)) - { - if(!actor.health) actor.health = (autocvar_g_monster_mage_health); - if(!actor.speed) { actor.speed = (autocvar_g_monster_mage_speed_walk); } - if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_mage_speed_run); } - if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_mage_speed_stop); } - if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_mage_damageforcescale); } + actor.monster_loot = spawnfunc_item_health_large; + actor.monster_attackfunc = M_Mage_Attack; - actor.monster_loot = spawnfunc_item_health_large; - actor.monster_attackfunc = M_Mage_Attack; + return true; +} - return true; - } - METHOD(Mage, mr_precache, bool(Mage thismon)) - { - return true; - } - #endif +METHOD(Mage, mr_precache, bool(Mage thismon)) +{ + return true; +} +#endif #endif diff --git a/qcsrc/common/monsters/monster/shambler.qc b/qcsrc/common/monsters/monster/shambler.qc index 0ffa60f8c..b09171279 100644 --- a/qcsrc/common/monsters/monster/shambler.qc +++ b/qcsrc/common/monsters/monster/shambler.qc @@ -224,65 +224,68 @@ bool M_Shambler_Attack(int attack_type, entity actor, entity targ) spawnfunc(monster_shambler) { Monster_Spawn(this, MON_SHAMBLER.monsterid); } #endif // SVQC - #ifdef SVQC - METHOD(Shambler, mr_think, bool(Shambler thismon, entity actor)) - { - return true; - } - METHOD(Shambler, mr_pain, bool(Shambler thismon, entity actor)) - { - actor.pain_finished = time + 0.5; - setanim(actor, actor.anim_pain1, true, true, false); - return true; - } - METHOD(Shambler, mr_death, bool(Shambler thismon, entity actor)) - { - setanim(actor, actor.anim_die1, false, true, true); - return true; - } - #endif - #ifndef MENUQC - METHOD(Shambler, mr_anim, bool(Shambler thismon, entity actor)) - { - vector none = '0 0 0'; - actor.anim_die1 = animfixfps(actor, '8 1 0.5', none); // 2 seconds - actor.anim_walk = animfixfps(actor, '1 1 1', none); - actor.anim_idle = animfixfps(actor, '0 1 1', none); - actor.anim_pain1 = animfixfps(actor, '7 1 2', none); // 0.5 seconds - actor.anim_melee1 = animfixfps(actor, '3 1 5', none); // analyze models and set framerate - actor.anim_melee2 = animfixfps(actor, '4 1 5', none); // analyze models and set framerate - actor.anim_melee3 = animfixfps(actor, '5 1 5', none); // analyze models and set framerate - actor.anim_shoot = animfixfps(actor, '6 1 5', none); // analyze models and set framerate - actor.anim_run = animfixfps(actor, '2 1 1', none); - return true; - } - #endif - #ifdef SVQC - spawnfunc(item_health_mega); - .float animstate_endtime; - METHOD(Shambler, mr_setup, bool(Shambler thismon, entity actor)) - { - if(!actor.health) actor.health = (autocvar_g_monster_shambler_health); - if(!actor.attack_range) actor.attack_range = 150; - if(!actor.speed) { actor.speed = (autocvar_g_monster_shambler_speed_walk); } - if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_shambler_speed_run); } - if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_shambler_speed_stop); } - if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_shambler_damageforcescale); } +#ifdef SVQC +METHOD(Shambler, mr_think, bool(Shambler thismon, entity actor)) +{ + return true; +} - actor.monster_loot = spawnfunc_item_health_mega; - actor.weapon = WEP_ELECTRO.m_id; // matches attacks better than WEP_VORTEX +METHOD(Shambler, mr_pain, bool(Shambler thismon, entity actor)) +{ + actor.pain_finished = time + 0.5; + setanim(actor, actor.anim_pain1, true, true, false); + return true; +} - setanim(actor, actor.anim_shoot, false, true, true); - actor.spawn_time = actor.animstate_endtime; - actor.spawnshieldtime = actor.spawn_time; - actor.monster_attackfunc = M_Shambler_Attack; +METHOD(Shambler, mr_death, bool(Shambler thismon, entity actor)) +{ + setanim(actor, actor.anim_die1, false, true, true); + return true; +} +#endif +#ifndef MENUQC +METHOD(Shambler, mr_anim, bool(Shambler thismon, entity actor)) +{ + vector none = '0 0 0'; + actor.anim_die1 = animfixfps(actor, '8 1 0.5', none); // 2 seconds + actor.anim_walk = animfixfps(actor, '1 1 1', none); + actor.anim_idle = animfixfps(actor, '0 1 1', none); + actor.anim_pain1 = animfixfps(actor, '7 1 2', none); // 0.5 seconds + actor.anim_melee1 = animfixfps(actor, '3 1 5', none); // analyze models and set framerate + actor.anim_melee2 = animfixfps(actor, '4 1 5', none); // analyze models and set framerate + actor.anim_melee3 = animfixfps(actor, '5 1 5', none); // analyze models and set framerate + actor.anim_shoot = animfixfps(actor, '6 1 5', none); // analyze models and set framerate + actor.anim_run = animfixfps(actor, '2 1 1', none); + return true; +} +#endif +#ifdef SVQC +spawnfunc(item_health_mega); +.float animstate_endtime; +METHOD(Shambler, mr_setup, bool(Shambler thismon, entity actor)) +{ + if(!actor.health) actor.health = (autocvar_g_monster_shambler_health); + if(!actor.attack_range) actor.attack_range = 150; + if(!actor.speed) { actor.speed = (autocvar_g_monster_shambler_speed_walk); } + if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_shambler_speed_run); } + if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_shambler_speed_stop); } + if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_shambler_damageforcescale); } + + actor.monster_loot = spawnfunc_item_health_mega; + actor.weapon = WEP_ELECTRO.m_id; // matches attacks better than WEP_VORTEX + + setanim(actor, actor.anim_shoot, false, true, true); + actor.spawn_time = actor.animstate_endtime; + actor.spawnshieldtime = actor.spawn_time; + actor.monster_attackfunc = M_Shambler_Attack; + + return true; +} - return true; - } - METHOD(Shambler, mr_precache, bool(Shambler thismon)) - { - return true; - } - #endif +METHOD(Shambler, mr_precache, bool(Shambler thismon)) +{ + return true; +} +#endif #endif diff --git a/qcsrc/common/monsters/monster/spider.qc b/qcsrc/common/monsters/monster/spider.qc index 89239941e..512422d33 100644 --- a/qcsrc/common/monsters/monster/spider.qc +++ b/qcsrc/common/monsters/monster/spider.qc @@ -214,53 +214,56 @@ bool M_Spider_Attack(int attack_type, entity actor, entity targ) spawnfunc(monster_spider) { Monster_Spawn(this, MON_SPIDER.monsterid); } #endif // SVQC - #ifdef SVQC - METHOD(Spider, mr_think, bool(Spider thismon, entity actor)) - { - return true; - } - METHOD(Spider, mr_pain, bool(Spider thismon, entity actor)) - { - return true; - } - METHOD(Spider, mr_death, bool(Spider thismon, entity actor)) - { - setanim(actor, actor.anim_melee, false, true, true); - actor.angles_x = 180; - return true; - } - #endif - #ifndef MENUQC - METHOD(Spider, mr_anim, bool(Spider thismon, entity actor)) - { - vector none = '0 0 0'; - actor.anim_walk = animfixfps(actor, '1 1 1', none); - actor.anim_idle = animfixfps(actor, '0 1 1', none); - actor.anim_melee = animfixfps(actor, '2 1 5', none); // analyze models and set framerate - actor.anim_shoot = animfixfps(actor, '3 1 5', none); // analyze models and set framerate - actor.anim_run = animfixfps(actor, '1 1 1', none); - return true; - } - #endif - #ifdef SVQC - spawnfunc(item_health_medium); - METHOD(Spider, mr_setup, bool(Spider thismon, entity actor)) - { - if(!actor.health) actor.health = (autocvar_g_monster_spider_health); - if(!actor.speed) { actor.speed = (autocvar_g_monster_spider_speed_walk); } - if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_spider_speed_run); } - if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_spider_speed_stop); } - if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_spider_damageforcescale); } +#ifdef SVQC +METHOD(Spider, mr_think, bool(Spider thismon, entity actor)) +{ + return true; +} - actor.monster_loot = spawnfunc_item_health_medium; - actor.monster_attackfunc = M_Spider_Attack; +METHOD(Spider, mr_pain, bool(Spider thismon, entity actor)) +{ + return true; +} - return true; - } - METHOD(Spider, mr_precache, bool(Spider thismon)) - { - return true; - } - #endif +METHOD(Spider, mr_death, bool(Spider thismon, entity actor)) +{ + setanim(actor, actor.anim_melee, false, true, true); + actor.angles_x = 180; + return true; +} +#endif +#ifndef MENUQC +METHOD(Spider, mr_anim, bool(Spider thismon, entity actor)) +{ + vector none = '0 0 0'; + actor.anim_walk = animfixfps(actor, '1 1 1', none); + actor.anim_idle = animfixfps(actor, '0 1 1', none); + actor.anim_melee = animfixfps(actor, '2 1 5', none); // analyze models and set framerate + actor.anim_shoot = animfixfps(actor, '3 1 5', none); // analyze models and set framerate + actor.anim_run = animfixfps(actor, '1 1 1', none); + return true; +} +#endif +#ifdef SVQC +spawnfunc(item_health_medium); +METHOD(Spider, mr_setup, bool(Spider thismon, entity actor)) +{ + if(!actor.health) actor.health = (autocvar_g_monster_spider_health); + if(!actor.speed) { actor.speed = (autocvar_g_monster_spider_speed_walk); } + if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_spider_speed_run); } + if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_spider_speed_stop); } + if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_spider_damageforcescale); } + + actor.monster_loot = spawnfunc_item_health_medium; + actor.monster_attackfunc = M_Spider_Attack; + + return true; +} + +METHOD(Spider, mr_precache, bool(Spider thismon)) +{ + return true; +} +#endif #endif diff --git a/qcsrc/common/monsters/monster/wyvern.qc b/qcsrc/common/monsters/monster/wyvern.qc index b7d398da6..fc13de40f 100644 --- a/qcsrc/common/monsters/monster/wyvern.qc +++ b/qcsrc/common/monsters/monster/wyvern.qc @@ -142,58 +142,61 @@ bool M_Wyvern_Attack(int attack_type, entity actor, entity targ) spawnfunc(monster_wyvern) { Monster_Spawn(this, MON_WYVERN.monsterid); } #endif // SVQC - #ifdef SVQC - METHOD(Wyvern, mr_think, bool(Wyvern thismon, entity actor)) - { - return true; - } - METHOD(Wyvern, mr_pain, bool(Wyvern thismon, entity actor)) - { - actor.pain_finished = time + 0.5; - setanim(actor, actor.anim_pain1, true, true, false); - return true; - } - METHOD(Wyvern, mr_death, bool(Wyvern thismon, entity actor)) - { - setanim(actor, actor.anim_die1, false, true, true); - actor.velocity_x = -200 + 400 * random(); - actor.velocity_y = -200 + 400 * random(); - actor.velocity_z = 100 + 100 * random(); - return true; - } - #endif - #ifndef MENUQC - METHOD(Wyvern, mr_anim, bool(Wyvern thismon, entity actor)) - { - vector none = '0 0 0'; - actor.anim_die1 = animfixfps(actor, '4 1 0.5', none); // 2 seconds - actor.anim_walk = animfixfps(actor, '1 1 1', none); - actor.anim_idle = animfixfps(actor, '0 1 1', none); - actor.anim_pain1 = animfixfps(actor, '3 1 2', none); // 0.5 seconds - actor.anim_shoot = animfixfps(actor, '2 1 5', none); // analyze models and set framerate - actor.anim_run = animfixfps(actor, '1 1 1', none); - return true; - } - #endif - #ifdef SVQC - spawnfunc(item_cells); - METHOD(Wyvern, mr_setup, bool(Wyvern thismon, entity actor)) - { - if(!actor.health) actor.health = (autocvar_g_monster_wyvern_health); - if(!actor.speed) { actor.speed = (autocvar_g_monster_wyvern_speed_walk); } - if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_wyvern_speed_run); } - if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_wyvern_speed_stop); } - if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_wyvern_damageforcescale); } +#ifdef SVQC +METHOD(Wyvern, mr_think, bool(Wyvern thismon, entity actor)) +{ + return true; +} - actor.monster_loot = spawnfunc_item_cells; - actor.monster_attackfunc = M_Wyvern_Attack; +METHOD(Wyvern, mr_pain, bool(Wyvern thismon, entity actor)) +{ + actor.pain_finished = time + 0.5; + setanim(actor, actor.anim_pain1, true, true, false); + return true; +} - return true; - } - METHOD(Wyvern, mr_precache, bool(Wyvern thismon)) - { - return true; - } - #endif +METHOD(Wyvern, mr_death, bool(Wyvern thismon, entity actor)) +{ + setanim(actor, actor.anim_die1, false, true, true); + actor.velocity_x = -200 + 400 * random(); + actor.velocity_y = -200 + 400 * random(); + actor.velocity_z = 100 + 100 * random(); + return true; +} +#endif +#ifndef MENUQC +METHOD(Wyvern, mr_anim, bool(Wyvern thismon, entity actor)) +{ + vector none = '0 0 0'; + actor.anim_die1 = animfixfps(actor, '4 1 0.5', none); // 2 seconds + actor.anim_walk = animfixfps(actor, '1 1 1', none); + actor.anim_idle = animfixfps(actor, '0 1 1', none); + actor.anim_pain1 = animfixfps(actor, '3 1 2', none); // 0.5 seconds + actor.anim_shoot = animfixfps(actor, '2 1 5', none); // analyze models and set framerate + actor.anim_run = animfixfps(actor, '1 1 1', none); + return true; +} +#endif +#ifdef SVQC +spawnfunc(item_cells); +METHOD(Wyvern, mr_setup, bool(Wyvern thismon, entity actor)) +{ + if(!actor.health) actor.health = (autocvar_g_monster_wyvern_health); + if(!actor.speed) { actor.speed = (autocvar_g_monster_wyvern_speed_walk); } + if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_wyvern_speed_run); } + if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_wyvern_speed_stop); } + if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_wyvern_damageforcescale); } + + actor.monster_loot = spawnfunc_item_cells; + actor.monster_attackfunc = M_Wyvern_Attack; + + return true; +} + +METHOD(Wyvern, mr_precache, bool(Wyvern thismon)) +{ + return true; +} +#endif #endif diff --git a/qcsrc/common/monsters/monster/zombie.qc b/qcsrc/common/monsters/monster/zombie.qc index b522a9647..9163aaf07 100644 --- a/qcsrc/common/monsters/monster/zombie.qc +++ b/qcsrc/common/monsters/monster/zombie.qc @@ -154,76 +154,79 @@ bool M_Zombie_Attack(int attack_type, entity actor, entity targ) spawnfunc(monster_zombie) { Monster_Spawn(this, MON_ZOMBIE.monsterid); } #endif // SVQC - #ifdef SVQC - METHOD(Zombie, mr_think, bool(Zombie thismon, entity actor)) - { - if(time >= actor.spawn_time) - actor.damageforcescale = autocvar_g_monster_zombie_damageforcescale; - return true; - } - METHOD(Zombie, mr_pain, bool(Zombie thismon, entity actor)) - { - actor.pain_finished = time + 0.34; - setanim(actor, ((random() > 0.5) ? actor.anim_pain1 : actor.anim_pain2), true, true, false); - return true; - } - METHOD(Zombie, mr_death, bool(Zombie thismon, entity actor)) - { - actor.armorvalue = autocvar_g_monsters_armor_blockpercent; +#ifdef SVQC +METHOD(Zombie, mr_think, bool(Zombie thismon, entity actor)) +{ + if(time >= actor.spawn_time) + actor.damageforcescale = autocvar_g_monster_zombie_damageforcescale; + return true; +} - setanim(actor, ((random() > 0.5) ? actor.anim_die1 : actor.anim_die2), false, true, true); - return true; - } - #endif - #ifndef MENUQC - METHOD(Zombie, mr_anim, bool(Zombie thismon, entity actor)) - { - vector none = '0 0 0'; - actor.anim_die1 = animfixfps(actor, '9 1 0.5', none); // 2 seconds - actor.anim_die2 = animfixfps(actor, '12 1 0.5', none); // 2 seconds - actor.anim_spawn = animfixfps(actor, '30 1 3', none); - actor.anim_walk = animfixfps(actor, '27 1 1', none); - actor.anim_idle = animfixfps(actor, '19 1 1', none); - actor.anim_pain1 = animfixfps(actor, '20 1 2', none); // 0.5 seconds - actor.anim_pain2 = animfixfps(actor, '22 1 2', none); // 0.5 seconds - actor.anim_melee1 = animfixfps(actor, '4 1 5', none); // analyze models and set framerate - actor.anim_melee2 = animfixfps(actor, '4 1 5', none); // analyze models and set framerate - actor.anim_melee3 = animfixfps(actor, '4 1 5', none); // analyze models and set framerate - actor.anim_shoot = animfixfps(actor, '0 1 5', none); // analyze models and set framerate - actor.anim_run = animfixfps(actor, '27 1 1', none); - actor.anim_blockstart = animfixfps(actor, '8 1 1', none); - actor.anim_blockend = animfixfps(actor, '7 1 1', none); - return true; - } - #endif - #ifdef SVQC - METHOD(Zombie, mr_setup, bool(Zombie thismon, entity actor)) - { - if(!actor.health) actor.health = (autocvar_g_monster_zombie_health); - if(!actor.speed) { actor.speed = (autocvar_g_monster_zombie_speed_walk); } - if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_zombie_speed_run); } - if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_zombie_speed_stop); } +METHOD(Zombie, mr_pain, bool(Zombie thismon, entity actor)) +{ + actor.pain_finished = time + 0.34; + setanim(actor, ((random() > 0.5) ? actor.anim_pain1 : actor.anim_pain2), true, true, false); + return true; +} - if(actor.spawnflags & MONSTERFLAG_NORESPAWN) - actor.spawnflags &= ~MONSTERFLAG_NORESPAWN; // zombies always respawn +METHOD(Zombie, mr_death, bool(Zombie thismon, entity actor)) +{ + actor.armorvalue = autocvar_g_monsters_armor_blockpercent; - actor.spawnflags |= MONSTER_RESPAWN_DEATHPOINT; + setanim(actor, ((random() > 0.5) ? actor.anim_die1 : actor.anim_die2), false, true, true); + return true; +} +#endif +#ifndef MENUQC +METHOD(Zombie, mr_anim, bool(Zombie thismon, entity actor)) +{ + vector none = '0 0 0'; + actor.anim_die1 = animfixfps(actor, '9 1 0.5', none); // 2 seconds + actor.anim_die2 = animfixfps(actor, '12 1 0.5', none); // 2 seconds + actor.anim_spawn = animfixfps(actor, '30 1 3', none); + actor.anim_walk = animfixfps(actor, '27 1 1', none); + actor.anim_idle = animfixfps(actor, '19 1 1', none); + actor.anim_pain1 = animfixfps(actor, '20 1 2', none); // 0.5 seconds + actor.anim_pain2 = animfixfps(actor, '22 1 2', none); // 0.5 seconds + actor.anim_melee1 = animfixfps(actor, '4 1 5', none); // analyze models and set framerate + actor.anim_melee2 = animfixfps(actor, '4 1 5', none); // analyze models and set framerate + actor.anim_melee3 = animfixfps(actor, '4 1 5', none); // analyze models and set framerate + actor.anim_shoot = animfixfps(actor, '0 1 5', none); // analyze models and set framerate + actor.anim_run = animfixfps(actor, '27 1 1', none); + actor.anim_blockstart = animfixfps(actor, '8 1 1', none); + actor.anim_blockend = animfixfps(actor, '7 1 1', none); + return true; +} +#endif +#ifdef SVQC +METHOD(Zombie, mr_setup, bool(Zombie thismon, entity actor)) +{ + if(!actor.health) actor.health = (autocvar_g_monster_zombie_health); + if(!actor.speed) { actor.speed = (autocvar_g_monster_zombie_speed_walk); } + if(!actor.speed2) { actor.speed2 = (autocvar_g_monster_zombie_speed_run); } + if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_zombie_speed_stop); } - actor.monster_loot = spawnfunc_item_health_medium; - actor.monster_attackfunc = M_Zombie_Attack; - actor.spawnshieldtime = actor.spawn_time; - actor.respawntime = 0.2; - actor.damageforcescale = 0.0001; // no push while spawning + if(actor.spawnflags & MONSTERFLAG_NORESPAWN) + actor.spawnflags &= ~MONSTERFLAG_NORESPAWN; // zombies always respawn - setanim(actor, actor.anim_spawn, false, true, true); - actor.spawn_time = actor.animstate_endtime; + actor.spawnflags |= MONSTER_RESPAWN_DEATHPOINT; - return true; - } - METHOD(Zombie, mr_precache, bool(Zombie thismon)) - { - return true; - } - #endif + actor.monster_loot = spawnfunc_item_health_medium; + actor.monster_attackfunc = M_Zombie_Attack; + actor.spawnshieldtime = actor.spawn_time; + actor.respawntime = 0.2; + actor.damageforcescale = 0.0001; // no push while spawning + + setanim(actor, actor.anim_spawn, false, true, true); + actor.spawn_time = actor.animstate_endtime; + + return true; +} + +METHOD(Zombie, mr_precache, bool(Zombie thismon)) +{ + return true; +} +#endif #endif diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index ccc3b83aa..8f1d80276 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -90,7 +90,7 @@ bool Monster_ValidTarget(entity this, entity targ) || (!IS_VEHICLE(targ) && (IS_DEAD(targ) || IS_DEAD(this) || targ.health <= 0 || this.health <= 0)) || (this.monster_follow == targ || targ.monster_follow == this) || (!IS_VEHICLE(targ) && (targ.flags & FL_NOTARGET)) - || (!autocvar_g_monsters_typefrag && targ.BUTTON_CHAT) + || (!autocvar_g_monsters_typefrag && PHYS_INPUT_BUTTON_CHAT(targ)) || (SAME_TEAM(targ, this)) || (STAT(FROZEN, targ)) || (targ.alpha != 0 && targ.alpha < 0.5) @@ -1361,6 +1361,9 @@ bool Monster_Spawn(entity this, int mon_id) if(autocvar_g_nodepthtestplayers) { this.effects |= EF_NODEPTHTEST; } if(mon.spawnflags & MONSTER_TYPE_SWIM) { this.flags |= FL_SWIM; } + if(autocvar_g_playerclip_collisions) + this.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP; + if(mon.spawnflags & MONSTER_TYPE_FLY) { this.flags |= FL_FLY; diff --git a/qcsrc/common/mutators/base.qh b/qcsrc/common/mutators/base.qh index 62df8dcbc..79cba7f92 100644 --- a/qcsrc/common/mutators/base.qh +++ b/qcsrc/common/mutators/base.qh @@ -166,6 +166,7 @@ void Mutator_Remove(Mutator mut); bool mutator_log = false; #ifndef MENUQC +/** server mutators activate corresponding client mutators for all clients */ REGISTER_NET_LINKED(Mutator) #ifdef SVQC @@ -183,11 +184,12 @@ void NET_Mutator_Remove(entity this) { string s = this.netname; WITH(bool, mutator_log, true, LAMBDA( - FOREACH(Mutators, it.registered_id == s, LAMBDA(Mutator_Remove(it))); + FOREACH(Mutators, it.registered_id == s, Mutator_Remove(it)); )); } NET_HANDLE(Mutator, bool isNew) { + make_pure(this); string s = this.netname = ReadString(); return = true; if (isNew) @@ -196,7 +198,7 @@ NET_HANDLE(Mutator, bool isNew) this.entremove = NET_Mutator_Remove; int added = 0; WITH(bool, mutator_log, true, LAMBDA( - FOREACH(Mutators, it.registered_id == s, LAMBDA(Mutator_Add(it); ++added)); + FOREACH(Mutators, it.registered_id == s, { Mutator_Add(it); ++added; }); )); if (added > 1) LOG_WARNINGF("Added more than one mutator for %s\n", s); } @@ -276,7 +278,7 @@ STATIC_INIT(Mutators) { } STATIC_INIT_LATE(Mutators) { - FOREACH(Mutators, it.mutatorcheck(), LAMBDA(Mutator_Add(it))); + FOREACH(Mutators, it.mutatorcheck(), Mutator_Add(it)); } #define MUTATOR_ONADD if (mode == MUTATOR_ADDING) diff --git a/qcsrc/common/mutators/mutator/bloodloss/bloodloss.qc b/qcsrc/common/mutators/mutator/bloodloss/bloodloss.qc index 4543ae10e..de3d19038 100644 --- a/qcsrc/common/mutators/mutator/bloodloss/bloodloss.qc +++ b/qcsrc/common/mutators/mutator/bloodloss/bloodloss.qc @@ -8,7 +8,7 @@ MUTATOR_HOOKFUNCTION(bloodloss, PlayerPreThink) if(IS_PLAYER(self)) if(self.health <= autocvar_g_bloodloss && !IS_DEAD(self)) { - self.BUTTON_CROUCH = true; + PHYS_INPUT_BUTTON_CROUCH(self) = true; if(time >= self.bloodloss_timer) { diff --git a/qcsrc/common/mutators/mutator/buffs/buffs.qc b/qcsrc/common/mutators/mutator/buffs/buffs.qc index 903237f92..30e19f0f5 100644 --- a/qcsrc/common/mutators/mutator/buffs/buffs.qc +++ b/qcsrc/common/mutators/mutator/buffs/buffs.qc @@ -755,7 +755,7 @@ MUTATOR_HOOKFUNCTION(buffs, ForbidThrowCurrentWeapon) // set pusher so self gets the kill if they fall into void closest.pusher = self; closest.pushltime = time + autocvar_g_maxpushtime; - closest.istypefrag = closest.BUTTON_CHAT; + closest.istypefrag = PHYS_INPUT_BUTTON_CHAT(closest); Send_Effect(EFFECT_ELECTRO_COMBO, their_org, '0 0 0', 1); Send_Effect(EFFECT_ELECTRO_COMBO, my_org, '0 0 0', 1); @@ -1031,11 +1031,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerRegen) return false; } -MUTATOR_HOOKFUNCTION(buffs, GetCvars) -{ - GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_buffs_autoreplace, "cl_buffs_autoreplace"); - return false; -} +REPLICATE(cvar_cl_buffs_autoreplace, bool, "cl_buffs_autoreplace"); MUTATOR_HOOKFUNCTION(buffs, BuildMutatorsString) { diff --git a/qcsrc/common/mutators/mutator/campcheck/campcheck.qc b/qcsrc/common/mutators/mutator/campcheck/campcheck.qc index 4916464a1..1d0bd19eb 100644 --- a/qcsrc/common/mutators/mutator/campcheck/campcheck.qc +++ b/qcsrc/common/mutators/mutator/campcheck/campcheck.qc @@ -10,7 +10,7 @@ REGISTER_MUTATOR(campcheck, cvar("g_campcheck")); MUTATOR_HOOKFUNCTION(campcheck, PlayerDies) { - Kill_Notification(NOTIF_ONE, frag_target, MSG_CENTER_CPID, CPID_CAMPCHECK); + Kill_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CPID_CAMPCHECK); return false; } @@ -36,7 +36,7 @@ MUTATOR_HOOKFUNCTION(campcheck, PlayerPreThink) if(IS_REAL_CLIENT(self)) // bots may camp, but that's no reason to constantly kill them if(!IS_DEAD(self)) if(!STAT(FROZEN, self)) - if(!self.BUTTON_CHAT) + if(!PHYS_INPUT_BUTTON_CHAT(self)) if(autocvar_g_campcheck_interval) { vector dist; diff --git a/qcsrc/common/mutators/mutator/damagetext/damagetext.qc b/qcsrc/common/mutators/mutator/damagetext/damagetext.qc index 6a33ab34e..70c574853 100644 --- a/qcsrc/common/mutators/mutator/damagetext/damagetext.qc +++ b/qcsrc/common/mutators/mutator/damagetext/damagetext.qc @@ -13,7 +13,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_format, string, "-%3$$d", "How to format the damage text. 1$ is health, 2$ is armor, 3$ is both"); +AUTOCVAR_SAVE(cl_damagetext_format, string, "-{total}", "How to format the damage text. {health}, {armor}, {total}"); AUTOCVAR_SAVE(cl_damagetext_color, vector, '1 1 0', "Damage text color"); AUTOCVAR_SAVE(cl_damagetext_color_per_weapon, bool, false, "Damage text uses weapon color"); AUTOCVAR_SAVE(cl_damagetext_size, float, 8, "Damage text font size"); @@ -51,7 +51,10 @@ CLASS(DamageText, Object) Weapon w = DEATH_WEAPONOF(this.m_deathtype); if (w != WEP_Null) rgb = w.wpcolor; } - string s = sprintf(autocvar_cl_damagetext_format, this.m_damage, this.m_armordamage, this.m_damage + this.m_armordamage); + string s = autocvar_cl_damagetext_format; + s = strreplace("{health}", sprintf("%d", this.m_damage), s); + s = strreplace("{armor}", sprintf("%d", this.m_armordamage), s); + s = strreplace("{total}", sprintf("%d", this.m_damage + this.m_armordamage), s); drawcolorcodedstring2(pos, s, this.m_size * '1 1 0', rgb, this.alpha, DRAWFLAG_NORMAL); } } @@ -98,8 +101,8 @@ MUTATOR_HOOKFUNCTION(damagetext, PlayerDamaged) { ) { msg_entity = it; WriteHeader(MSG_ONE, damagetext); - WriteShort(MSG_ONE, health); - WriteShort(MSG_ONE, armor); + WriteShort(MSG_ONE, rint(health)); + WriteShort(MSG_ONE, rint(armor)); WriteEntity(MSG_ONE, hit); WriteCoord(MSG_ONE, location.x); WriteCoord(MSG_ONE, location.y); diff --git a/qcsrc/common/mutators/mutator/dodging/dodging.qc b/qcsrc/common/mutators/mutator/dodging/dodging.qc index 6d3662c73..1707d0a9d 100644 --- a/qcsrc/common/mutators/mutator/dodging/dodging.qc +++ b/qcsrc/common/mutators/mutator/dodging/dodging.qc @@ -275,11 +275,7 @@ MUTATOR_HOOKFUNCTION(dodging, PlayerPhysics) #ifdef SVQC -MUTATOR_HOOKFUNCTION(dodging, GetCvars) -{ - GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout"); - return false; -} +REPLICATE(cvar_cl_dodging_timeout, float, "cl_dodging_timeout"); MUTATOR_HOOKFUNCTION(dodging, GetPressedKeys) { diff --git a/qcsrc/common/mutators/mutator/instagib/instagib.qc b/qcsrc/common/mutators/mutator/instagib/instagib.qc index 640e3d5b6..33773131a 100644 --- a/qcsrc/common/mutators/mutator/instagib/instagib.qc +++ b/qcsrc/common/mutators/mutator/instagib/instagib.qc @@ -52,7 +52,7 @@ void instagib_stop_countdown(entity e) { if (!e.instagib_needammo) return; - Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_INSTAGIB_FINDAMMO); + Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER, CPID_INSTAGIB_FINDAMMO); e.instagib_needammo = false; } void instagib_ammocheck() @@ -293,7 +293,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerDamage_Calculate) frag_target.armorvalue -= 1; frag_damage = 0; frag_target.damage_dealt += 1; - frag_attacker.damage_dealt += 1; // TODO: change this to a specific hitsound for armor hit + frag_attacker.damage_dealt += 1; Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_INSTAGIB_LIVES_REMAINING, frag_target.armorvalue); } } diff --git a/qcsrc/common/mutators/mutator/multijump/multijump.qc b/qcsrc/common/mutators/mutator/multijump/multijump.qc index 43be345c1..c4a2e40fc 100644 --- a/qcsrc/common/mutators/mutator/multijump/multijump.qc +++ b/qcsrc/common/mutators/mutator/multijump/multijump.qc @@ -21,7 +21,7 @@ REGISTER_MUTATOR(multijump, true); .bool multijump_ready; #ifdef CSQC -bool autocvar_cl_multijump = false; +bool autocvar_cl_multijump = true; #define PHYS_MULTIJUMP_CLIENT(s) autocvar_cl_multijump #elif defined(SVQC) @@ -116,11 +116,7 @@ MUTATOR_HOOKFUNCTION(multijump, PlayerJump) #ifdef SVQC -MUTATOR_HOOKFUNCTION(multijump, GetCvars) -{ - GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_multijump, "cl_multijump"); - return false; -} +REPLICATE(cvar_cl_multijump, bool, "cl_multijump"); MUTATOR_HOOKFUNCTION(multijump, BuildMutatorsString) { diff --git a/qcsrc/common/mutators/mutator/nades/nades.qc b/qcsrc/common/mutators/mutator/nades/nades.qc index fcfce9ab7..250a3ef71 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qc +++ b/qcsrc/common/mutators/mutator/nades/nades.qc @@ -2,6 +2,12 @@ #ifdef IMPLEMENTATION +#ifdef SVQC +bool autocvar_g_nades_nade_small; +#endif + +REGISTER_STAT(NADES_SMALL, int, autocvar_g_nades_nade_small) + #ifndef MENUQC entity Nade_TrailEffect(int proj, int nade_team) { @@ -63,8 +69,16 @@ MUTATOR_HOOKFUNCTION(cl_nades, EditProjectile) entity nade_type = Nade_FromProjectile(self.cnt); if (nade_type == NADE_TYPE_Null) return; - self.mins = '-16 -16 -16'; - self.maxs = '16 16 16'; + if(STAT(NADES_SMALL, NULL)) + { + self.mins = '-8 -8 -8'; + self.maxs = '8 8 8'; + } + else + { + self.mins = '-16 -16 -16'; + self.maxs = '16 16 16'; + } self.colormod = nade_type.m_color; self.move_movetype = MOVETYPE_BOUNCE; self.move_touch = func_null; @@ -242,7 +256,7 @@ void nade_napalm_ball() proj = new(grenade); proj.owner = self.owner; proj.realowner = self.realowner; - proj.team = self.owner.team; + proj.team = self.team; proj.bot_dodge = true; proj.bot_dodgerating = autocvar_g_nades_napalm_ball_damage; proj.movetype = MOVETYPE_BOUNCE; @@ -360,7 +374,7 @@ void nade_ice_think() { if ( autocvar_g_nades_ice_explode ) { - entity expef = EFFECT_NADE_EXPLODE(self.realowner.team); + entity expef = EFFECT_NADE_EXPLODE(self.team); Send_Effect(expef, self.origin + '0 0 1', '0 0 0', 1); sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); @@ -555,7 +569,7 @@ void nade_heal_boom() setorigin(healer, self.origin); healer.healer_lifetime = autocvar_g_nades_heal_time; // save the cvar healer.ltime = time + healer.healer_lifetime; - healer.team = self.realowner.team; + healer.team = self.team; healer.bot_dodge = false; healer.solid = SOLID_TRIGGER; healer.touch = nade_heal_touch; @@ -602,7 +616,7 @@ void nade_boom() case NADE_TYPE_MONSTER: case NADE_TYPE_SPAWN: nade_blast = false; - switch(self.realowner.team) + switch(self.team) { case NUM_TEAM_1: expef = EFFECT_SPAWN_RED; break; case NUM_TEAM_2: expef = EFFECT_SPAWN_BLUE; break; @@ -618,7 +632,7 @@ void nade_boom() default: case NADE_TYPE_NORMAL: - expef = EFFECT_NADE_EXPLODE(self.realowner.team); + expef = EFFECT_NADE_EXPLODE(self.team); break; } @@ -657,6 +671,20 @@ void nade_boom() remove(self); } +void spawn_held_nade(entity player, entity nowner, float ntime, int ntype, string pntype); +void nade_pickup(entity this, entity thenade) +{ + spawn_held_nade(this, thenade.realowner, autocvar_g_nades_pickup_time, thenade.nade_type, thenade.pokenade_type); + + // set refire so player can't even + this.nade_refire = time + autocvar_g_nades_nade_refire; + this.nade_timer = 0; + + if(this.nade) + this.nade.nade_time_primed = thenade.nade_time_primed; +} + +bool CanThrowNade(entity this); void nade_touch() {SELFPARAM(); if(other) @@ -664,6 +692,19 @@ void nade_touch() if(other == self.realowner) return; // no self impacts + + if(autocvar_g_nades_pickup) + if(time >= self.spawnshieldtime) + if(!other.nade && self.health == self.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 + { + nade_pickup(other, self); + sound(self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX)); + remove(self); + return; + } /*float is_weapclip = 0; if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODRAW) if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID)) @@ -758,7 +799,10 @@ void nade_damage(entity this, entity inflictor, entity attacker, float damage, i this.health -= damage; if ( this.nade_type != NADE_TYPE_HEAL.m_id || IS_PLAYER(attacker) ) + { + this.team = attacker.team; this.realowner = attacker; + } if(this.health <= 0) WITH(entity, self, this, W_PrepareExplosionByDamage(attacker, nade_boom)); @@ -766,7 +810,7 @@ void nade_damage(entity this, entity inflictor, entity attacker, float damage, i nade_burn_spawn(this); } -void toss_nade(entity e, vector _velocity, float _time) +void toss_nade(entity e, bool set_owner, vector _velocity, float _time) {SELFPARAM(); if(e.nade == world) return; @@ -781,7 +825,7 @@ void toss_nade(entity e, vector _velocity, float _time) W_SetupShot(e, false, false, "", CH_WEAPON_A, 0); - Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_NADES); + Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER, CPID_NADES); vector offset = (v_forward * autocvar_g_nades_throw_offset.x) + (v_right * autocvar_g_nades_throw_offset.y) @@ -793,14 +837,17 @@ void toss_nade(entity e, vector _velocity, float _time) //setmodel(_nade, MDL_PROJECTILE_NADE); //setattachment(_nade, world, ""); PROJECTILE_MAKETRIGGER(_nade); - setsize(_nade, '-16 -16 -16', '16 16 16'); + if(STAT(NADES_SMALL, e)) + setsize(_nade, '-8 -8 -8', '8 8 8'); + else + setsize(_nade, '-16 -16 -16', '16 16 16'); _nade.movetype = MOVETYPE_BOUNCE; tracebox(_nade.origin, _nade.mins, _nade.maxs, _nade.origin, false, _nade); if (trace_startsolid) setorigin(_nade, e.origin); - if(self.v_angle.x >= 70 && self.v_angle.x <= 110 && self.BUTTON_CROUCH) + if(self.v_angle.x >= 70 && self.v_angle.x <= 110 && PHYS_INPUT_BUTTON_CROUCH(self)) _nade.velocity = '0 0 100'; else if(autocvar_g_nades_nade_newton_style == 1) _nade.velocity = e.velocity + _velocity; @@ -809,7 +856,11 @@ void toss_nade(entity e, vector _velocity, float _time) else _nade.velocity = W_CalculateProjectileVelocity(e.velocity, _velocity, true); + if(set_owner) + _nade.realowner = e; + _nade.touch = nade_touch; + _nade.spawnshieldtime = time + 0.1; // prevent instantly picking up again _nade.health = autocvar_g_nades_nade_health; _nade.max_health = _nade.health; _nade.takedamage = DAMAGE_AIM; @@ -881,7 +932,7 @@ MUTATOR_HOOKFUNCTION(nades, PutClientInServer) float nade_customize() {SELFPARAM(); //if(IS_SPEC(other)) { return false; } - if(other == self.realowner || (IS_SPEC(other) && other.enemy == self.realowner)) + if(other == self.exteriormodeltoclient || (IS_SPEC(other) && other.enemy == self.exteriormodeltoclient)) { // somewhat hide the model, but keep the glow //self.effects = 0; @@ -900,6 +951,43 @@ float nade_customize() return true; } +void spawn_held_nade(entity player, entity nowner, float ntime, int ntype, string pntype) +{ + entity n = new(nade), fn = new(fake_nade); + + n.nade_type = bound(1, ntype, Nades_COUNT); + n.pokenade_type = pntype; + + setmodel(n, MDL_PROJECTILE_NADE); + //setattachment(n, player, "bip01 l hand"); + n.exteriormodeltoclient = player; + n.customizeentityforclient = nade_customize; + n.team = player.team; + n.traileffectnum = _particleeffectnum(Nade_TrailEffect(Nades_from(n.nade_type).m_projectile[false], n.team).eent_eff_name); + n.colormod = Nades_from(n.nade_type).m_color; + n.realowner = nowner; + n.colormap = player.colormap; + n.glowmod = player.glowmod; + n.wait = time + max(0, ntime); + n.nade_time_primed = time; + n.think = nade_beep; + n.nextthink = max(n.wait - 3, time); + n.projectiledeathtype = DEATH_NADE.m_id; + + setmodel(fn, MDL_NADE_VIEW); + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + setattachment(fn, player.(weaponentity), ""); + fn.realowner = fn.owner = player; + fn.colormod = Nades_from(n.nade_type).m_color; + fn.colormap = player.colormap; + fn.glowmod = player.glowmod; + fn.think = SUB_Remove_self; + fn.nextthink = n.wait; + + player.nade = n; + player.fake_nade = fn; +} + void nade_prime() {SELFPARAM(); if(autocvar_g_nades_bonus_only) @@ -912,71 +1000,44 @@ void nade_prime() if(self.fake_nade) remove(self.fake_nade); - entity n = new(nade), fn = new(fake_nade); + int ntype; + string pntype = self.pokenade_type; if(self.items & ITEM_Strength.m_itemid && autocvar_g_nades_bonus_onstrength) - n.nade_type = self.nade_type; + ntype = self.nade_type; else if (self.bonus_nades >= 1) { - n.nade_type = self.nade_type; - n.pokenade_type = self.pokenade_type; + ntype = self.nade_type; + pntype = self.pokenade_type; self.bonus_nades -= 1; } else { - n.nade_type = ((autocvar_g_nades_client_select) ? self.cvar_cl_nade_type : autocvar_g_nades_nade_type); - n.pokenade_type = ((autocvar_g_nades_client_select) ? self.cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type); + ntype = ((autocvar_g_nades_client_select) ? self.cvar_cl_nade_type : autocvar_g_nades_nade_type); + pntype = ((autocvar_g_nades_client_select) ? self.cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type); } - n.nade_type = bound(1, n.nade_type, Nades_COUNT); - - setmodel(n, MDL_PROJECTILE_NADE); - //setattachment(n, self, "bip01 l hand"); - n.exteriormodeltoclient = self; - n.customizeentityforclient = nade_customize; - n.traileffectnum = _particleeffectnum(Nade_TrailEffect(Nades_from(n.nade_type).m_projectile[false], self.team).eent_eff_name); - n.colormod = Nades_from(n.nade_type).m_color; - n.realowner = self; - n.colormap = self.colormap; - n.glowmod = self.glowmod; - n.wait = time + autocvar_g_nades_nade_lifetime; - n.nade_time_primed = time; - n.think = nade_beep; - n.nextthink = max(n.wait - 3, time); - n.projectiledeathtype = DEATH_NADE.m_id; - - setmodel(fn, MDL_NADE_VIEW); - .entity weaponentity = weaponentities[0]; // TODO: unhardcode - setattachment(fn, self.(weaponentity), ""); - fn.realowner = fn.owner = self; - fn.colormod = Nades_from(n.nade_type).m_color; - fn.colormap = self.colormap; - fn.glowmod = self.glowmod; - fn.think = SUB_Remove_self; - fn.nextthink = n.wait; - - self.nade = n; - self.fake_nade = fn; + spawn_held_nade(self, self, autocvar_g_nades_nade_lifetime, ntype, pntype); } -float CanThrowNade() -{SELFPARAM(); - if(self.vehicle) +bool CanThrowNade(entity this) +{ + if(this.vehicle) return false; if(gameover) return false; - if(IS_DEAD(self)) + if(IS_DEAD(this)) return false; if (!autocvar_g_nades) return false; // allow turning them off mid match - if(forbidWeaponUse(self)) + if(forbidWeaponUse(this)) return false; - if (!IS_PLAYER(self)) + if (!IS_PLAYER(this)) return false; return true; @@ -986,7 +1047,7 @@ float CanThrowNade() void nades_CheckThrow() {SELFPARAM(); - if(!CanThrowNade()) + if(!CanThrowNade(self)) return; entity held_nade = self.nade; @@ -1008,7 +1069,7 @@ void nades_CheckThrow() float _force = time - held_nade.nade_time_primed; _force /= autocvar_g_nades_nade_lifetime; _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce)); - toss_nade(self, (v_forward * 0.75 + v_up * 0.2 + v_right * 0.05) * _force, 0); + toss_nade(self, true, (v_forward * 0.75 + v_up * 0.2 + v_right * 0.05) * _force, 0); } } } @@ -1027,7 +1088,7 @@ void nades_Clear(entity player) MUTATOR_HOOKFUNCTION(nades, VehicleEnter) { if(vh_player.nade) - toss_nade(vh_player, '0 0 100', max(vh_player.nade.wait, time + 0.05)); + toss_nade(vh_player, true, '0 0 100', max(vh_player.nade.wait, time + 0.05)); return false; } @@ -1046,10 +1107,10 @@ CLASS(NadeOffhand, OffhandWeapon) held_nade.angles_y = player.angles.y; if (time + 0.1 >= held_nade.wait) - toss_nade(player, '0 0 0', time + 0.05); + toss_nade(player, false, '0 0 0', time + 0.05); } - if (!CanThrowNade()) return; + if (!CanThrowNade(player)) return; if (!(time > player.nade_refire)) return; if (key_pressed) { if (!held_nade) { @@ -1062,7 +1123,7 @@ CLASS(NadeOffhand, OffhandWeapon) float _force = time - held_nade.nade_time_primed; _force /= autocvar_g_nades_nade_lifetime; _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce)); - toss_nade(player, (v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0); + toss_nade(player, false, (v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0); } } } @@ -1201,7 +1262,7 @@ MUTATOR_HOOKFUNCTION(nades, PlayerDies, CBC_ORDER_LAST) { if(frag_target.nade) if(!STAT(FROZEN, frag_target) || !autocvar_g_freezetag_revive_nade) - toss_nade(frag_target, '0 0 100', max(frag_target.nade.wait, time + 0.05)); + toss_nade(frag_target, true, '0 0 100', max(frag_target.nade.wait, time + 0.05)); float killcount_bonus = ((frag_attacker.killcount >= 1) ? bound(0, autocvar_g_nades_bonus_score_minor * frag_attacker.killcount, autocvar_g_nades_bonus_score_medium) : autocvar_g_nades_bonus_score_minor); @@ -1264,7 +1325,7 @@ MUTATOR_HOOKFUNCTION(nades, MonsterDies) MUTATOR_HOOKFUNCTION(nades, DropSpecialItems) { if(frag_target.nade) - toss_nade(frag_target, '0 0 0', time + 0.05); + toss_nade(frag_target, true, '0 0 0', time + 0.05); return false; } @@ -1292,13 +1353,8 @@ MUTATOR_HOOKFUNCTION(nades, SpectateCopy) return false; } -MUTATOR_HOOKFUNCTION(nades, GetCvars) -{ - GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_nade_type, "cl_nade_type"); - GetCvars_handleString(get_cvars_s, get_cvars_f, cvar_cl_pokenade_type, "cl_pokenade_type"); - - return false; -} +REPLICATE(cvar_cl_nade_type, int, "cl_nade_type"); +REPLICATE(cvar_cl_pokenade_type, string, "cl_pokenade_type"); MUTATOR_HOOKFUNCTION(nades, BuildMutatorsString) { diff --git a/qcsrc/common/mutators/mutator/new_toys/new_toys.qc b/qcsrc/common/mutators/mutator/new_toys/new_toys.qc index ab0567d3a..014c22508 100644 --- a/qcsrc/common/mutators/mutator/new_toys/new_toys.qc +++ b/qcsrc/common/mutators/mutator/new_toys/new_toys.qc @@ -122,7 +122,6 @@ bool nt_IsNewToy(int w) case WEP_MINE_LAYER.m_id: case WEP_HLAC.m_id: case WEP_RIFLE.m_id: - case WEP_SHOCKWAVE.m_id: return true; default: return false; diff --git a/qcsrc/common/mutators/mutator/overkill/hmg.qc b/qcsrc/common/mutators/mutator/overkill/hmg.qc index c08c3690e..30473e09b 100644 --- a/qcsrc/common/mutators/mutator/overkill/hmg.qc +++ b/qcsrc/common/mutators/mutator/overkill/hmg.qc @@ -56,7 +56,7 @@ spawnfunc(weapon_hmg) { weapon_defaultspawnfunc(this, WEP_HMG); } void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int fire) { - if (!actor.BUTTON_ATCK) + if (!PHYS_INPUT_BUTTON_ATCK(actor)) { w_ready(thiswep, actor, weaponentity, fire); return; @@ -98,72 +98,78 @@ void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weapone weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(hmg, refire), W_HeavyMachineGun_Attack_Auto); } - METHOD(HeavyMachineGun, wr_aim, void(entity thiswep)) - { - if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200)) - self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false); - else - self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false); - } - METHOD(HeavyMachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(WEP_CVAR(hmg, reload_ammo) && actor.clip_load < WEP_CVAR(hmg, ammo)) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else - { - if (fire & 1) - if (weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) - { - actor.misc_bulletcounter = 0; - W_HeavyMachineGun_Attack_Auto(thiswep, actor, weaponentity, fire); - } - } - } - METHOD(HeavyMachineGun, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo); - - if(autocvar_g_balance_hmg_reload_ammo) - ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo); - - return ammo_amount; - } - METHOD(HeavyMachineGun, wr_checkammo2, bool(entity thiswep)) - { - float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo); - - if(autocvar_g_balance_hmg_reload_ammo) - ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo); - - return ammo_amount; - } - METHOD(HeavyMachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, WEP_CVAR(hmg, ammo), SND(RELOAD)); - } - METHOD(HeavyMachineGun, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_THINKING_WITH_PORTALS; - } - METHOD(HeavyMachineGun, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_HMG_MURDER_SNIPE; - else - return WEAPON_HMG_MURDER_SPRAY; - } +METHOD(HeavyMachineGun, wr_aim, void(entity thiswep)) +{ + if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200)) + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false); + else + PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false); +} + +METHOD(HeavyMachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(WEP_CVAR(hmg, reload_ammo) && actor.clip_load < WEP_CVAR(hmg, ammo)) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else + { + if (fire & 1) + if (weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) + { + actor.misc_bulletcounter = 0; + W_HeavyMachineGun_Attack_Auto(thiswep, actor, weaponentity, fire); + } + } +} + +METHOD(HeavyMachineGun, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo); + + if(autocvar_g_balance_hmg_reload_ammo) + ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo); + + return ammo_amount; +} + +METHOD(HeavyMachineGun, wr_checkammo2, bool(entity thiswep)) +{ + float ammo_amount = self.ammo_nails >= WEP_CVAR(hmg, ammo); + + if(autocvar_g_balance_hmg_reload_ammo) + ammo_amount += self.(weapon_load[WEP_HMG.m_id]) >= WEP_CVAR(hmg, ammo); + + return ammo_amount; +} + +METHOD(HeavyMachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, WEP_CVAR(hmg, ammo), SND(RELOAD)); +} + +METHOD(HeavyMachineGun, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_THINKING_WITH_PORTALS; +} + +METHOD(HeavyMachineGun, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_HMG_MURDER_SNIPE; + else + return WEAPON_HMG_MURDER_SPRAY; +} #endif #ifdef CSQC - METHOD(HeavyMachineGun, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_MACHINEGUN_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_NORM); - } +METHOD(HeavyMachineGun, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_MACHINEGUN_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_NORM); +} #endif #endif diff --git a/qcsrc/common/mutators/mutator/overkill/overkill.qc b/qcsrc/common/mutators/mutator/overkill/overkill.qc index f0db0836a..125025f20 100644 --- a/qcsrc/common/mutators/mutator/overkill/overkill.qc +++ b/qcsrc/common/mutators/mutator/overkill/overkill.qc @@ -77,7 +77,7 @@ void ok_IncreaseCharge(entity ent, int wep) if (wepent == WEP_Null) return; // dummy if(ent.ok_use_ammocharge) - if(!ent.BUTTON_ATCK) // not while attacking? + if(!PHYS_INPUT_BUTTON_ATCK(ent)) // not while attacking? ent.ammo_charge[wep] = min(autocvar_g_overkill_ammo_charge_limit, ent.ammo_charge[wep] + cvar(sprintf("g_overkill_ammo_charge_rate_%s", wepent.netname)) * frametime / W_TICSPERFRAME); } @@ -182,13 +182,18 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) if(self.ok_lastwep) { - PS(self).m_switchweapon = Weapons_from(self.ok_lastwep); + Weapon newwep = Weapons_from(self.ok_lastwep); + if(self.ok_lastwep == WEP_HMG.m_id) + newwep = WEP_MACHINEGUN; + if(self.ok_lastwep == WEP_RPC.m_id) + newwep = WEP_VORTEX; + PS(self).m_switchweapon = newwep; self.ok_lastwep = 0; } ok_IncreaseCharge(self, PS(self).m_weapon.m_id); - if(self.BUTTON_ATCK2) + if(PHYS_INPUT_BUTTON_ATCK2(self)) if(!forbidWeaponUse(self) || self.weapon_blocked) // allow if weapon is blocked if(time >= self.jump_interval) { @@ -220,7 +225,7 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) if(self.ok_use_ammocharge) if(!ok_CheckWeaponCharge(self, PS(self).m_weapon.m_id)) { - if(autocvar_g_overkill_ammo_charge_notice && time > self.ok_notice_time && self.BUTTON_ATCK && IS_REAL_CLIENT(self) && PS(self).m_weapon == PS(self).m_switchweapon) + if(autocvar_g_overkill_ammo_charge_notice && time > self.ok_notice_time && PHYS_INPUT_BUTTON_ATCK(self) && IS_REAL_CLIENT(self) && PS(self).m_weapon == PS(self).m_switchweapon) { //Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_OVERKILL_CHARGE); self.ok_notice_time = time + 2; @@ -229,12 +234,12 @@ MUTATOR_HOOKFUNCTION(ok, PlayerPreThink) Weapon wpn = PS(self).m_weapon; .entity weaponentity = weaponentities[0]; // TODO: unhardcode if(self.(weaponentity).state != WS_CLEAR) - w_ready(wpn, self, weaponentity, (self.BUTTON_ATCK ? 1 : 0) | (self.BUTTON_ATCK2 ? 2 : 0)); + w_ready(wpn, self, weaponentity, PHYS_INPUT_BUTTON_ATCK(self) | (PHYS_INPUT_BUTTON_ATCK2(self) << 1)); self.weapon_blocked = true; } - self.BUTTON_ATCK2 = 0; + PHYS_INPUT_BUTTON_ATCK2(self) = false; return false; } @@ -251,6 +256,10 @@ MUTATOR_HOOKFUNCTION(ok, PlayerSpawn) else self.ok_use_ammocharge = 0; + // if player changed their weapon while dead, don't switch to their death weapon + if(self.impulse) + self.ok_lastwep = 0; + self.ok_pauseregen_finished = time + 2; return false; diff --git a/qcsrc/common/mutators/mutator/overkill/rpc.qc b/qcsrc/common/mutators/mutator/overkill/rpc.qc index 96e54d5a0..50362a1de 100644 --- a/qcsrc/common/mutators/mutator/overkill/rpc.qc +++ b/qcsrc/common/mutators/mutator/overkill/rpc.qc @@ -150,74 +150,80 @@ void W_RocketPropelledChainsaw_Attack (Weapon thiswep) MUTATOR_CALLHOOK(EditProjectile, self, missile); } - METHOD(RocketPropelledChainsaw, wr_aim, void(entity thiswep)) - { - self.BUTTON_ATCK = bot_aim(WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false); - } - METHOD(RocketPropelledChainsaw, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(WEP_CVAR(rpc, reload_ammo) && actor.clip_load < WEP_CVAR(rpc, ammo)) { - thiswep.wr_reload(thiswep, actor, weaponentity); - } else - { - if (fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(rpc, refire))) - { - W_RocketPropelledChainsaw_Attack(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(rpc, animtime), w_ready); - } - } - - if (fire & 2) - { - // to-do - } - } - } - METHOD(RocketPropelledChainsaw, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(rpc, ammo); - ammo_amount += self.(weapon_load[WEP_RPC.m_id]) >= WEP_CVAR(rpc, ammo); - return ammo_amount; - } - METHOD(RocketPropelledChainsaw, wr_checkammo2, bool(entity thiswep)) - { - return false; - } - METHOD(RocketPropelledChainsaw, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, WEP_CVAR(rpc, ammo), SND(RELOAD)); - } - METHOD(RocketPropelledChainsaw, wr_suicidemessage, int(entity thiswep)) - { - if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH)) - return WEAPON_RPC_SUICIDE_SPLASH; - else - return WEAPON_RPC_SUICIDE_DIRECT; - } - METHOD(RocketPropelledChainsaw, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_BLASTER_MURDER; - else if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH)) - return WEAPON_RPC_MURDER_SPLASH; - else - return WEAPON_RPC_MURDER_DIRECT; - } +METHOD(RocketPropelledChainsaw, wr_aim, void(entity thiswep)) +{ + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(rpc, speed), 0, WEP_CVAR(rpc, lifetime), false); +} + +METHOD(RocketPropelledChainsaw, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(WEP_CVAR(rpc, reload_ammo) && actor.clip_load < WEP_CVAR(rpc, ammo)) { + thiswep.wr_reload(thiswep, actor, weaponentity); + } else + { + if (fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(rpc, refire))) + { + W_RocketPropelledChainsaw_Attack(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(rpc, animtime), w_ready); + } + } + + if (fire & 2) + { + // to-do + } + } +} + +METHOD(RocketPropelledChainsaw, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(rpc, ammo); + ammo_amount += self.(weapon_load[WEP_RPC.m_id]) >= WEP_CVAR(rpc, ammo); + return ammo_amount; +} + +METHOD(RocketPropelledChainsaw, wr_checkammo2, bool(entity thiswep)) +{ + return false; +} + +METHOD(RocketPropelledChainsaw, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, WEP_CVAR(rpc, ammo), SND(RELOAD)); +} + +METHOD(RocketPropelledChainsaw, wr_suicidemessage, Notification(entity thiswep)) +{ + if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH)) + return WEAPON_RPC_SUICIDE_SPLASH; + else + return WEAPON_RPC_SUICIDE_DIRECT; +} + +METHOD(RocketPropelledChainsaw, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_BLASTER_MURDER; + else if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH)) + return WEAPON_RPC_MURDER_SPLASH; + else + return WEAPON_RPC_MURDER_DIRECT; +} #endif #ifdef CSQC - METHOD(RocketPropelledChainsaw, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 12; - pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); - } +METHOD(RocketPropelledChainsaw, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 12; + pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); +} #endif #endif diff --git a/qcsrc/common/mutators/mutator/sandbox/sandbox.qc b/qcsrc/common/mutators/mutator/sandbox/sandbox.qc index 2dffb42f8..6391e1f87 100644 --- a/qcsrc/common/mutators/mutator/sandbox/sandbox.qc +++ b/qcsrc/common/mutators/mutator/sandbox/sandbox.qc @@ -213,7 +213,7 @@ entity sandbox_ObjectSpawn(float database) e.angles_y = self.v_angle.y; } - WITH(entity, self, e, CSQCMODEL_AUTOINIT(e)); + CSQCMODEL_AUTOINIT(e); object_count += 1; return e; diff --git a/qcsrc/common/mutators/mutator/spawn_near_teammate/spawn_near_teammate.qc b/qcsrc/common/mutators/mutator/spawn_near_teammate/spawn_near_teammate.qc index d94cb5397..23348f39d 100644 --- a/qcsrc/common/mutators/mutator/spawn_near_teammate/spawn_near_teammate.qc +++ b/qcsrc/common/mutators/mutator/spawn_near_teammate/spawn_near_teammate.qc @@ -28,10 +28,9 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, Spawn_Score) RandomSelection_Init(); FOREACH_CLIENT(IS_PLAYER(it) && it != self && SAME_TEAM(it, self) && !IS_DEAD(it), LAMBDA( - float l = vlen(spawn_spot.origin - it.origin); - if(l > autocvar_g_spawn_near_teammate_distance) + if(vdist(spawn_spot.origin - it.origin, >, autocvar_g_spawn_near_teammate_distance)) continue; - if(l < 48) + if(vdist(spawn_spot.origin - it.origin, <, 48)) continue; if(!checkpvs(spawn_spot.origin, it)) continue; @@ -52,6 +51,22 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, Spawn_Score) MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn) {SELFPARAM(); if(!teamplay) { return false; } + + int num_red = 0, num_blue = 0, num_yellow = 0, num_pink = 0; + FOREACH_CLIENT(IS_PLAYER(it), + { + switch(it.team) + { + case NUM_TEAM_1: ++num_red; break; + case NUM_TEAM_2: ++num_blue; break; + case NUM_TEAM_3: ++num_yellow; break; + case NUM_TEAM_4: ++num_pink; break; + } + }); + + if(num_red == 1 || num_blue == 1 || num_yellow == 1 || num_pink == 1) + return false; // at least 1 team has only 1 player, let's not give the bigger team too much of an advantage! + // Note: when entering this, fixangle is already set. if(autocvar_g_spawn_near_teammate_ignore_spawnpoint == 1 || (autocvar_g_spawn_near_teammate_ignore_spawnpoint == 2 && self.cvar_cl_spawn_near_teammate)) { @@ -70,7 +85,7 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn) if(STAT(FROZEN, it) == 0) if(it != self) { - tracebox(it.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - '0 0 100', MOVE_WORLDONLY, it); + tracebox(it.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - '0 0 100', MOVE_NOMONSTERS, it); if(trace_fraction != 1.0) if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) { @@ -82,30 +97,30 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn) else fixedmakevectors(it.angles); - for(pc = 0; pc < 5; ++pc) // test 5 diffrent spots close to mate + for(pc = 0; pc < 4; ++pc) // test 4 diffrent spots close to mate { switch(pc) { case 0: - tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin + v_right * 128, MOVE_NORMAL, it); + tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin + v_right * 128, MOVE_NOMONSTERS, it); break; case 1: - tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - v_right * 128 , MOVE_NORMAL, it); + tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - v_right * 128 , MOVE_NOMONSTERS, it); break; case 2: - tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin + v_right * 64 - v_forward * 64, MOVE_NORMAL, it); + tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin + v_right * 128 - v_forward * 64, MOVE_NOMONSTERS, it); break; case 3: - tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - v_right * 64 - v_forward * 64, MOVE_NORMAL, it); - break; - case 4: - tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - v_forward * 128, MOVE_NORMAL, it); + tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - v_right * 128 - v_forward * 64, MOVE_NOMONSTERS, it); break; + //case 4: + //tracebox(it.origin , STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - v_forward * 128, MOVE_NOMONSTERS, it); + //break; } if(trace_fraction == 1.0) { - traceline(trace_endpos + '0 0 4', trace_endpos - '0 0 100', MOVE_NORMAL, it); + traceline(trace_endpos + '0 0 4', trace_endpos - '0 0 100', MOVE_NOMONSTERS, it); if(trace_fraction != 1.0) { if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath) @@ -164,9 +179,6 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerDies) return 0; } -MUTATOR_HOOKFUNCTION(spawn_near_teammate, GetCvars) -{ - GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_spawn_near_teammate, "cl_spawn_near_teammate"); - return false; -} +REPLICATE(cvar_cl_spawn_near_teammate, bool, "cl_spawn_near_teammate"); + #endif diff --git a/qcsrc/common/mutators/mutator/waypoints/all.qh b/qcsrc/common/mutators/mutator/waypoints/all.qh index 17a103dd4..2b28784b7 100644 --- a/qcsrc/common/mutators/mutator/waypoints/all.qh +++ b/qcsrc/common/mutators/mutator/waypoints/all.qh @@ -42,7 +42,6 @@ REGISTER_RADARICON(NONE, 0); REGISTER_RADARICON(FLAG, 1); REGISTER_RADARICON(FLAGCARRIER, 1); -// TODO make these 3 and 4, and make images for them REGISTER_RADARICON(HERE, 1); REGISTER_RADARICON(DANGER, 1); diff --git a/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc b/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc index 1cb2766ab..1fb8fda3b 100644 --- a/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc +++ b/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc @@ -997,7 +997,6 @@ entity WaypointSprite_Spawn( ) { entity wp = new(sprite_waypoint); - make_pure(wp); wp.teleport_time = time + _lifetime; wp.fade_time = _lifetime; wp.exteriormodeltoclient = ref; diff --git a/qcsrc/common/net_notice.qc b/qcsrc/common/net_notice.qc index 59061e5a9..d67a1de3d 100644 --- a/qcsrc/common/net_notice.qc +++ b/qcsrc/common/net_notice.qc @@ -30,7 +30,7 @@ void sv_notice_to(entity _to, string _notice, float _howlong, float _modal) void sv_notice_toall(string _notice, float _howlong, float _modal) { - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA(sv_notice_to(it, _notice, _howlong, _modal))); + FOREACH_CLIENT(IS_REAL_CLIENT(it), sv_notice_to(it, _notice, _howlong, _modal)); } #endif // SVQC @@ -48,8 +48,7 @@ STATIC_INIT(cl_notice) } void cl_notice_read() { - entity _notice = new(sv_notice); - make_pure(_notice); + entity _notice = new_pure(sv_notice); _notice.netname = strzone(ReadString()); _notice.alpha = ReadLong() + time; _notice.skin = ReadByte(); @@ -59,7 +58,7 @@ void cl_notice_read() void cl_notice_run() { bool flag = false; - LL_EACH(cl_notices, it.alpha > time, LAMBDA(flag = true; break)); + LL_EACH(cl_notices, it.alpha > time, { flag = true; break; }); if (!flag) return; const int M1 = 30; const int M2 = 10; @@ -79,10 +78,10 @@ void cl_notice_run() #define OUT(s, z) MACRO_BEGIN { drawcolorcodedstring(v3, s, '1 1 0' * z, 1, DRAWFLAG_NORMAL); v3.y += z + 4; } MACRO_END OUT(_("^1Server notices:"), 32); - LL_EACH(cl_notices, it.alpha > time, LAMBDA( + 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); - )); + }); #undef OUT } diff --git a/qcsrc/common/notifications.inc b/qcsrc/common/notifications.inc deleted file mode 100644 index 545b8783b..000000000 --- a/qcsrc/common/notifications.inc +++ /dev/null @@ -1,852 +0,0 @@ -// ==================================== -// Notifications List and Information -// ==================================== -/* - List of all notifications (including identifiers and display information) - Possible Tokens: - default, name, strnum, flnum, - channel, sound, volume, position, - args, hudargs, icon, cpid, durcnt, normal, gentle, - anncename, infoname, centername, - challow, chtype, optiona, optionb - Format Specifications: - MSG_ANNCE: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = enabled if gentle is disabled, 2 = always enabled - name: VAR: Name of notification - channel: FLOAT: Sound channel to broadcast on to - sound: STRING: Filename for the announcement sound - volume: FLOAT: Volume setting for the announcement sound - position: FLOAT: Attenuation/positioning value - MSG_INFO: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = enabled, 2 = also print to chat box - name: VAR: Name of notification - strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive) - flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive) - args: STRING: Arguments for Local_Notification_sprintf() - hudargs: STRING: Arguments for Local_Notification_HUD_Notify_Push() - icon: STRING: icon string name for the hud notify panel, "" if no icon is used - normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled) - gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled) - MSG_CENTER: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = enabled - name: VAR: Name of notification - strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive) - flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive) - args: STRING: Arguments for Local_Notification_sprintf() - cpid: FLOAT: centerprint ID number (CPID_*), NO_CPID if no CPID is needed - durcnt: XPD(FLOAT, FLOAT): Duration/Countdown: extra arguments for centerprint messages - normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled) - gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled) - MSG_MULTI: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = enabled - name: VAR: Name of chaining notification - anncename: VAR: Name of announcer notification for reference - infoname: VAR: Name of info notification for reference - centername: VAR: Name of centerprint notification for reference - MSG_CHOICE: - default: FLOAT: Default setting for whether the notification is enabled or not - ^-> 0 = disabled, 1 = select option A, 2 = selection option B - challow: FLOAT: Default setting for server allowing choices other than A - ^-> 0 = no choice, 1 = allowed in warmup, 2 = always allowed - name: VAR: Name of choice notification - chtype: VAR: Notification message type for options - optiona: VAR: Name of choice "A" notification for reference - optionb: VAR: Name of choice "B" notification for reference - - Messages with ^F1, ^BG, ^TC, etc etc in them will replace those strings - with colors according to the cvars the user has chosen. This allows for - users to create unique color profiles for their HUD, giving more customization - options to HUD designers and end users who want such a feature. - - Check out the definitions in util.qc/util.qh/teams.qh for string CCR(...) and - string TCR(...) to better understand how these code replacements work. - - Additionally, you can find all the definitions and explanations for - the argument values and what they return down below in this file. - - Guidlines for notification declaration (please try and follow these): - Specific rules: - -ALWAYS start the string with a color, preferably background. - -ALWAYS reset a color after a name (this way they don't set it for the whole string). - -NEVER re-declare an event twice. - -NEVER add or remove tokens from the format, it SHOULD already work. - -MSG_INFO hudargs must always be ATTACKER -> VICTIM - -MSG_INFO and MSG_CENTER should NOT end with a new line - - General rules: - -Be clean and simple with your notification naming, - nothing too long for the name field... Abbreviations are your friend. :D - -Keep the spacing as clean as possible... if the arguments are abnormally long, - it's okay to go out of line a bit... but try and keep it clean still. - - Use ONLY spaces for spacing in the notification list, tabs are too inconsistent - with keeping alignment on different mediums. - -Sort the notifications in the most appropriate order for their tasks. - -ARIRE unir frk jvgu lbhe bja zbgure. (gvc sbe zvxrrhfn) -- Don't pay attention to this ^_^ - - Final note: DO NOT PROVIDE MORE ARGUMENTS THAN NECESSARY FOR THE NOTIFICATION YOU'RE CALLING! - The system is designed to save as much networking bandwidth as possible, - so please dynamically control your argument sending to fit *exactly* what is required. - If you send a notification with mismatching arguments, Send_Notification() will error. -*/ - -#define MULTITEAM_ANNCE2(default,prefix,channel,sound,volume,position) \ - MSG_ANNCE_NOTIF(default, prefix##RED, channel, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), volume, position) \ - MSG_ANNCE_NOTIF(default, prefix##BLUE, channel, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), volume, position) -#define MULTITEAM_ANNCE3(default,prefix,channel,sound,volume,position) \ - MSG_ANNCE_NOTIF(default, prefix##RED, channel, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), volume, position) \ - MSG_ANNCE_NOTIF(default, prefix##BLUE, channel, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), volume, position) \ - MSG_ANNCE_NOTIF(default, prefix##YELLOW, channel, sprintf(sound, strtolower(STATIC_NAME_TEAM_3)), volume, position) -#define MULTITEAM_ANNCE4(default,prefix,channel,sound,volume,position) \ - MSG_ANNCE_NOTIF(default, prefix##RED, channel, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), volume, position) \ - MSG_ANNCE_NOTIF(default, prefix##BLUE, channel, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), volume, position) \ - MSG_ANNCE_NOTIF(default, prefix##YELLOW, channel, sprintf(sound, strtolower(STATIC_NAME_TEAM_3)), volume, position) \ - MSG_ANNCE_NOTIF(default, prefix##PINK, channel, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), volume, position) -#define MULTITEAM_ANNCE(default,prefix,teams,channel,sound,volume,position) \ - MULTITEAM_ANNCE##teams(default,prefix,channel,sound,volume,position) - -// MSG_ANNCE_NOTIFICATIONS - MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_AIRSHOT, CH_INFO, "airshot", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_AMAZING, CH_INFO, "amazing", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_AWESOME, CH_INFO, "awesome", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_BOTLIKE, CH_INFO, "botlike", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_ACHIEVEMENT_ELECTROBITCH, CH_INFO, "electrobitch", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_IMPRESSIVE, CH_INFO, "impressive", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_YODA, CH_INFO, "yoda", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_BEGIN, CH_INFO, "begin", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_03, CH_INFO, "03kills", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_05, CH_INFO, "05kills", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_10, CH_INFO, "10kills", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_15, CH_INFO, "15kills", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_20, CH_INFO, "20kills", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_25, CH_INFO, "25kills", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_30, CH_INFO, "30kills", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_INSTAGIB_LASTSECOND, CH_INFO, "lastsecond", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_INSTAGIB_NARROWLY, CH_INFO, "narrowly", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_INSTAGIB_TERMINATED, CH_INFO, "terminated", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_MULTIFRAG, CH_INFO, "multifrag", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_1, CH_INFO, "1", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_2, CH_INFO, "2", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_3, CH_INFO, "3", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_4, CH_INFO, "4", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_5, CH_INFO, "5", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_6, CH_INFO, "6", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_7, CH_INFO, "7", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_8, CH_INFO, "8", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_9, CH_INFO, "9", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_10, CH_INFO, "10", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_GAMESTART_1, CH_INFO, "1", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_GAMESTART_2, CH_INFO, "2", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_GAMESTART_3, CH_INFO, "3", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_GAMESTART_4, CH_INFO, "4", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_GAMESTART_5, CH_INFO, "5", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_GAMESTART_6, CH_INFO, "6", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_GAMESTART_7, CH_INFO, "7", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_GAMESTART_8, CH_INFO, "8", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_GAMESTART_9, CH_INFO, "9", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_GAMESTART_10, CH_INFO, "10", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_1, CH_INFO, "1", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_2, CH_INFO, "2", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_3, CH_INFO, "3", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_4, CH_INFO, "4", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_5, CH_INFO, "5", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_6, CH_INFO, "6", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_7, CH_INFO, "7", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_8, CH_INFO, "8", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_9, CH_INFO, "9", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_IDLE_10, CH_INFO, "10", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_1, CH_INFO, "1", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_2, CH_INFO, "2", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_3, CH_INFO, "3", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_4, CH_INFO, "4", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_5, CH_INFO, "5", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_6, CH_INFO, "6", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_7, CH_INFO, "7", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_8, CH_INFO, "8", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_9, CH_INFO, "9", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_KILL_10, CH_INFO, "10", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_1, CH_INFO, "1", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_2, CH_INFO, "2", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_3, CH_INFO, "3", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_4, CH_INFO, "4", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_5, CH_INFO, "5", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_6, CH_INFO, "6", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_7, CH_INFO, "7", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_8, CH_INFO, "8", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_9, CH_INFO, "9", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_RESPAWN_10, CH_INFO, "10", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_ROUNDSTART_1, CH_INFO, "1", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_ROUNDSTART_2, CH_INFO, "2", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_NUM_ROUNDSTART_3, CH_INFO, "3", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_ROUNDSTART_4, CH_INFO, "4", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_ROUNDSTART_5, CH_INFO, "5", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_ROUNDSTART_6, CH_INFO, "6", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_ROUNDSTART_7, CH_INFO, "7", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_ROUNDSTART_8, CH_INFO, "8", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_ROUNDSTART_9, CH_INFO, "9", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(0, ANNCE_NUM_ROUNDSTART_10, CH_INFO, "10", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_PREPARE, CH_INFO, "prepareforbattle", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_REMAINING_FRAG_1, CH_INFO, "1fragleft", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_REMAINING_FRAG_2, CH_INFO, "2fragsleft", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(1, ANNCE_REMAINING_FRAG_3, CH_INFO, "3fragsleft", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_REMAINING_MIN_1, CH_INFO, "1minuteremains", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_REMAINING_MIN_5, CH_INFO, "5minutesremain", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_TIMEOUT, CH_INFO, "timeoutcalled", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_VOTE_ACCEPT, CH_INFO, "voteaccept", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_VOTE_CALL, CH_INFO, "votecall", VOL_BASEVOICE, ATTEN_NONE) - MSG_ANNCE_NOTIF(2, ANNCE_VOTE_FAIL, CH_INFO, "votefail", VOL_BASEVOICE, ATTEN_NONE) - -#define MULTITEAM_INFO2(default,prefix,strnum,flnum,args,hudargs,icon,normal,gentle) \ - MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ - MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) -#define MULTITEAM_INFO3(default,prefix,strnum,flnum,args,hudargs,icon,normal,gentle) \ - MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ - MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \ - MSG_INFO_NOTIF(default, prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) -#define MULTITEAM_INFO4(default,prefix,strnum,flnum,args,hudargs,icon,normal,gentle) \ - MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ - MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \ - MSG_INFO_NOTIF(default, prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) \ - MSG_INFO_NOTIF(default, prefix##PINK, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) -#define MULTITEAM_INFO(default,prefix,teams,strnum,flnum,args,hudargs,icon,normal,gentle) \ - MULTITEAM_INFO##teams(default,prefix,strnum,flnum,args,hudargs,icon,normal,gentle) - -// MSG_INFO_NOTIFICATIONS - MSG_INFO_NOTIF(1, INFO_CONNECTING, 1, 0, "s1", "", "", _("^BG%s^BG is connecting..."), "") - MSG_INFO_NOTIF(2, INFO_CHAT_NOSPECTATORS, 0, 0, "", "", "", _("^F4NOTE: ^BGSpectator chat is not sent to players during the match"), "") - MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 4, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag"), "") - MULTITEAM_INFO(1, INFO_CTF_CAPTURE_BROKEN_, 4, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds"), "") - MSG_INFO_NOTIF(1, INFO_CTF_CAPTURE_NEUTRAL, 1, 0, "s1", "s1", "notify_neutral_captured", _("^BG%s^BG captured the flag"), "") - MULTITEAM_INFO(1, INFO_CTF_CAPTURE_TIME_, 4, 1, 1, "s1 f1p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "") - MULTITEAM_INFO(1, INFO_CTF_CAPTURE_UNBROKEN_, 4, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds"), "") - MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "") - MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL,0, 0, "", "", "", _("^BGThe flag was returned by its owner"), "") - MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "") - MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL, 0, 0, "", "", "", _("^BGThe flag was destroyed and returned to base"), "") - MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"), "") - MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL, 0, 0, "", "", "", _("^BGThe flag was dropped in the base and returned itself"), "") - MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_NEEDKILL_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "") - MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL,0, 0, "", "", "", _("^BGThe flag fell somewhere it couldn't be reached and returned to base"), "") - MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_SPEEDRUN_, 4, 0, 1, "f1p2dec", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") - MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL,0, 1, "f1p2dec", "", "", _("^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") - MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag has returned to the base"), "") - MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL, 0, 0, "", "", "", _("^BGThe flag has returned to the base"), "") - MULTITEAM_INFO(1, INFO_CTF_LOST_, 4, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag"), "") - MSG_INFO_NOTIF(1, INFO_CTF_LOST_NEUTRAL, 1, 0, "s1", "s1", "notify_neutral_lost", _("^BG%s^BG lost the flag"), "") - MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 4, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag"), "") - MSG_INFO_NOTIF(1, INFO_CTF_PICKUP_NEUTRAL, 1, 0, "s1", "s1", "notify_neutral_taken", _("^BG%s^BG got the flag"), "") - MULTITEAM_INFO(1, INFO_CTF_RETURN_, 4, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") - MULTITEAM_INFO(1, INFO_CTF_RETURN_MONSTER_, 4, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") - MSG_INFO_NOTIF(2, INFO_COINTOSS, 1, 0, "s1", "", "", _("^F2Throwing coin... Result: %s^F2!"), "") - MSG_INFO_NOTIF(1, INFO_JETPACK_NOFUEL, 0, 0, "", "", "", _("^BGYou don't have any fuel for the ^F1Jetpack"), "") - MSG_INFO_NOTIF(2, INFO_SUPERSPEC_MISSING_UID, 0, 0, "", "", "", _("^F2You lack a UID, superspec options will not be saved/restored"), "") - MSG_INFO_NOTIF(1, INFO_CA_JOIN_LATE, 0, 0, "", "", "", _("^F1Round already started, you will join the game in the next round"), "") - MSG_INFO_NOTIF(1, INFO_CA_LEAVE, 0, 0, "", "", "", _("^F2You will spectate in the next round"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_BUFF, 3, 3, "spree_inf s1 s2 f3buffname s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"), _("^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_CHEAT, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_DROWN, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_water", _("^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FALL, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_fall", _("^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FIRE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"), _("^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_LAVA, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_lava", _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_MONSTER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was pushed infront of a monster by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_normal", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_NAPALM, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_napalm", _("^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"), _("^BG%s%s^K1 got too close to a napalm explosion%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE_FREEZE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_HEAL, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_heal", _("^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SHOOTING_STAR, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_shootingstar", _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SLIME, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SWAMP, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TELEFRAG, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_telefrag", _("^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s"), _("^BG%s%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_TOUCHEXPLODE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_DEATH, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_BUMB_GUN, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_CRUSH, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was crushed by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_BOMB, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_CANNON, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_RAPT_DEATH, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_DEATH, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_MINIGUN, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_SPID_ROCKET, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_DEATH, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_GUN, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_ROCKET, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VOID, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_void", _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_AUTOTEAMCHANGE, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 was moved into the %s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_BETRAYAL, 2, 1, "s1 s2loc spree_lost", "s1", "notify_teamkill_red", _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CAMP, 2, 1, "s1 s2loc spree_lost", "s1", "notify_camping", _("^BG%s^K1 thought they found a nice camping ground%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CHEAT, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 unfairly eliminated themself%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_CUSTOM, 3, 1, "s1 s2 s3loc spree_lost", "s1", "notify_void", "^BG%s^K1 %s^K1%s%s", "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_DROWN, 2, 1, "s1 s2loc spree_lost", "s1", "notify_water", _("^BG%s^K1 couldn't catch their breath%s%s"), _("^BG%s^K1 was in the water for too long%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FALL, 2, 1, "s1 s2loc spree_lost", "s1", "notify_fall", _("^BG%s^K1 hit the ground with a crunch%s%s"), _("^BG%s^K1 hit the ground with a bit too much force%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FIRE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 became a bit too crispy%s%s"), _("^BG%s^K1 felt a little hot%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_GENERIC, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 died%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_LAVA, 2, 1, "s1 s2loc spree_lost", "s1", "notify_lava", _("^BG%s^K1 turned into hot slag%s%s"), _("^BG%s^K1 found a hot place%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_MAGE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was exploded by a Mage%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_CLAW, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1's innards became outwards by a Shambler%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_SMASH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was smashed by a Shambler%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_ZAP, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was zapped to death by a Shambler%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SPIDER, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was bitten by a Spider%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_WYVERN, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was fireballed by a Wyvern%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 joins the Zombies%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE, 2, 1, "s1 s2loc spree_lost", "s1", "nade_normal", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_NAPALM, 2, 1, "s1 s2loc spree_lost", "s1", "nade_napalm", _("^BG%s^K1 was burned to death by their own Napalm Nade%s%s"), _("^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE_FREEZE, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 was frozen to death by their own Ice Nade%s%s"), _("^BG%s^K1 felt a little chilly%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_HEAL, 2, 1, "s1 s2loc spree_lost", "s1", "nade_heal", _("^BG%s^K1's Healing Nade didn't quite heal them%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NOAMMO, 2, 1, "s1 s2loc spree_lost", "s1", "notify_outofammo", _("^BG%s^K1 died%s%s. What's the point of living without ammo?"), _("^BG%s^K1 ran out of ammo%s%s")) - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_ROT, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 rotted away%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SHOOTING_STAR, 2, 1, "s1 s2loc spree_lost", "s1", "notify_shootingstar", _("^BG%s^K1 became a shooting star%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SLIME, 2, 1, "s1 s2loc spree_lost", "s1", "notify_slime", _("^BG%s^K1 was slimed%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 couldn't take it anymore%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SWAMP, 2, 1, "s1 s2loc spree_lost", "s1", "notify_slime", _("^BG%s^K1 is now preserved for centuries to come%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TEAMCHANGE, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 switched to the %s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TOUCHEXPLODE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 died in an accident%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 ran into a turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_EWHEEL, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by an eWheel turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_FLAC, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught up in the FLAC turret fire%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HELLION, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by a Hellion turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_HK, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 could not hide from the Hunter turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MACHINEGUN, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_MLRS, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PHASER, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was phased out by a turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_PLASMA, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served some superheated plasma from a turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_TESLA, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was electrocuted by a Tesla turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_GUN, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served a lead enrichment by a Walker turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_MELEE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was impaled by a Walker turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_TURRET_WALK_ROCKET, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by a Walker turret%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_BUMB_DEATH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_CRUSH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was crushed by a vehicle%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_RAPT_BOMB, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was caught in a Raptor cluster bomb%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_RAPT_DEATH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Raptor explosion%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_SPID_DEATH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_SPID_ROCKET, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_DEATH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Racer explosion%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_ROCKET, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VOID, 3, 1, "s1 s2 s2loc spree_lost", "s1", "notify_void", "^BG%s^K1 %s^K1%s%s", "") - MULTITEAM_INFO(1, INFO_DEATH_TEAMKILL_, 4, 3, 1, "s1 s2 s3loc spree_end", "s2 s1", "notify_teamkill_%s", _("^BG%s^K1 was betrayed by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_DOMINATION_CAPTURE_TIME, 2, 2, "s1 s2 f1 f1points f2", "", "", _("^BG%s^BG%s^BG (%s %s every %s seconds)"), "") - MSG_INFO_NOTIF(1, INFO_FREEZETAG_FREEZE, 2, 0, "s1 s2", "", "", _("^BG%s^K1 was frozen by ^BG%s"), "") - MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED, 2, 0, "s1 s2", "", "", _("^BG%s^K3 was revived by ^BG%s"), "") - MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED_FALL, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by falling"), "") - MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED_NADE, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by their Nade explosion"), "") - MSG_INFO_NOTIF(1, INFO_FREEZETAG_AUTO_REVIVED, 1, 1, "s1 f1", "", "", _("^BG%s^K3 was automatically revived after %s second(s)"), "") - MULTITEAM_INFO(1, INFO_ROUND_TEAM_WIN_, 4, 0, 0, "", "", "", _("^TC^TT^BG team wins the round"), "") - MSG_INFO_NOTIF(1, INFO_ROUND_PLAYER_WIN, 1, 0, "s1", "", "", _("^BG%s^BG wins the round"), "") - MSG_INFO_NOTIF(1, INFO_ROUND_TIED, 0, 0, "", "", "", _("^BGRound tied"), "") - MSG_INFO_NOTIF(1, INFO_ROUND_OVER, 0, 0, "", "", "", _("^BGRound over, there's no winner"), "") - MSG_INFO_NOTIF(1, INFO_FREEZETAG_SELF, 1, 0, "s1", "", "", _("^BG%s^K1 froze themself"), "") - MSG_INFO_NOTIF(1, INFO_GODMODE_OFF, 0, 1, "f1", "", "", _("^BGGodmode saved you %s units of damage, cheater!"), "") - MSG_INFO_NOTIF(1, INFO_ITEM_BUFF, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG got the %s^BG buff!"), "") - MSG_INFO_NOTIF(1, INFO_ITEM_BUFF_LOST, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG lost the %s^BG buff!"), "") - MSG_INFO_NOTIF(1, INFO_ITEM_BUFF_DROP, 0, 1, "item_buffname", "", "", _("^BGYou dropped the %s^BG buff!"), "") - MSG_INFO_NOTIF(1, INFO_ITEM_BUFF_GOT, 0, 1, "item_buffname", "", "", _("^BGYou got the %s^BG buff!"), "") - MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DONTHAVE, 0, 1, "item_wepname", "", "", _("^BGYou do not have the ^F1%s"), "") - MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DROP, 1, 1, "item_wepname item_wepammo", "", "", _("^BGYou dropped the ^F1%s^BG%s"), "") - MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_GOT, 0, 1, "item_wepname", "", "", _("^BGYou got the ^F1%s"), "") - MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_NOAMMO, 0, 1, "item_wepname", "", "", _("^BGYou don't have enough ammo for the ^F1%s"), "") - MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_PRIMORSEC, 0, 3, "item_wepname f2primsec f3primsec", "", "", _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") - MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_UNAVAILABLE, 0, 1, "item_wepname", "", "", _("^F1%s^BG is ^F4not available^BG on this map"), "") - MSG_INFO_NOTIF(2, INFO_JOIN_CONNECT, 1, 0, "s1", "", "", _("^BG%s^F3 connected"), "") - MULTITEAM_INFO(2, INFO_JOIN_CONNECT_TEAM_, 4, 1, 0, "s1", "", "", _("^BG%s^F3 connected and joined the ^TC^TT team"), "") - MSG_INFO_NOTIF(1, INFO_JOIN_PLAY, 1, 0, "s1", "", "", _("^BG%s^F3 is now playing"), "") - MULTITEAM_INFO(2, INFO_JOIN_PLAY_TEAM_, 4, 1, 0, "s1", "", "", _("^BG%s^F3 is now playing on the ^TC^TT team"), "") - MSG_INFO_NOTIF(1, INFO_KEEPAWAY_DROPPED, 1, 0, "s1", "s1", "notify_balldropped", _("^BG%s^BG has dropped the ball!"), "") - MSG_INFO_NOTIF(1, INFO_KEEPAWAY_PICKUP, 1, 0, "s1", "s1", "notify_ballpickedup", _("^BG%s^BG has picked up the ball!"), "") - MULTITEAM_INFO(1, INFO_KEYHUNT_CAPTURE_, 4, 1, 0, "s1", "", "", _("^BG%s^BG captured the keys for the ^TC^TT team"), "") - MULTITEAM_INFO(1, INFO_KEYHUNT_DROP_, 4, 1, 0, "s1", "", "", _("^BG%s^BG dropped the ^TC^TT Key"), "") - MULTITEAM_INFO(1, INFO_KEYHUNT_LOST_, 4, 1, 0, "s1", "", "", _("^BG%s^BG lost the ^TC^TT Key"), "") - MULTITEAM_INFO(1, INFO_KEYHUNT_PICKUP_, 4, 1, 0, "s1", "", "", _("^BG%s^BG picked up the ^TC^TT Key"), "") - MSG_INFO_NOTIF(1, INFO_LMS_FORFEIT, 1, 0, "s1", "", "", _("^BG%s^F3 forfeited"), "") - MSG_INFO_NOTIF(1, INFO_LMS_NOLIVES, 1, 0, "s1", "", "", _("^BG%s^F3 has no more lives left"), "") - MSG_INFO_NOTIF(1, INFO_MONSTERS_DISABLED, 0, 0, "", "", "", _("^BGMonsters are currently disabled"), "") - MSG_INFO_NOTIF(1, INFO_ONSLAUGHT_CAPTURE, 2, 0, "s1 s2", "", "", _("^BG%s^BG captured %s^BG control point"), "") - MULTITEAM_INFO(1, INFO_ONSLAUGHT_CPDESTROYED_, 4, 2, 0, "s1 s2", "", "", _("^TC^TT^BG team %s^BG control point has been destroyed by %s"), "") - MULTITEAM_INFO(1, INFO_ONSLAUGHT_GENDESTROYED_, 4, 0, 0, "", "", "", _("^TC^TT^BG generator has been destroyed"), "") - MULTITEAM_INFO(1, INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_, 4, 0, 0, "", "", "", _("^TC^TT^BG generator spontaneously combusted due to overtime!"), "") - MSG_INFO_NOTIF(1, INFO_POWERUP_INVISIBILITY, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Invisibility"), "") - MSG_INFO_NOTIF(1, INFO_POWERUP_SHIELD, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Shield"), "") - MSG_INFO_NOTIF(1, INFO_POWERUP_SPEED, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Speed"), "") - MSG_INFO_NOTIF(1, INFO_POWERUP_STRENGTH, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Strength"), "") - MSG_INFO_NOTIF(2, INFO_QUIT_DISCONNECT, 1, 0, "s1", "", "", _("^BG%s^F3 disconnected"), "") - MSG_INFO_NOTIF(2, INFO_QUIT_KICK_IDLING, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked for idling"), "") - MSG_INFO_NOTIF(1, INFO_QUIT_KICK_SPECTATING, 0, 0, "", "", "", _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "") - MSG_INFO_NOTIF(1, INFO_QUIT_SPECTATE, 1, 0, "s1", "", "", _("^BG%s^F3 is now spectating"), "") - MSG_INFO_NOTIF(1, INFO_RACE_ABANDONED, 1, 0, "s1", "", "", _("^BG%s^BG has abandoned the race"), "") - MSG_INFO_NOTIF(1, INFO_RACE_FAIL_RANKED, 1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1 f3race_time", "race_newfail", _("^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s"), "") - MSG_INFO_NOTIF(1, INFO_RACE_FAIL_UNRANKED, 1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1 f3race_time", "race_newfail", _("^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s"), "") - MSG_INFO_NOTIF(1, INFO_RACE_FINISHED, 1, 0, "s1", "", "", _("^BG%s^BG has finished the race"), "") - MSG_INFO_NOTIF(1, INFO_RACE_NEW_BROKEN, 2, 3, "s1 s2 race_col f1ord race_col f2race_time race_diff", "s1 f2race_time", "race_newrankyellow", _("^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s"), "") - MSG_INFO_NOTIF(1, INFO_RACE_NEW_IMPROVED, 1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1 f2race_time", "race_newtime", _("^BG%s^BG improved their %s%s^BG place record with %s%s %s"), "") - MSG_INFO_NOTIF(1, INFO_RACE_NEW_MISSING_UID, 1, 1, "s1 f1race_time", "s1 f1race_time", "race_newfail", _("^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID and will be lost."), "") - MSG_INFO_NOTIF(1, INFO_RACE_NEW_SET, 1, 2, "s1 race_col f1ord race_col f2race_time", "s1 f2race_time", "race_newrecordserver", _("^BG%s^BG set the %s%s^BG place record with %s%s"), "") - MULTIICON_INFO(1, INFO_MINIGAME_INVITE, 2, 0, "s2 minigame1_name s1","s2", "minigame1_d", "minigames/%s/icon_notif",_("^F4You have been invited by ^BG%s^F4 to join their game of ^F2%s^F4 (^F1%s^F4)"), "") - MULTITEAM_INFO(1, INFO_SCORES_, 4, 0, 0, "", "", "", _("^TC^TT ^BGteam scores!"), "") - MSG_INFO_NOTIF(1, INFO_SPECTATE_WARNING, 0, 1, "f1secs", "", "", _("^F2You have to become a player within the next %s, otherwise you will be kicked, because spectating isn't allowed at this time!"), "") - MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP, 1, 0, "s1", "s1", "superweapons", _("^BG%s^K1 picked up a Superweapon"), "") - MSG_INFO_NOTIF(1, INFO_TEAMCHANGE_LARGERTEAM, 0, 0, "", "", "", _("^BGYou cannot change to a larger team"), "") - MSG_INFO_NOTIF(1, INFO_TEAMCHANGE_NOTALLOWED, 0, 0, "", "", "", _("^BGYou are not allowed to change teams"), "") - MSG_INFO_NOTIF(2, INFO_VERSION_BETA, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s"), "") - MSG_INFO_NOTIF(2, INFO_VERSION_OLD, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"), "") - MSG_INFO_NOTIF(2, INFO_VERSION_OUTDATED, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!"), "") - MSG_INFO_NOTIF(1, INFO_WATERMARK, 1, 0, "s1", "", "", _("^F3SVQC Build information: ^F4%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_ACCORDEON_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_ARC_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponarc", _("^BG%s%s^K1 was electrocuted by ^BG%s^K1's Arc%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_ARC_MURDER_SPRAY, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponarc", _("^BG%s%s^K1 was blasted by ^BG%s^K1's Arc bolts%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_BLASTER_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponlaser", _("^BG%s%s^K1 was shot to death by ^BG%s^K1's Blaster%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_BLASTER_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weaponlaser", _("^BG%s^K1 shot themself to hell with their Blaster%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponcrylink", _("^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_CRYLINK_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weaponcrylink", _("^BG%s^K1 felt the strong pull of their Crylink%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_DEVASTATOR_MURDER_DIRECT, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrocketlauncher", _("^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_DEVASTATOR_MURDER_SPLASH, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrocketlauncher", _("^BG%s%s^K1 got too close ^BG%s^K1's rocket%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_DEVASTATOR_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrocketlauncher", _("^BG%s^K1 blew themself up with their Devastator%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_BOLT, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_COMBO, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_MURDER_ORBS, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 got too close to ^BG%s^K1's Electro orb%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_BOLT, 2, 1, "s1 s2loc spree_lost", "s1", "weaponelectro", _("^BG%s^K1 played with Electro bolts%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_ELECTRO_SUICIDE_ORBS, 2, 1, "s1 s2loc spree_lost", "s1", "weaponelectro", _("^BG%s^K1 could not remember where they put their Electro orb%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_BLAST, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponfireball", _("^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_MURDER_FIREMINE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponfireball", _("^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_BLAST, 2, 1, "s1 s2loc spree_lost", "s1", "weaponfireball", _("^BG%s^K1 should have used a smaller gun%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE, 2, 1, "s1 s2loc spree_lost", "s1", "weaponfireball", _("^BG%s^K1 forgot about their firemine%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_BURST, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhagar", _("^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_MURDER_SPRAY, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhagar", _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_HAGAR_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weaponhagar", _("^BG%s^K1 played with tiny Hagar rockets%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhlac", _("^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_HLAC_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weaponhlac", _("^BG%s^K1 got a little jumpy with their HLAC%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_HMG_MURDER_SNIPE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhmg", _("^BG%s%s^K1 was sniped by ^BG%s^K1's Heavy Machine Gun%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_HMG_MURDER_SPRAY, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhmg", _("^BG%s%s^K1 was torn to bits by ^BG%s^K1's Heavy Machine Gun%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_HOOK_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhook", _("^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_KLEINBOTTLE_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_MACHINEGUN_MURDER_SNIPE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponuzi", _("^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_MACHINEGUN_MURDER_SPRAY, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponuzi", _("^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_LIMIT, 0, 1, "f1", "", "", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponminelayer", _("^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_MINELAYER_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weaponminelayer", _("^BG%s^K1 forgot about their mine%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_BOUNCE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapongrenadelauncher", _("^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_MURDER_EXPLODE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapongrenadelauncher", _("^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_BOUNCE, 2, 1, "s1 s2loc spree_lost", "s1", "weapongrenadelauncher", _("^BG%s^K1 didn't see their own Mortar grenade%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_MORTAR_SUICIDE_EXPLODE, 2, 1, "s1 s2loc spree_lost", "s1", "weapongrenadelauncher", _("^BG%s^K1 blew themself up with their own Mortar%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_PIERCING, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_RPC_MURDER_DIRECT, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrpc", _("^BG%s%s^K1 was sawn in half by ^BG%s^K1's Rocket Propelled Chainsaw%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_RPC_MURDER_SPLASH, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrpc", _("^BG%s%s^K1 almost dodged ^BG%s^K1's Rocket Propelled Chainsaw%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_RPC_SUICIDE_DIRECT, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrpc", _("^BG%s^K1 was sawn in half by their own Rocket Propelled Chainsaw%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_RPC_SUICIDE_SPLASH, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrpc", _("^BG%s^K1 blew themself up with their Rocket Propelled Chainsaw%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_SPRAY, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponseeker", _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_MURDER_TAG, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponseeker", _("^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_SEEKER_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weaponseeker", _("^BG%s^K1 played with tiny Seeker rockets%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_SHOCKWAVE_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponshotgun", _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_SHOCKWAVE_MURDER_SLAP, 3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1", "notify_melee_shotgun", _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shockwave%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponshotgun", _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_SHOTGUN_MURDER_SLAP, 3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1", "notify_melee_shotgun", _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_THINKING_WITH_PORTALS, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 is now thinking with portals%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_TUBA_SUICIDE, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_VAPORIZER_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponminstanex", _("^BG%s%s^K1 has been sublimated by ^BG%s^K1's Vaporizer%s%s"), "") - MSG_INFO_NOTIF(1, INFO_WEAPON_VORTEX_MURDER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponnex", _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Vortex%s%s"), "") - -#define MULTITEAM_CENTER2(default,prefix,strnum,flnum,args,cpid,durcnt,normal,gentle) \ - MSG_CENTER_NOTIF(default, prefix##RED, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ - MSG_CENTER_NOTIF(default, prefix##BLUE, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) -#define MULTITEAM_CENTER3(default,prefix,strnum,flnum,args,cpid,durcnt,normal,gentle) \ - MSG_CENTER_NOTIF(default, prefix##RED, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ - MSG_CENTER_NOTIF(default, prefix##BLUE, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \ - MSG_CENTER_NOTIF(default, prefix##YELLOW, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) -#define MULTITEAM_CENTER4(default,prefix,strnum,flnum,args,cpid,durcnt,normal,gentle) \ - MSG_CENTER_NOTIF(default, prefix##RED, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ - MSG_CENTER_NOTIF(default, prefix##BLUE, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \ - MSG_CENTER_NOTIF(default, prefix##YELLOW, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) \ - MSG_CENTER_NOTIF(default, prefix##PINK, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) -#define MULTITEAM_CENTER(default,prefix,teams,strnum,flnum,args,cpid,durcnt,normal,gentle) \ - MULTITEAM_CENTER##teams(default,prefix,strnum,flnum,args,cpid,durcnt,normal,gentle) - -// MSG_CENTER_NOTIFICATIONS - MSG_CENTER_NOTIF(1, CENTER_ALONE, 0, 0, "", NO_CPID, "0 0", _("^F4You are now alone!"), "") - MSG_CENTER_NOTIF(1, CENTER_ASSAULT_ATTACKING, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are attacking!"), "") - MSG_CENTER_NOTIF(1, CENTER_ASSAULT_DEFENDING, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are defending!"), "") - MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_BEGIN, 0, 0, "", CPID_ROUND, "2 0", _("^F4Begin!"), "") - MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_GAMESTART, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Game starts in ^COUNT"), "") - MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_ROUNDSTART, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Round starts in ^COUNT"), "") - MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_ROUNDSTOP, 0, 0, "", CPID_ROUND, "2 0", _("^F4Round cannot start"), "") - MSG_CENTER_NOTIF(1, CENTER_ROUND_TIED, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound tied"), "") - MSG_CENTER_NOTIF(1, CENTER_ROUND_OVER, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound over, there's no winner"), "") - MSG_CENTER_NOTIF(1, CENTER_CAMPCHECK, 0, 0, "", CPID_CAMPCHECK, "0 0", _("^F2Don't camp!"), "") - MSG_CENTER_NOTIF(1, CENTER_COINTOSS, 1, 0, "s1", NO_CPID, "0 0", _("^F2Throwing coin... Result: %s^F2!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_FREE, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_INACTIVE, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGThis flag is currently inactive"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_SHIELDED, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now ^F1shielded^BG from the flag(s)\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") - MULTITEAM_CENTER(1, CENTER_CTF_CAPTURE_, 4, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURE_NEUTRAL, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the flag!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_FLAG_THROW_PUNISH, 0, 1, "f1secs", CPID_CTF_LOWPRIO, "0 0", _("^BGToo many flag throws! Throwing disabled for %s."), "") - MULTITEAM_CENTER(1, CENTER_CTF_PASS_OTHER_, 4, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_OTHER_NEUTRAL, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the flag to %s"), "") - MULTITEAM_CENTER(1, CENTER_CTF_PASS_RECEIVED_, 4, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the ^TC^TT^BG flag from %s"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_RECEIVED_NEUTRAL, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the flag from %s"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTED, 1, 0, "s1 pass_key", CPID_CTF_PASS, "0 0", _("^BG%s^BG requests you to pass the flag%s"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTING, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGRequesting %s^BG to pass you the flag"), "") - MULTITEAM_CENTER(1, CENTER_CTF_PASS_SENT_, 4, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the ^TC^TT^BG flag to %s"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_SENT_NEUTRAL, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the flag to %s"), "") - MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_, 4, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_NEUTRAL, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the flag!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got your %steam^BG's flag, return it!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_ENEMY, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the %senemy^BG's flag, return it!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_VERBOSE, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_NEUTRAL, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got the flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE, 2, 0, "s1 s2 s1",CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_TEAM, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got their flag! Retrieve it!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE,2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"), "") - MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_TEAM_, 4, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"), "") - MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_TEAM_VERBOSE_, 4, 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!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_NEUTRAL, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the flag! Protect them!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") - MULTITEAM_CENTER(1, CENTER_CTF_RETURN_, 4, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou returned the ^TC^TT^BG flag!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_CARRIER, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Enemies can now see you on radar!"), "") - MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_OTHER, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG, 1, 1, "spree_cen s1", NO_CPID, "0 0", _("^K3%sYou fragged ^BG%s"), _("^K3%sYou scored against ^BG%s")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAGGED, 1, 1, "spree_cen s1", NO_CPID, "0 0", _("^K1%sYou were fragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAGGED_VERBOSE, 1, 4, "spree_cen s1 frag_stats", NO_CPID, "0 0", _("^K1%sYou were fragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^BG%s")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG_VERBOSE, 1, 2, "spree_cen s1 frag_ping", NO_CPID, "0 0", _("^K3%sYou fragged ^BG%s^BG%s"), _("^K3%sYou scored against ^BG%s^BG%s")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG, 1, 1, "spree_cen s1", NO_CPID, "0 0", _("^K1%sYou typefragged ^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED, 1, 1, "spree_cen s1", NO_CPID, "0 0", _("^K1%sYou were typefragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE, 1, 4, "spree_cen s1 frag_stats", NO_CPID, "0 0", _("^K1%sYou were typefragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing^BG%s")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE, 1, 2, "spree_cen s1 frag_ping", NO_CPID, "0 0", _("^K1%sYou typefragged ^BG%s^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing^BG%s")) - MSG_CENTER_NOTIF(1, CENTER_NADE_THROW, 0, 0, "", CPID_NADES, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the nade!"), "") - MSG_CENTER_NOTIF(1, CENTER_NADE_BONUS, 0, 0, "", CPID_NADES, "0 0", _("^F2You got a ^K1BONUS GRENADE^F2!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_AUTOTEAMCHANGE, 0, 1, "death_team", NO_CPID, "0 0", _("^BGYou have been moved into a different team\nYou are now on: %s"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_BETRAYAL, 0, 0, "", NO_CPID, "0 0", _("^K1Don't shoot your team mates!"), _("^K1Don't go against your team mates!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CAMP, 0, 0, "", NO_CPID, "0 0", _("^K1Die camper!"), _("^K1Reconsider your tactics, camper!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CHEAT, 0, 0, "", NO_CPID, "0 0", _("^K1You unfairly eliminated yourself!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CUSTOM, 2, 0, "s2", NO_CPID, "0 0", _("^K1You were %s"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_DROWN, 0, 0, "", NO_CPID, "0 0", _("^K1You couldn't catch your breath!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_FALL, 0, 0, "", NO_CPID, "0 0", _("^K1You hit the ground with a crunch!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_FIRE, 0, 0, "", NO_CPID, "0 0", _("^K1You got a little bit too crispy!"), _("^K1You felt a little too hot!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_GENERIC, 0, 0, "", NO_CPID, "0 0", _("^K1You killed your own dumb self!"), _("^K1You need to be more careful!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_LAVA, 0, 0, "", NO_CPID, "0 0", _("^K1You couldn't stand the heat!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_MONSTER, 0, 0, "", NO_CPID, "0 0", _("^K1You were killed by a monster!"), _("^K1You need to watch out for monsters!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE, 0, 0, "", NO_CPID, "0 0", _("^K1You forgot to put the pin back in!"), _("^K1Tastes like chicken!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE_NAPALM, 0, 0, "", NO_CPID, "0 0", _("^K1Hanging around a napalm explosion is bad!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE_ICE_FREEZE, 0, 0, "", NO_CPID, "0 0", _("^K1You got a little bit too cold!"), _("^K1You felt a little chilly!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE_HEAL, 0, 0, "", NO_CPID, "0 0", _("^K1Your Healing Nade is a bit defective"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NOAMMO, 0, 0, "", NO_CPID, "0 0", _("^K1You were killed for running out of ammo..."), _("^K1You are respawning for running out of ammo...")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_ROT, 0, 0, "", NO_CPID, "0 0", _("^K1You grew too old without taking your medicine"), _("^K1You need to preserve your health")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SHOOTING_STAR, 0, 0, "", NO_CPID, "0 0", _("^K1You became a shooting star!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SLIME, 0, 0, "", NO_CPID, "0 0", _("^K1You melted away in slime!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SUICIDE, 0, 0, "", NO_CPID, "0 0", _("^K1You committed suicide!"), _("^K1You ended it all!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SWAMP, 0, 0, "", NO_CPID, "0 0", _("^K1You got stuck in a swamp!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TEAMCHANGE, 0, 1, "death_team", NO_CPID, "0 0", _("^BGYou are now on: %s"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TOUCHEXPLODE, 0, 0, "", NO_CPID, "0 0", _("^K1You died in an accident!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TURRET, 0, 0, "", NO_CPID, "0 0", _("^K1You were fragged by a turret!"), _("^K1You had an unfortunate run in with a turret!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TURRET_EWHEEL, 0, 0, "", NO_CPID, "0 0", _("^K1You were fragged by an eWheel turret!"), _("^K1You had an unfortunate run in with an eWheel turret!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_TURRET_WALK, 0, 0, "", NO_CPID, "0 0", _("^K1You were fragged by a Walker turret!"), _("^K1You had an unfortunate run in with a Walker turret!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_BUMB_DEATH, 0, 0, "", NO_CPID, "0 0", _("^K1You got caught in the blast of a Bumblebee explosion!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_CRUSH, 0, 0, "", NO_CPID, "0 0", _("^K1You were crushed by a vehicle!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_RAPT_BOMB, 0, 0, "", NO_CPID, "0 0", _("^K1You were caught in a Raptor cluster bomb!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_RAPT_DEATH, 0, 0, "", NO_CPID, "0 0", _("^K1You got caught in the blast of a Raptor explosion!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_SPID_DEATH, 0, 0, "", NO_CPID, "0 0", _("^K1You got caught in the blast of a Spiderbot explosion!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_SPID_ROCKET, 0, 0, "", NO_CPID, "0 0", _("^K1You were blasted to bits by a Spiderbot rocket!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_WAKI_DEATH, 0, 0, "", NO_CPID, "0 0", _("^K1You got caught in the blast of a Racer explosion!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VH_WAKI_ROCKET, 0, 0, "", NO_CPID, "0 0", _("^K1You couldn't find shelter from a Racer rocket!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_VOID, 0, 0, "", NO_CPID, "0 0", _("^K1Watch your step!"), "") - MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAG, 1, 0, "s1", NO_CPID, "0 0", _("^K1Moron! You fragged ^BG%s^K1, a team mate!"), _("^K1Moron! You went against ^BG%s^K1, a team mate!")) - MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAGGED, 1, 0, "s1", NO_CPID, "0 0", _("^K1You were fragged by ^BG%s^K1, a team mate"), _("^K1You were scored against by ^BG%s^K1, a team mate")) - MSG_CENTER_NOTIF(1, CENTER_DISCONNECT_IDLING, 0, 1, "", CPID_IDLING, "1 f1", _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") - MSG_CENTER_NOTIF(1, CENTER_DOOR_LOCKED_NEED, 1, 0, "s1", NO_CPID, "0 0", _("^BGYou need %s^BG!"), "") - MSG_CENTER_NOTIF(1, CENTER_DOOR_LOCKED_ALSONEED, 1, 0, "s1", NO_CPID, "0 0", _("^BGYou also need %s^BG!"), "") - MSG_CENTER_NOTIF(1, CENTER_DOOR_UNLOCKED, 0, 0, "", NO_CPID, "0 0", _("^BGDoor unlocked!"), "") - MSG_CENTER_NOTIF(1, CENTER_EXTRALIVES, 0, 0, "", NO_CPID, "0 0", _("^F2You picked up some extra lives"), "") - MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FREEZE, 1, 0, "s1", NO_CPID, "0 0", _("^K3You froze ^BG%s"), "") - MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FROZEN, 1, 0, "s1", NO_CPID, "0 0", _("^K1You were frozen by ^BG%s"), "") - MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE, 1, 0, "s1", NO_CPID, "0 0", _("^K3You revived ^BG%s"), "") - MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE_SELF, 0, 0, "", NO_CPID, "0 0", _("^K3You revived yourself"), "") - MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVED, 1, 0, "s1", NO_CPID, "0 0", _("^K3You were revived by ^BG%s"), "") - MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_AUTO_REVIVED, 0, 1, "f1", NO_CPID, "0 0", _("^K3You were automatically revived after %s second(s)"), "") - MSG_CENTER_NOTIF(1, CENTER_GENERATOR_UNDERATTACK, 0, 0, "", NO_CPID, "0 0", _("^BGThe generator is under attack!"), "") - MULTITEAM_CENTER(1, CENTER_ROUND_TEAM_WIN_, 4, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team wins the round"), "") - MSG_CENTER_NOTIF(1, CENTER_ROUND_PLAYER_WIN, 1, 0, "s1", CPID_ROUND, "0 0", _("^BG%s^BG wins the round"), "") - MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SELF, 0, 0, "", NO_CPID, "0 0", _("^K1You froze yourself"), "") - MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SPAWN_LATE, 0, 0, "", NO_CPID, "0 0", _("^K1Round already started, you spawn as frozen"), "") - MSG_CENTER_NOTIF(1, CENTER_INVASION_SUPERMONSTER, 1, 0, "s1", NO_CPID, "0 0", _("^K1A %s has arrived!"), "") - MSG_CENTER_NOTIF(1, CENTER_ITEM_BUFF_DROP, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou dropped the %s^BG buff!"), "") - MSG_CENTER_NOTIF(1, CENTER_ITEM_BUFF_GOT, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou got the %s^BG buff!"), "") - MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DONTHAVE, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou do not have the ^F1%s"), "") - MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DROP, 1, 1, "item_wepname item_wepammo", CPID_ITEM, "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "") - MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_GOT, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1%s"), "") - MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_NOAMMO, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou don't have enough ammo for the ^F1%s"), "") - MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_PRIMORSEC, 0, 3, "item_wepname f2primsec f3primsec", CPID_ITEM, "item_centime 0", _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") - MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_UNAVAILABLE, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^F1%s^BG is ^F4not available^BG on this map"), "") - MSG_CENTER_NOTIF(1, CENTER_JOIN_NOSPAWNS, 0, 0, "", CPID_PREVENT_JOIN, "0 0", _("^K1No spawnpoints available!\nHope your team can fix it..."), "") - MSG_CENTER_NOTIF(1, CENTER_JOIN_PREVENT, 0, 0, "", CPID_PREVENT_JOIN, "0 0", _("^K1You may not join the game at this time.\nThe player limit reached maximum capacity."), "") - MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_DROPPED, 1, 0, "s1", CPID_KEEPAWAY, "0 0", _("^BG%s^BG has dropped the ball!"), "") - MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_PICKUP, 1, 0, "s1", CPID_KEEPAWAY, "0 0", _("^BG%s^BG has picked up the ball!"), "") - MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_PICKUP_SELF, 0, 0, "", CPID_KEEPAWAY, "0 0", _("^BGYou picked up the ball"), "") - MSG_CENTER_NOTIF(1, CENTER_KEEPAWAY_WARN, 0, 0, "", CPID_KEEPAWAY_WARN, "0 0", _("^BGKilling people while you don't have the ball gives no points!"), "") - MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_HELP, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in your team's hands!\nHelp the key carriers to meet!"), "") - MULTITEAM_CENTER(1, CENTER_KEYHUNT_INTERFERE_, 4, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in ^TC^TT team^BG's hands!\nInterfere ^F4NOW^BG!"), "") - MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_MEET, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in your team's hands!\nMeet the other key carriers ^F4NOW^BG!"), "") - MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_ROUNDSTART, 0, 1, "", CPID_KEYHUNT_OTHER, "1 f1", _("^F4Round will start in ^COUNT"), "") - MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_SCAN, 0, 1, "", CPID_KEYHUNT_OTHER, "f1 0", _("^BGScanning frequency range..."), "") - MULTITEAM_CENTER(1, CENTER_KEYHUNT_START_, 4, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGYou are starting with the ^TC^TT Key"), "") - MSG_CENTER_NOTIF(1, CENTER_LMS_NOLIVES, 0, 0, "", CPID_LMS, "0 0", _("^BGYou have no lives left, you must wait until the next match"), "") - MSG_CENTER_NOTIF(1, CENTER_MISSING_TEAMS, 0, 1, "missing_teams", CPID_MISSING_TEAMS, "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") - MSG_CENTER_NOTIF(1, CENTER_MISSING_PLAYERS, 0, 1, "f1", CPID_MISSING_PLAYERS, "-1 0", _("^BGWaiting for %s player(s) to join..."), "") - MSG_CENTER_NOTIF(1, CENTER_INSTAGIB_DOWNGRADE, 0, 0, "", CPID_INSTAGIB_FINDAMMO,"5 0", _("^BGYour weapon has been downgraded until you find some ammo!"), "") - MSG_CENTER_NOTIF(1, CENTER_INSTAGIB_FINDAMMO, 0, 0, "", CPID_INSTAGIB_FINDAMMO,"1 9", _("^F4^COUNT^BG left to find some ammo!"), "") - MSG_CENTER_NOTIF(1, CENTER_INSTAGIB_FINDAMMO_FIRST, 0, 0, "", CPID_INSTAGIB_FINDAMMO,"1 10", _("^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"), _("^BGGet some ammo! ^F4^COUNT^BG left!")) - MSG_CENTER_NOTIF(1, CENTER_INSTAGIB_LIVES_REMAINING, 0, 1, "f1", NO_CPID, "0 0", _("^F2Extra lives remaining: ^K1%s"), "") - MSG_CENTER_NOTIF(1, CENTER_MOTD, 1, 0, "s1", CPID_MOTD, "-1 0", "^BG%s", "") - MSG_CENTER_NOTIF(1, CENTER_NIX_COUNTDOWN, 0, 2, "item_wepname", CPID_NIX, "1 f2", _("^F2^COUNT^BG until weapon change...\nNext weapon: ^F1%s"), "") - MSG_CENTER_NOTIF(1, CENTER_NIX_NEWWEAPON, 0, 1, "item_wepname", CPID_NIX, "0 0", _("^F2Active weapon: ^F1%s"), "") - MSG_CENTER_NOTIF(1, CENTER_NADE, 0, 0, "", NO_CPID, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the grenade!"), "") - MSG_CENTER_NOTIF(1, CENTER_ONS_CAPTURE, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^BGYou captured %s^BG control point"), "") - MULTITEAM_CENTER(1, CENTER_ONS_CAPTURE_, 4, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^TC^TT^BG team captured %s^BG control point"), "") - MSG_CENTER_NOTIF(1, CENTER_ONS_CONTROLPOINT_SHIELDED, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThis control point currently cannot be captured"), "") - MSG_CENTER_NOTIF(1, CENTER_ONS_GENERATOR_SHIELDED, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThe enemy generator cannot be destroyed yet\n^F2Capture some control points to unshield it"), "") - MULTITEAM_CENTER(1, CENTER_ONS_NOTSHIELDED_, 4, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^BGThe ^TCenemy^BG generator is no longer shielded!"), "") - MSG_CENTER_NOTIF(1, CENTER_ONS_NOTSHIELDED_TEAM, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^K1Your generator is NOT shielded!\n^BGRe-capture control points to shield it!"), "") - MSG_CENTER_NOTIF(1, CENTER_ONS_TELEPORT, 0, 0, "pass_key", CPID_ONSLAUGHT, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to teleport"), "") - MSG_CENTER_NOTIF(1, CENTER_ONS_TELEPORT_ANTISPAM, 0, 1, "f1secs", CPID_ONSLAUGHT, "0 0", _("^BGTeleporting disabled for %s"), "") - MSG_CENTER_NOTIF(1, CENTER_OVERTIME_FRAG, 0, 0, "", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\nKeep fragging until we have a winner!"), _("^F2Now playing ^F4OVERTIME^F2!\nKeep scoring until we have a winner!")) - MSG_CENTER_NOTIF(1, CENTER_OVERTIME_CONTROLPOINT, 0, 0, "", CPID_OVERTIME, "5 0", _("^F2Now playing ^F4OVERTIME^F2!\n\nGenerators are now decaying.\nThe more control points your team holds,\nthe faster the enemy generator decays"), "") - MSG_CENTER_NOTIF(1, CENTER_OVERTIME_TIME, 0, 1, "f1time", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\n^BGAdded ^F4%s^BG to the game!"), "") - MSG_CENTER_NOTIF(1, CENTER_PORTO_CREATED_IN, 0, 0, "", NO_CPID, "0 0", _("^K1In^BG-portal created"), "") - MSG_CENTER_NOTIF(1, CENTER_PORTO_CREATED_OUT, 0, 0, "", NO_CPID, "0 0", _("^F3Out^BG-portal created"), "") - MSG_CENTER_NOTIF(1, CENTER_PORTO_FAILED, 0, 0, "", NO_CPID, "0 0", _("^F1Portal creation failed"), "") - MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_INVISIBILITY, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Invisibility has worn off"), "") - MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SHIELD, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Shield has worn off"), "") - MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SPEED, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Speed has worn off"), "") - MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_STRENGTH, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Strength has worn off"), "") - MSG_CENTER_NOTIF(1, CENTER_POWERUP_INVISIBILITY, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You are invisible"), "") - MSG_CENTER_NOTIF(1, CENTER_POWERUP_SHIELD, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Shield surrounds you"), "") - MSG_CENTER_NOTIF(1, CENTER_POWERUP_SPEED, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You are on speed"), "") - MSG_CENTER_NOTIF(1, CENTER_POWERUP_STRENGTH, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Strength infuses your weapons with devastating power"), "") - MSG_CENTER_NOTIF(1, CENTER_RACE_FINISHLAP, 0, 0, "", CPID_RACE_FINISHLAP, "0 0", _("^F2The race is over, finish your lap!"), "") - MSG_CENTER_NOTIF(1, CENTER_SECONDARY_NODAMAGE, 0, 0, "", NO_CPID, "0 0", _("^BGSecondary fire inflicts no damage!"), "") - MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COMPLETED, 0, 0, "", NO_CPID, "0 0", _("^BGSequence completed!"), "") - MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COUNTER, 0, 0, "", NO_CPID, "0 0", _("^BGThere are more to go..."), "") - MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COUNTER_FEWMORE, 0, 1, "f1", NO_CPID, "0 0", _("^BGOnly %s^BG more to go..."), "") - MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_BROKEN, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have broken down"), "") - MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_LOST, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have been lost"), "") - MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_PICKUP, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You now have a superweapon"), "") - MULTITEAM_CENTER(1, CENTER_TEAMCHANGE_, 4, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Changing to ^TC^TT^K1 in ^COUNT"), "") - MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_AUTO, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Changing team in ^COUNT"), "") - MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SPECTATE, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Spectating in ^COUNT"), "") - MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SUICIDE, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Suicide in ^COUNT"), "") - MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_BEGINNING, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout begins in ^COUNT"), "") - MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_ENDING, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout ends in ^COUNT"), "") - MSG_CENTER_NOTIF(1, CENTER_JOIN_PREVENT_MINIGAME, 0, 0, "", NO_CPID, "0 0", _("^K1Cannot join given minigame session!"), "" ) - MSG_CENTER_NOTIF(1, CENTER_VEHICLE_ENTER, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter/exit the vehicle"), "") - MSG_CENTER_NOTIF(1, CENTER_VEHICLE_ENTER_GUNNER, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter the vehicle gunner"), "") - MSG_CENTER_NOTIF(1, CENTER_VEHICLE_ENTER_STEAL, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to steal this vehicle"), "") - MSG_CENTER_NOTIF(1, CENTER_VEHICLE_STEAL, 0, 0, "", CPID_VEHICLES_OTHER, "0 0", _("^F2The enemy is stealing one of your vehicles!\n^F4Stop them!"), "") - MSG_CENTER_NOTIF(1, CENTER_VEHICLE_STEAL_SELF, 0, 0, "", CPID_VEHICLES_OTHER, "4 0", _("^F2You have stolen the enemy's vehicle, you are now visible on their radar!"), "") - MSG_CENTER_NOTIF(1, CENTER_WEAPON_MINELAYER_LIMIT, 0, 1, "f1", NO_CPID, "0 0", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "") - -#define MULTITEAM_MULTI2(default,prefix,anncepre,infopre,centerpre) \ - MSG_MULTI_NOTIF(default, prefix##RED, anncepre##RED, infopre##RED, centerpre##RED) \ - MSG_MULTI_NOTIF(default, prefix##BLUE, anncepre##BLUE, infopre##BLUE, centerpre##BLUE) -#define MULTITEAM_MULTI3(default,prefix,anncepre,infopre,centerpre) \ - MSG_MULTI_NOTIF(default, prefix##RED, anncepre##RED, infopre##RED, centerpre##RED) \ - MSG_MULTI_NOTIF(default, prefix##BLUE, anncepre##BLUE, infopre##BLUE, centerpre##BLUE) \ - MSG_MULTI_NOTIF(default, prefix##YELLOW, anncepre##YELLOW, infopre##YELLOW, centerpre##YELLOW) -#define MULTITEAM_MULTI4(default,prefix,anncepre,infopre,centerpre) \ - MSG_MULTI_NOTIF(default, prefix##RED, anncepre##RED, infopre##RED, centerpre##RED) \ - MSG_MULTI_NOTIF(default, prefix##BLUE, anncepre##BLUE, infopre##BLUE, centerpre##BLUE) \ - MSG_MULTI_NOTIF(default, prefix##YELLOW, anncepre##YELLOW, infopre##YELLOW, centerpre##YELLOW) \ - MSG_MULTI_NOTIF(default, prefix##PINK, anncepre##PINK, infopre##PINK, centerpre##PINK) -#define MULTITEAM_MULTI(default,prefix,teams,anncepre,infopre,centerpre) \ - MULTITEAM_MULTI##teams(default,prefix,anncepre,infopre,centerpre) - -// MSG_MULTI_NOTIFICATIONS - MSG_MULTI_NOTIF(1, DEATH_MURDER_BUFF, NO_MSG, INFO_DEATH_MURDER_BUFF, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_CHEAT, NO_MSG, INFO_DEATH_MURDER_CHEAT, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_DROWN, NO_MSG, INFO_DEATH_MURDER_DROWN, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_FALL, NO_MSG, INFO_DEATH_MURDER_FALL, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_FIRE, NO_MSG, INFO_DEATH_MURDER_FIRE, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_LAVA, NO_MSG, INFO_DEATH_MURDER_LAVA, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_MONSTER, NO_MSG, INFO_DEATH_MURDER_MONSTER, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE, NO_MSG, INFO_DEATH_MURDER_NADE, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_NAPALM, NO_MSG, INFO_DEATH_MURDER_NADE_NAPALM, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_ICE, NO_MSG, INFO_DEATH_MURDER_NADE_ICE, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_ICE_FREEZE, NO_MSG, INFO_DEATH_MURDER_NADE_ICE_FREEZE, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_HEAL, NO_MSG, INFO_DEATH_MURDER_NADE_HEAL, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_SHOOTING_STAR, NO_MSG, INFO_DEATH_MURDER_SHOOTING_STAR, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_SLIME, NO_MSG, INFO_DEATH_MURDER_SLIME, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_SWAMP, NO_MSG, INFO_DEATH_MURDER_SWAMP, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_TELEFRAG, NO_MSG, INFO_DEATH_MURDER_TELEFRAG, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_TOUCHEXPLODE, NO_MSG, INFO_DEATH_MURDER_TOUCHEXPLODE, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_BUMB_DEATH, NO_MSG, INFO_DEATH_MURDER_VH_BUMB_DEATH, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_BUMB_GUN, NO_MSG, INFO_DEATH_MURDER_VH_BUMB_GUN, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_CRUSH, NO_MSG, INFO_DEATH_MURDER_VH_CRUSH, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_BOMB, NO_MSG, INFO_DEATH_MURDER_VH_RAPT_BOMB, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_CANNON, NO_MSG, INFO_DEATH_MURDER_VH_RAPT_CANNON, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_DEATH, NO_MSG, INFO_DEATH_MURDER_VH_RAPT_DEATH, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_DEATH, NO_MSG, INFO_DEATH_MURDER_VH_SPID_DEATH, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_MINIGUN, NO_MSG, INFO_DEATH_MURDER_VH_SPID_MINIGUN, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_ROCKET, NO_MSG, INFO_DEATH_MURDER_VH_SPID_ROCKET, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_DEATH, NO_MSG, INFO_DEATH_MURDER_VH_WAKI_DEATH, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_GUN, NO_MSG, INFO_DEATH_MURDER_VH_WAKI_GUN, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_ROCKET, NO_MSG, INFO_DEATH_MURDER_VH_WAKI_ROCKET, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_MURDER_VOID, NO_MSG, INFO_DEATH_MURDER_VOID, NO_MSG) - MSG_MULTI_NOTIF(1, DEATH_SELF_AUTOTEAMCHANGE, NO_MSG, INFO_DEATH_SELF_AUTOTEAMCHANGE, CENTER_DEATH_SELF_AUTOTEAMCHANGE) - MSG_MULTI_NOTIF(1, DEATH_SELF_BETRAYAL, NO_MSG, INFO_DEATH_SELF_BETRAYAL, CENTER_DEATH_SELF_BETRAYAL) - MSG_MULTI_NOTIF(1, DEATH_SELF_CAMP, NO_MSG, INFO_DEATH_SELF_CAMP, CENTER_DEATH_SELF_CAMP) - MSG_MULTI_NOTIF(1, DEATH_SELF_CHEAT, NO_MSG, INFO_DEATH_SELF_CHEAT, CENTER_DEATH_SELF_CHEAT) - MSG_MULTI_NOTIF(1, DEATH_SELF_CUSTOM, NO_MSG, INFO_DEATH_SELF_GENERIC, CENTER_DEATH_SELF_CUSTOM) - MSG_MULTI_NOTIF(1, DEATH_SELF_DROWN, NO_MSG, INFO_DEATH_SELF_DROWN, CENTER_DEATH_SELF_DROWN) - MSG_MULTI_NOTIF(1, DEATH_SELF_FALL, NO_MSG, INFO_DEATH_SELF_FALL, CENTER_DEATH_SELF_FALL) - MSG_MULTI_NOTIF(1, DEATH_SELF_FIRE, NO_MSG, INFO_DEATH_SELF_FIRE, CENTER_DEATH_SELF_FIRE) - MSG_MULTI_NOTIF(1, DEATH_SELF_GENERIC, NO_MSG, INFO_DEATH_SELF_GENERIC, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, DEATH_SELF_LAVA, NO_MSG, INFO_DEATH_SELF_LAVA, CENTER_DEATH_SELF_LAVA) - MSG_MULTI_NOTIF(1, DEATH_SELF_MON_MAGE, NO_MSG, INFO_DEATH_SELF_MON_MAGE, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(1, DEATH_SELF_MON_SHAMBLER_CLAW, NO_MSG, INFO_DEATH_SELF_MON_SHAMBLER_CLAW, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(1, DEATH_SELF_MON_SHAMBLER_SMASH, NO_MSG, INFO_DEATH_SELF_MON_SHAMBLER_SMASH, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(1, DEATH_SELF_MON_SHAMBLER_ZAP, NO_MSG, INFO_DEATH_SELF_MON_SHAMBLER_ZAP, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(1, DEATH_SELF_MON_SPIDER, NO_MSG, INFO_DEATH_SELF_MON_SPIDER, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(1, DEATH_SELF_MON_WYVERN, NO_MSG, INFO_DEATH_SELF_MON_WYVERN, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(1, DEATH_SELF_MON_ZOMBIE_JUMP, NO_MSG, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(1, DEATH_SELF_MON_ZOMBIE_MELEE, NO_MSG, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, CENTER_DEATH_SELF_MONSTER) - MSG_MULTI_NOTIF(1, DEATH_SELF_NADE, NO_MSG, INFO_DEATH_SELF_NADE, CENTER_DEATH_SELF_NADE) - MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_NAPALM, NO_MSG, INFO_DEATH_SELF_NADE_NAPALM, CENTER_DEATH_SELF_NADE_NAPALM) - MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_ICE, NO_MSG, INFO_DEATH_SELF_NADE_ICE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) - MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_ICE_FREEZE, NO_MSG, INFO_DEATH_SELF_NADE_ICE_FREEZE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) - MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_HEAL, NO_MSG, INFO_DEATH_SELF_NADE_HEAL, CENTER_DEATH_SELF_NADE_HEAL) - MSG_MULTI_NOTIF(1, DEATH_SELF_NOAMMO, NO_MSG, INFO_DEATH_SELF_NOAMMO, CENTER_DEATH_SELF_NOAMMO) - MSG_MULTI_NOTIF(1, DEATH_SELF_ROT, NO_MSG, INFO_DEATH_SELF_ROT, CENTER_DEATH_SELF_ROT) - MSG_MULTI_NOTIF(1, DEATH_SELF_SHOOTING_STAR, NO_MSG, INFO_DEATH_SELF_SHOOTING_STAR, CENTER_DEATH_SELF_SHOOTING_STAR) - MSG_MULTI_NOTIF(1, DEATH_SELF_SLIME, NO_MSG, INFO_DEATH_SELF_SLIME, CENTER_DEATH_SELF_SLIME) - MSG_MULTI_NOTIF(1, DEATH_SELF_SUICIDE, NO_MSG, INFO_DEATH_SELF_SUICIDE, CENTER_DEATH_SELF_SUICIDE) - MSG_MULTI_NOTIF(1, DEATH_SELF_SWAMP, NO_MSG, INFO_DEATH_SELF_SWAMP, CENTER_DEATH_SELF_SWAMP) - MSG_MULTI_NOTIF(1, DEATH_SELF_TEAMCHANGE, NO_MSG, INFO_DEATH_SELF_TEAMCHANGE, CENTER_DEATH_SELF_TEAMCHANGE) - MSG_MULTI_NOTIF(1, DEATH_SELF_TOUCHEXPLODE, NO_MSG, INFO_DEATH_SELF_TOUCHEXPLODE, CENTER_DEATH_SELF_TOUCHEXPLODE) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET, NO_MSG, INFO_DEATH_SELF_TURRET, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_EWHEEL, NO_MSG, INFO_DEATH_SELF_TURRET_EWHEEL, CENTER_DEATH_SELF_TURRET_EWHEEL) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_FLAC, NO_MSG, INFO_DEATH_SELF_TURRET_FLAC, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_HELLION, NO_MSG, INFO_DEATH_SELF_TURRET_HELLION, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_HK, NO_MSG, INFO_DEATH_SELF_TURRET_HK, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_MACHINEGUN, NO_MSG, INFO_DEATH_SELF_TURRET_MACHINEGUN, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_MLRS, NO_MSG, INFO_DEATH_SELF_TURRET_MLRS, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_PHASER, NO_MSG, INFO_DEATH_SELF_TURRET_PHASER, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_PLASMA, NO_MSG, INFO_DEATH_SELF_TURRET_PLASMA, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_TESLA, NO_MSG, INFO_DEATH_SELF_TURRET_TESLA, CENTER_DEATH_SELF_TURRET) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_GUN, NO_MSG, INFO_DEATH_SELF_TURRET_WALK_GUN, CENTER_DEATH_SELF_TURRET_WALK) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_MELEE, NO_MSG, INFO_DEATH_SELF_TURRET_WALK_MELEE, CENTER_DEATH_SELF_TURRET_WALK) - MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_ROCKET, NO_MSG, INFO_DEATH_SELF_TURRET_WALK_ROCKET, CENTER_DEATH_SELF_TURRET_WALK) - MSG_MULTI_NOTIF(1, DEATH_SELF_VH_BUMB_DEATH, NO_MSG, INFO_DEATH_SELF_VH_BUMB_DEATH, CENTER_DEATH_SELF_VH_BUMB_DEATH) - MSG_MULTI_NOTIF(1, DEATH_SELF_VH_CRUSH, NO_MSG, INFO_DEATH_SELF_VH_CRUSH, CENTER_DEATH_SELF_VH_CRUSH) - MSG_MULTI_NOTIF(1, DEATH_SELF_VH_RAPT_BOMB, NO_MSG, INFO_DEATH_SELF_VH_RAPT_BOMB, CENTER_DEATH_SELF_VH_RAPT_BOMB) - MSG_MULTI_NOTIF(1, DEATH_SELF_VH_RAPT_DEATH, NO_MSG, INFO_DEATH_SELF_VH_RAPT_DEATH, CENTER_DEATH_SELF_VH_RAPT_DEATH) - MSG_MULTI_NOTIF(1, DEATH_SELF_VH_SPID_DEATH, NO_MSG, INFO_DEATH_SELF_VH_SPID_DEATH, CENTER_DEATH_SELF_VH_SPID_DEATH) - MSG_MULTI_NOTIF(1, DEATH_SELF_VH_SPID_ROCKET, NO_MSG, INFO_DEATH_SELF_VH_SPID_ROCKET, CENTER_DEATH_SELF_VH_SPID_ROCKET) - MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_DEATH, NO_MSG, INFO_DEATH_SELF_VH_WAKI_DEATH, CENTER_DEATH_SELF_VH_WAKI_DEATH) - MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_ROCKET, NO_MSG, INFO_DEATH_SELF_VH_WAKI_ROCKET, CENTER_DEATH_SELF_VH_WAKI_ROCKET) - MSG_MULTI_NOTIF(1, DEATH_SELF_VOID, NO_MSG, INFO_DEATH_SELF_VOID, CENTER_DEATH_SELF_VOID) - MSG_MULTI_NOTIF(1, ITEM_BUFF_DROP, NO_MSG, INFO_ITEM_BUFF_DROP, CENTER_ITEM_BUFF_DROP) - MSG_MULTI_NOTIF(1, ITEM_BUFF_GOT, NO_MSG, INFO_ITEM_BUFF_GOT, CENTER_ITEM_BUFF_GOT) - MSG_MULTI_NOTIF(1, ITEM_WEAPON_DONTHAVE, NO_MSG, INFO_ITEM_WEAPON_DONTHAVE, CENTER_ITEM_WEAPON_DONTHAVE) - MSG_MULTI_NOTIF(1, ITEM_WEAPON_DROP, NO_MSG, INFO_ITEM_WEAPON_DROP, CENTER_ITEM_WEAPON_DROP) - MSG_MULTI_NOTIF(1, ITEM_WEAPON_GOT, NO_MSG, INFO_ITEM_WEAPON_GOT, CENTER_ITEM_WEAPON_GOT) - MSG_MULTI_NOTIF(1, ITEM_WEAPON_NOAMMO, NO_MSG, INFO_ITEM_WEAPON_NOAMMO, CENTER_ITEM_WEAPON_NOAMMO) - MSG_MULTI_NOTIF(1, ITEM_WEAPON_PRIMORSEC, NO_MSG, INFO_ITEM_WEAPON_PRIMORSEC, CENTER_ITEM_WEAPON_PRIMORSEC) - MSG_MULTI_NOTIF(1, ITEM_WEAPON_UNAVAILABLE, NO_MSG, INFO_ITEM_WEAPON_UNAVAILABLE, CENTER_ITEM_WEAPON_UNAVAILABLE) - MSG_MULTI_NOTIF(1, MULTI_COINTOSS, NO_MSG, INFO_COINTOSS, CENTER_COINTOSS) - MSG_MULTI_NOTIF(1, MULTI_COUNTDOWN_BEGIN, ANNCE_BEGIN, NO_MSG, CENTER_COUNTDOWN_BEGIN) - MSG_MULTI_NOTIF(1, MULTI_INSTAGIB_FINDAMMO, ANNCE_NUM_10, NO_MSG, CENTER_INSTAGIB_FINDAMMO_FIRST) - MSG_MULTI_NOTIF(1, WEAPON_ACCORDEON_MURDER, NO_MSG, INFO_WEAPON_ACCORDEON_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_ACCORDEON_SUICIDE, NO_MSG, INFO_WEAPON_ACCORDEON_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_ARC_MURDER, NO_MSG, INFO_WEAPON_ARC_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_ARC_MURDER_SPRAY, NO_MSG, INFO_WEAPON_ARC_MURDER_SPRAY, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_BLASTER_MURDER, NO_MSG, INFO_WEAPON_BLASTER_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_BLASTER_SUICIDE, NO_MSG, INFO_WEAPON_BLASTER_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_CRYLINK_MURDER, NO_MSG, INFO_WEAPON_CRYLINK_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_CRYLINK_SUICIDE, NO_MSG, INFO_WEAPON_CRYLINK_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_DEVASTATOR_MURDER_DIRECT, NO_MSG, INFO_WEAPON_DEVASTATOR_MURDER_DIRECT, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_DEVASTATOR_MURDER_SPLASH, NO_MSG, INFO_WEAPON_DEVASTATOR_MURDER_SPLASH, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_DEVASTATOR_SUICIDE, NO_MSG, INFO_WEAPON_DEVASTATOR_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_BOLT, NO_MSG, INFO_WEAPON_ELECTRO_MURDER_BOLT, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_COMBO, NO_MSG, INFO_WEAPON_ELECTRO_MURDER_COMBO, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_ORBS, NO_MSG, INFO_WEAPON_ELECTRO_MURDER_ORBS, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_SUICIDE_BOLT, NO_MSG, INFO_WEAPON_ELECTRO_SUICIDE_BOLT, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_SUICIDE_ORBS, NO_MSG, INFO_WEAPON_ELECTRO_SUICIDE_ORBS, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_MURDER_BLAST, NO_MSG, INFO_WEAPON_FIREBALL_MURDER_BLAST, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_MURDER_FIREMINE, NO_MSG, INFO_WEAPON_FIREBALL_MURDER_FIREMINE, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_SUICIDE_BLAST, NO_MSG, INFO_WEAPON_FIREBALL_SUICIDE_BLAST, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_SUICIDE_FIREMINE, NO_MSG, INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_HAGAR_MURDER_BURST, NO_MSG, INFO_WEAPON_HAGAR_MURDER_BURST, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_HAGAR_MURDER_SPRAY, NO_MSG, INFO_WEAPON_HAGAR_MURDER_SPRAY, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_HAGAR_SUICIDE, NO_MSG, INFO_WEAPON_HAGAR_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_HLAC_MURDER, NO_MSG, INFO_WEAPON_HLAC_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_HLAC_SUICIDE, NO_MSG, INFO_WEAPON_HLAC_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_HMG_MURDER_SNIPE, NO_MSG, INFO_WEAPON_HMG_MURDER_SNIPE, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_HMG_MURDER_SPRAY, NO_MSG, INFO_WEAPON_HMG_MURDER_SPRAY, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_HOOK_MURDER, NO_MSG, INFO_WEAPON_HOOK_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_KLEINBOTTLE_MURDER, NO_MSG, INFO_WEAPON_KLEINBOTTLE_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_KLEINBOTTLE_SUICIDE, NO_MSG, INFO_WEAPON_KLEINBOTTLE_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_MACHINEGUN_MURDER_SNIPE, NO_MSG, INFO_WEAPON_MACHINEGUN_MURDER_SNIPE, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_MACHINEGUN_MURDER_SPRAY, NO_MSG, INFO_WEAPON_MACHINEGUN_MURDER_SPRAY, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_MINELAYER_LIMIT, NO_MSG, INFO_WEAPON_MINELAYER_LIMIT, CENTER_WEAPON_MINELAYER_LIMIT) - MSG_MULTI_NOTIF(1, WEAPON_MINELAYER_MURDER, NO_MSG, INFO_WEAPON_MINELAYER_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_MINELAYER_SUICIDE, NO_MSG, INFO_WEAPON_MINELAYER_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_MORTAR_MURDER_BOUNCE, NO_MSG, INFO_WEAPON_MORTAR_MURDER_BOUNCE, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_MORTAR_MURDER_EXPLODE, NO_MSG, INFO_WEAPON_MORTAR_MURDER_EXPLODE, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_MORTAR_SUICIDE_BOUNCE, NO_MSG, INFO_WEAPON_MORTAR_SUICIDE_BOUNCE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_MORTAR_SUICIDE_EXPLODE, NO_MSG, INFO_WEAPON_MORTAR_SUICIDE_EXPLODE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER, NO_MSG, INFO_WEAPON_RIFLE_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL, NO_MSG, INFO_WEAPON_RIFLE_MURDER_HAIL, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL_PIERCING, NO_MSG, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_PIERCING, NO_MSG, INFO_WEAPON_RIFLE_MURDER_PIERCING, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_RPC_MURDER_DIRECT, NO_MSG, INFO_WEAPON_RPC_MURDER_DIRECT, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_RPC_MURDER_SPLASH, NO_MSG, INFO_WEAPON_RPC_MURDER_SPLASH, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_RPC_SUICIDE_DIRECT, NO_MSG, INFO_WEAPON_RPC_SUICIDE_DIRECT, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_RPC_SUICIDE_SPLASH, NO_MSG, INFO_WEAPON_RPC_SUICIDE_SPLASH, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_SEEKER_MURDER_SPRAY, NO_MSG, INFO_WEAPON_SEEKER_MURDER_SPRAY, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_SEEKER_MURDER_TAG, NO_MSG, INFO_WEAPON_SEEKER_MURDER_TAG, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_SEEKER_SUICIDE, NO_MSG, INFO_WEAPON_SEEKER_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_SHOCKWAVE_MURDER, NO_MSG, INFO_WEAPON_SHOCKWAVE_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_SHOCKWAVE_MURDER_SLAP, NO_MSG, INFO_WEAPON_SHOCKWAVE_MURDER_SLAP, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_SHOTGUN_MURDER, NO_MSG, INFO_WEAPON_SHOTGUN_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_SHOTGUN_MURDER_SLAP, NO_MSG, INFO_WEAPON_SHOTGUN_MURDER_SLAP, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_THINKING_WITH_PORTALS, NO_MSG, INFO_WEAPON_THINKING_WITH_PORTALS, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_TUBA_MURDER, NO_MSG, INFO_WEAPON_TUBA_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_TUBA_SUICIDE, NO_MSG, INFO_WEAPON_TUBA_SUICIDE, CENTER_DEATH_SELF_GENERIC) - MSG_MULTI_NOTIF(1, WEAPON_VAPORIZER_MURDER, NO_MSG, INFO_WEAPON_VAPORIZER_MURDER, NO_MSG) - MSG_MULTI_NOTIF(1, WEAPON_VORTEX_MURDER, NO_MSG, INFO_WEAPON_VORTEX_MURDER, NO_MSG) - -#define MULTITEAM_CHOICE2(default,challow,prefix,chtype,optiona,optionb) \ - MSG_CHOICE_NOTIF(default, challow, prefix##RED, chtype, optiona##RED, optionb##RED) \ - MSG_CHOICE_NOTIF(default, challow, prefix##BLUE, chtype, optiona##BLUE, optionb##BLUE) -#define MULTITEAM_CHOICE3(default,challow,prefix,chtype,optiona,optionb) \ - MSG_CHOICE_NOTIF(default, challow, prefix##RED, chtype, optiona##RED, optionb##RED) \ - MSG_CHOICE_NOTIF(default, challow, prefix##BLUE, chtype, optiona##BLUE, optionb##BLUE) \ - MSG_CHOICE_NOTIF(default, challow, prefix##YELLOW, chtype, optiona##YELLOW, optionb##YELLOW) -#define MULTITEAM_CHOICE4(default,challow,prefix,chtype,optiona,optionb) \ - MSG_CHOICE_NOTIF(default, challow, prefix##RED, chtype, optiona##RED, optionb##RED) \ - MSG_CHOICE_NOTIF(default, challow, prefix##BLUE, chtype, optiona##BLUE, optionb##BLUE) \ - MSG_CHOICE_NOTIF(default, challow, prefix##YELLOW, chtype, optiona##YELLOW, optionb##YELLOW) \ - MSG_CHOICE_NOTIF(default, challow, prefix##PINK, chtype, optiona##PINK, optionb##PINK) -#define MULTITEAM_CHOICE(default,challow,prefix,teams,chtype,optiona,optionb) \ - MULTITEAM_CHOICE##teams(default,challow,prefix,chtype,optiona,optionb) - -// MSG_CHOICE_NOTIFICATIONS - MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_BROKEN_, 4, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_BROKEN_) - MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_TIME_, 4, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_TIME_) - MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_UNBROKEN_, 4, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_UNBROKEN_) - MULTITEAM_CHOICE(1, 2, CHOICE_CTF_PICKUP_TEAM_, 4, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_, CENTER_CTF_PICKUP_TEAM_VERBOSE_) - MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_TEAM_NEUTRAL, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_NEUTRAL, CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL) - MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_ENEMY, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY, CENTER_CTF_PICKUP_ENEMY_VERBOSE) - MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_ENEMY_NEUTRAL, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_NEUTRAL, CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE) - MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_ENEMY_TEAM, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_TEAM, CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE) - MSG_CHOICE_NOTIF(1, 1, CHOICE_FRAG, MSG_CENTER, CENTER_DEATH_MURDER_FRAG, CENTER_DEATH_MURDER_FRAG_VERBOSE) - MSG_CHOICE_NOTIF(1, 1, CHOICE_FRAGGED, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED, CENTER_DEATH_MURDER_FRAGGED_VERBOSE) - MSG_CHOICE_NOTIF(1, 1, CHOICE_TYPEFRAG, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE) - MSG_CHOICE_NOTIF(1, 1, CHOICE_TYPEFRAGGED, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE) - //MSG_CHOICE_NOTIF(2, CHOICE_) diff --git a/qcsrc/common/notifications.qc b/qcsrc/common/notifications.qc deleted file mode 100644 index def7484ef..000000000 --- a/qcsrc/common/notifications.qc +++ /dev/null @@ -1,2190 +0,0 @@ -#if defined(CSQC) - #include "../client/announcer.qh" -#elif defined(MENUQC) -#elif defined(SVQC) - #include "constants.qh" - #include "teams.qh" - #include "../server/autocvars.qh" - #include "../server/constants.qh" - #include "../server/defs.qh" - #include "notifications.qh" - #include -#endif - -// ================================================ -// Unified notification system, written by Samual -// Last updated: August, 2013 -// ================================================ - -string Get_Notif_TypeName(int net_type) -{ - switch(net_type) - { - case MSG_ANNCE: return "MSG_ANNCE"; - case MSG_INFO: return "MSG_INFO"; - case MSG_CENTER: return "MSG_CENTER"; - case MSG_CENTER_CPID: return "MSG_CENTER_CPID"; - case MSG_MULTI: return "MSG_MULTI"; - case MSG_CHOICE: return "MSG_CHOICE"; - } - backtrace(sprintf("Get_Notif_TypeName(%d): Improper net type!\n", net_type)); - return ""; -} - -entity Get_Notif_Ent(int net_type, int net_name) -{ - switch(net_type) - { - case MSG_ANNCE: return msg_annce_notifs[net_name - 1]; - case MSG_INFO: return msg_info_notifs[net_name - 1]; - case MSG_CENTER: return msg_center_notifs[net_name - 1]; - case MSG_MULTI: return msg_multi_notifs[net_name - 1]; - case MSG_CHOICE: return msg_choice_notifs[net_name - 1]; - } - backtrace(sprintf("Get_Notif_Ent(%d, %d): Improper net type!\n", net_type, net_name)); - return world; -} - -#ifdef SVQC -#ifdef NOTIFICATIONS_DEBUG -string Get_Notif_BroadcastName(float broadcast) -{ - switch(broadcast) - { - case NOTIF_ONE: return "NOTIF_ONE"; - case NOTIF_ONE_ONLY: return "NOTIF_ONE_ONLY"; - case NOTIF_ALL_EXCEPT: return "NOTIF_ALL_EXCEPT"; - case NOTIF_ALL: return "NOTIF_ALL"; - case NOTIF_TEAM: return "NOTIF_TEAM"; - case NOTIF_TEAM_EXCEPT: return "NOTIF_TEAM_EXCEPT"; - } - backtrace(sprintf("Get_Notif_BroadcastName(%d): Improper broadcast!\n", broadcast)); - return ""; -} -#endif -#endif - -string Notification_CheckArgs_TypeName(float net_type, float net_name) -{ - // check supplied type and name for errors - string checkargs = ""; - #define CHECKARG_TYPENAME(type) case MSG_##type: \ - { if(!net_name || (net_name > NOTIF_##type##_COUNT)) \ - { checkargs = sprintf("Improper name: %d!", net_name); } break; } - switch(net_type) - { - CHECKARG_TYPENAME(ANNCE) - CHECKARG_TYPENAME(INFO) - CHECKARG_TYPENAME(CENTER) - CHECKARG_TYPENAME(MULTI) - CHECKARG_TYPENAME(CHOICE) - default: { checkargs = sprintf("Improper type: %d!", checkargs, net_type); break; } - } - #undef CHECKARG_TYPENAME - return checkargs; -} - -#ifdef SVQC -string Notification_CheckArgs( - float broadcast, entity client, - float net_type, float net_name) -{ - // check supplied broadcast, target, type, and name for errors - string checkargs = Notification_CheckArgs_TypeName(net_type, net_name); - if(checkargs != "") { checkargs = strcat(checkargs, " "); } - switch(broadcast) - { - case NOTIF_ONE: - case NOTIF_ONE_ONLY: - { - if(IS_NOT_A_CLIENT(client)) - { checkargs = sprintf("%sNo client provided!", checkargs); } - break; - } - - case NOTIF_ALL_EXCEPT: - { - if(IS_NOT_A_CLIENT(client)) - { checkargs = sprintf("%sException can't be a non-client!", checkargs); } - break; - } - - case NOTIF_ALL: - { - if(client) - { checkargs = sprintf("%sEntity provided when world was required!", checkargs); } - break; - } - - case NOTIF_TEAM: - { - if (!teamplay) - { checkargs = sprintf("%sTeamplay not active!", checkargs); } - //else if (!client.team) { checkargs = sprintf("%sNo team provided!", checkargs); } - break; - } - - case NOTIF_TEAM_EXCEPT: - { - if (!teamplay) - { checkargs = sprintf("%sTeamplay not active!", checkargs); } - else if(IS_NOT_A_CLIENT(client)) - { checkargs = sprintf("%sException can't be a non-client!", checkargs); } - break; - } - - default: { checkargs = sprintf("%sImproper broadcast: %d!", checkargs, broadcast); break; } - } - return checkargs; -} - -float Notification_ShouldSend(float broadcast, entity to_client, entity other_client) -{ - switch(broadcast) - { - case NOTIF_ONE: // send to one client and their spectator - { - if( - (to_client == other_client) - || - ( - IS_SPEC(to_client) - && - (to_client.enemy == other_client) - ) - ) { return true; } - break; - } - case NOTIF_ONE_ONLY: // send ONLY to one client - { - if(to_client == other_client) { return true; } - break; - } - case NOTIF_TEAM: // send only to X team and their spectators - { - if( - (to_client.team == other_client.team) - || - ( - IS_SPEC(to_client) - && - (to_client.enemy.team == other_client.team) - ) - ) { return true; } - break; - } - case NOTIF_TEAM_EXCEPT: // send only to X team and their spectators, except for Y person and their spectators - { - if( - (to_client != other_client) - && - ( - (to_client.team == other_client.team) - || - ( - IS_SPEC(to_client) - && - ( - (to_client.enemy != other_client) - && - (to_client.enemy.team == other_client.team) - ) - ) - ) - ) { return true; } - break; - } - case NOTIF_ALL: // send to everyone - { - return true; - } - case NOTIF_ALL_EXCEPT: // send to everyone except X person and their spectators - { - if( - (to_client != other_client) - && - !( - IS_SPEC(to_client) - && - (to_client.enemy == other_client) - ) - ) { return true; } - break; - } - } - return false; -} - -#endif - -// =============================== -// Initialization Core Functions -// =============================== - -// used by restartnotifs command to initialize notifications -void Destroy_Notification_Entity(entity notif) -{ - if(notif.nent_name != "") { strunzone(notif.nent_name); } - if(notif.nent_snd != "") { strunzone(notif.nent_snd); } - if(notif.nent_args != "") { strunzone(notif.nent_args); } - if(notif.nent_hudargs != "") { strunzone(notif.nent_hudargs); } - if(notif.nent_icon != "") { strunzone(notif.nent_icon); } - if(notif.nent_durcnt != "") { strunzone(notif.nent_durcnt); } - if(notif.nent_string != "") { strunzone(notif.nent_string); } - remove(notif); -} - -void Destroy_All_Notifications() -{ - entity notif; - int i; - - #define DESTROY_LOOP(type,count) MACRO_BEGIN { \ - for(i = 1; i <= count; ++i) \ - { \ - notif = Get_Notif_Ent(type, i); \ - if (!notif) { backtrace("Destroy_All_Notifications(): Missing notification entity!\n"); return; } \ - Destroy_Notification_Entity(notif); \ - } \ - } MACRO_END - - // kill all networked notifications and centerprints - #ifdef SVQC - Kill_Notification(NOTIF_ALL, world, 0, 0); - #else - reset_centerprint_messages(); - #endif - - // kill all real notification entities - DESTROY_LOOP(MSG_ANNCE, NOTIF_ANNCE_COUNT); - DESTROY_LOOP(MSG_INFO, NOTIF_INFO_COUNT); - DESTROY_LOOP(MSG_CENTER, NOTIF_CENTER_COUNT); - DESTROY_LOOP(MSG_MULTI, NOTIF_MULTI_COUNT); - DESTROY_LOOP(MSG_CHOICE, NOTIF_CHOICE_COUNT); - #undef DESTROY_LOOP -} - -string Process_Notif_Line( - int typeId, - bool chat, - string input, - string notiftype, - string notifname, - string stringtype) -{ - #ifdef CSQC - if(typeId == MSG_INFO) - { - if((chat && autocvar_notification_allow_chatboxprint) - || (autocvar_notification_allow_chatboxprint == 2)) - { - // pass 1: add ETX char at beginning of line - input = strcat("\{3}", input); - - // pass 2: add ETX char at end of each new line (so that - // messages with multiple lines are put through chatbox too) - input = strreplace("\n", "\n\{3}", input); - - // pass 3: strip trailing ETX char - if(substring(input, (strlen(input) - 1), 1) == "\{3}") - { input = substring(input, 0, (strlen(input) - 1)); } - } - } - #endif - - // done to both MSG_INFO and MSG_CENTER - if(substring(input, (strlen(input) - 1), 1) == "\n") - { - LOG_INFOF( - strcat( - "^1TRAILING NEW LINE AT END OF NOTIFICATION: ", - "^7net_type = %s, net_name = %s, string = %s.\n" - ), - notiftype, - notifname, - stringtype - ); - notif_error = true; - input = substring(input, 1, (strlen(input) - 1)); - } - - return input; -} - -string Process_Notif_Args( - float arg_type, - string args, - string notiftype, - string notifname) -{ - string selected, remaining = args; - float sel_num = 0; - - for (;(remaining != "");) - { - selected = car(remaining); remaining = cdr(remaining); - - switch(arg_type) - { - case 1: // normal args - { - if(sel_num == NOTIF_MAX_ARGS) - { - LOG_INFOF( - strcat( - "^1NOTIFICATION HAS TOO MANY ARGUMENTS: ", - "^7net_type = %s, net_name = %s, max args = %d.\n" - ), - notiftype, - notifname, - NOTIF_MAX_ARGS - ); - notif_error = true; - break; - } - - switch(strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_SV(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_DC(selected,result) - #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: - { - LOG_INFOF( - strcat( - "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ", - "^7net_type = %s, net_name = %s, args arg = '%s'.\n" - ), - notiftype, - notifname, - selected - ); - notif_error = true; - break; - } - } - break; - } - case 2: // hudargs - { - if(sel_num == NOTIF_MAX_HUDARGS) - { - LOG_INFOF( - strcat( - "^1NOTIFICATION HAS TOO MANY ARGUMENTS: ", - "^7net_type = %s, net_name = %s, max hudargs = %d.\n" - ), - notiftype, - notifname, - NOTIF_MAX_HUDARGS - ); - notif_error = true; - break; - } - - switch(strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV_DC(selected,result) - #define ARG_CASE_ARG_CS_SV(selected,result) - #define ARG_CASE_ARG_CS(selected,result) - #define ARG_CASE_ARG_SV(selected,result) - #define ARG_CASE_ARG_DC(selected,result) - #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: - { - LOG_INFOF( - strcat( - "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ", - "^7net_type = %s, net_name = %s, hudargs arg = '%s'.\n" - ), - notiftype, - notifname, - selected - ); - notif_error = true; - break; - } - } - break; - } - case 3: // durcnt - { - if(sel_num == NOTIF_MAX_DURCNT) - { - LOG_INFOF( - strcat( - "^1NOTIFICATION HAS TOO MANY ARGUMENTS: ", - "^7net_type = %s, net_name = %s, max durcnt = %d.\n" - ), - notiftype, - notifname, - NOTIF_MAX_DURCNT - ); - notif_error = true; - break; - } - - switch(strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected,result) - #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV(selected,result) - #define ARG_CASE_ARG_CS(selected,result) - #define ARG_CASE_ARG_SV(selected,result) - #define ARG_CASE_ARG_DC(selected,result) case selected: { ++sel_num; break; } - #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: - { - if(ftos(stof(selected)) != "") { ++sel_num; } - else - { - LOG_INFOF( - strcat( - "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: ", - "^7net_type = %s, net_name = %s, durcnt arg = '%s'.\n" - ), - notiftype, - notifname, - selected - ); - notif_error = true; - } - break; - } - } - break; - } - } - } - return args; -} - -void Create_Notification_Entity( - float var_default, - float var_cvar, - int typeId, - int nameid, - string namestring, - int strnum, - int flnum, - /* MSG_ANNCE */ - float channel, - string snd, - float vol, - float position, - /* MSG_INFO & MSG_CENTER */ - string args, - string hudargs, - string icon, - float cpid, - string durcnt, - string normal, - string gentle, - /* MSG_MULTI */ - int anncename, - int infoname, - int centername, - /* MSG_CHOICE */ - float challow_def, - float challow_var, - int chtype, - int optiona, - int optionb) -{ - // ===================== - // Global Entity Setup - // ===================== - entity notif = new_pure(notification); - switch(typeId) - { - case MSG_ANNCE: - { - msg_annce_notifs[nameid - 1] = notif; - notif.classname = "msg_annce_notification"; - break; - } - case MSG_INFO: - { - msg_info_notifs[nameid - 1] = notif; - notif.classname = "msg_info_notification"; - break; - } - case MSG_CENTER: - { - msg_center_notifs[nameid - 1] = notif; - notif.classname = "msg_center_notification"; - break; - } - case MSG_MULTI: - { - msg_multi_notifs[nameid - 1] = notif; - notif.classname = "msg_multi_notification"; - break; - } - case MSG_CHOICE: - { - msg_choice_notifs[nameid - 1] = notif; - notif.classname = "msg_choice_notification"; - break; - } - - default: - { - error(sprintf( - strcat( - "^1NOTIFICATION WITH IMPROPER TYPE: ", - "^7net_type = %d, net_name = %s.\n" - ), - typeId, - namestring - )); - return; // It's not possible to recover from this one - } - } - notif.nent_default = var_default; - notif.nent_enabled = (1 <= var_cvar); - notif.nent_type = typeId; - notif.nent_id = nameid; - notif.nent_name = strzone(namestring); - - string typestring = Get_Notif_TypeName(typeId); - - // Other pre-notif-setup requisites - notif_error = false; - - // ==================== - // Notification Setup - // ==================== - switch(typeId) - { - case MSG_ANNCE: - { - // Set MSG_ANNCE information and handle precaching - #ifdef CSQC - if (!(GENTLE && (var_cvar == 1))) - { - if(snd != "") - { - if(notif.nent_enabled) - { - precache_sound(sprintf("announcer/%s/%s.wav", AnnouncerOption(), snd)); - notif.nent_channel = channel; - notif.nent_snd = strzone(snd); - notif.nent_vol = vol; - notif.nent_position = position; - } - } - else - { - LOG_INFOF( - strcat( - "^1NOTIFICATION WITH NO SOUND: ", - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - } - else { notif.nent_enabled = false; } - #else - notif.nent_enabled = false; - #endif - - break; - } - - case MSG_INFO: - case MSG_CENTER: - { - // Set MSG_INFO and MSG_CENTER string/float counts - notif.nent_stringcount = strnum; - notif.nent_floatcount = flnum; - - // Only initialize arguments if we're either a client or on a dedicated server - #ifdef SVQC - float should_process_args = server_is_dedicated; - #else - float should_process_args = true; - #endif - - if(should_process_args) - { - // ======================== - // Process Main Arguments - // ======================== - if(strnum + flnum) - { - if(args != "") - { - notif.nent_args = strzone( - Process_Notif_Args(1, args, typestring, namestring)); - } - else if((hudargs == "") && (durcnt =="")) - { - LOG_INFOF( - strcat( - "^1NOTIFICATION HAS ARG COUNTS BUT NO ARGS OR HUDARGS OR DURCNT: ", - "^7net_type = %s, net_name = %s, strnum = %d, flnum = %d\n" - ), - typestring, - namestring, - strnum, - flnum - ); - notif_error = true; - } - } - else if(args != "") - { - notif.nent_args = strzone( - Process_Notif_Args(1, args, typestring, namestring)); - } - - - // ======================================= - // Process HUD and Centerprint Arguments - // Only processed on CSQC, as these - // args are only for HUD features. - // ======================================= - #ifdef CSQC - if(hudargs != "") - { - notif.nent_hudargs = strzone( - Process_Notif_Args(2, hudargs, typestring, namestring)); - - if(icon != "") { notif.nent_icon = strzone(icon); } - else - { - LOG_INFOF( - strcat( - "^1NOTIFICATION HAS HUDARGS BUT NO ICON: ", - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - } - else if(icon != "") - { - LOG_INFOF( - strcat( - "^1NOTIFICATION HAS ICON BUT NO HUDARGS: ", - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - - if(durcnt != "") - { - notif.nent_durcnt = strzone( - Process_Notif_Args(3, durcnt, typestring, namestring)); - - if(cpid != NO_MSG) { notif.nent_cpid = cpid; } - else - { - LOG_INFOF( - strcat( - "^1NOTIFICATION HAS DURCNT BUT NO CPID: ", - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - } - else if(cpid != NO_MSG) { notif.nent_cpid = cpid; } - #endif - - - // ====================== - // Process Notif String - // ====================== - #define SET_NOTIF_STRING(string,stringname) MACRO_BEGIN { \ - notif.nent_string = strzone(CCR( \ - Process_Notif_Line( \ - typeId, \ - (var_cvar > 1), \ - string, \ - typestring, \ - namestring, \ - stringname \ - )) \ - ); \ - } MACRO_END - - if(GENTLE) - { - if(gentle != "") { SET_NOTIF_STRING(gentle, "GENTLE"); } - else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL"); } - } - else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL"); } - #undef SET_NOTIF_STRING - - // Check to make sure a string was chosen - if(notif.nent_string == "") - { - LOG_INFOF( - strcat( - "^1EMPTY NOTIFICATION: ", - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - } - - break; - } - - case MSG_MULTI: - { - // Set MSG_MULTI string/float counts - if((anncename == NO_MSG) && (infoname == NO_MSG) && (centername == NO_MSG)) - { - LOG_INFOF( - strcat( - "^1NOTIFICATION WITH NO SUBCALLS: ", - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - else - { - // announcements don't actually need any arguments, so lets not even count them. - if(anncename != NO_MSG) { notif.nent_msgannce = msg_annce_notifs[anncename - 1]; } - - float infoname_stringcount = 0, infoname_floatcount = 0; - float centername_stringcount = 0, centername_floatcount = 0; - - if(infoname != NO_MSG) - { - notif.nent_msginfo = msg_info_notifs[infoname - 1]; - infoname_stringcount = notif.nent_msginfo.nent_stringcount; - infoname_floatcount = notif.nent_msginfo.nent_floatcount; - } - - if(centername != NO_MSG) - { - notif.nent_msgcenter = msg_center_notifs[centername - 1]; - centername_stringcount = notif.nent_msgcenter.nent_stringcount; - centername_floatcount = notif.nent_msgcenter.nent_floatcount; - } - - // set the requirements of THIS notification to the totals of its subcalls - notif.nent_stringcount = max(infoname_stringcount, centername_stringcount); - notif.nent_floatcount = max(infoname_floatcount, centername_floatcount); - } - - break; - } - - case MSG_CHOICE: - { - if((chtype == NO_MSG) || (optiona == NO_MSG) || (optionb == NO_MSG)) - { - LOG_INFOF( - strcat( - "^1NOTIFICATION IS MISSING CHOICE PARAMS: ", - "^7net_type = %s, net_name = %s.\n" - ), - typestring, - namestring - ); - notif_error = true; - } - else - { - switch(chtype) - { - case MSG_ANNCE: - { - notif.nent_optiona = msg_annce_notifs[optiona - 1]; - notif.nent_optionb = msg_annce_notifs[optionb - 1]; - break; - } - case MSG_INFO: - { - notif.nent_optiona = msg_info_notifs[optiona - 1]; - notif.nent_optionb = msg_info_notifs[optionb - 1]; - break; - } - case MSG_CENTER: - { - notif.nent_optiona = msg_center_notifs[optiona - 1]; - notif.nent_optionb = msg_center_notifs[optionb - 1]; - break; - } - case MSG_MULTI: - { - notif.nent_optiona = msg_multi_notifs[optiona - 1]; - notif.nent_optionb = msg_multi_notifs[optionb - 1]; - break; - } - case MSG_CHOICE: // should we REALLY allow nested options?... - { - notif.nent_optiona = msg_choice_notifs[optiona - 1]; - notif.nent_optionb = msg_choice_notifs[optionb - 1]; - break; - } - - default: - { - LOG_INFOF( - strcat( - "^1NOTIFICATION WITH IMPROPER TYPE: ", - "^7net_type = %d, net_name = %s.\n" - ), - typeId, - namestring - ); - notif_error = true; - break; - } - } - notif.nent_challow_def = challow_def; // 0: never allowed, 1: allowed in warmup, 2: always allowed - notif.nent_challow_var = challow_var; // 0: never allowed, 1: allowed in warmup, 2: always allowed - notif.nent_stringcount = max(notif.nent_optiona.nent_stringcount, notif.nent_optionb.nent_stringcount); - notif.nent_floatcount = max(notif.nent_optiona.nent_floatcount, notif.nent_optionb.nent_floatcount); - - /*#ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Create_Notification_Entity(...): MSG_CHOICE: %s\n%s\n%s\n", - notif.nent_name, - sprintf( - "^ optiona: %s %s : %d %d", - Get_Notif_TypeName(notif.nent_optiona.nent_type), - notif.nent_optiona.nent_name, - notif.nent_optiona.nent_stringcount, - notif.nent_optiona.nent_floatcount - ), - sprintf( - "^ optionb: %s %s : %d %d", - Get_Notif_TypeName(notif.nent_optionb.nent_type), - notif.nent_optionb.nent_name, - notif.nent_optionb.nent_stringcount, - notif.nent_optionb.nent_floatcount - ) - )); - #endif*/ - } - break; - } - - default: - { - LOG_INFOF( - strcat( - "^1NOTIFICATION WITH IMPROPER TYPE: ", - "^7net_type = %d, net_name = %s.\n" - ), - typeId, - namestring - ); - notif_error = true; - break; - } - } - - // now check to see if any errors happened - if(notif_error) - { - notif.nent_enabled = false; // disable the notification so it can't cause trouble - notif_global_error = true; // throw the red flag that an error happened on init - } -} - - -// =============== -// Cvar Handling -// =============== - -// used by MSG_CHOICE to build list of choices -#ifdef SVQC -void Notification_GetCvars() -{ - for(int i = 0; i <= NOTIF_CHOICE_COUNT; ++i) - { - GetCvars_handleFloat( - get_cvars_s, - get_cvars_f, - msg_choice_choices[i], - sprintf("notification_%s", msg_choice_notifs[i].nent_name) - ); - } -} -#endif - -// used to output notifications.cfg file -void Dump_Notifications(float fh, float alsoprint) -{ - #define NOTIF_WRITE(a) { \ - fputs(fh, a); \ - if(alsoprint) { LOG_INFO(a); } } - #define NOTIF_WRITE_ENTITY(description) { \ - notif_msg = \ - sprintf( \ - "seta notification_%s \"%d\" \"%s\"\n", \ - e.nent_name, e.nent_default, description \ - ); \ - NOTIF_WRITE(notif_msg) } - #define NOTIF_WRITE_ENTITY_CHOICE(descriptiona,descriptionb) { \ - notif_msg = \ - sprintf( \ - "seta notification_%s \"%d\" \"%s\"\n" \ - "seta notification_%s_ALLOWED \"%d\" \"%s\"\n", \ - e.nent_name, e.nent_default, descriptiona, \ - e.nent_name, e.nent_challow_def, descriptionb \ - ); \ - NOTIF_WRITE(notif_msg) } - #define NOTIF_WRITE_HARDCODED(cvar,default,description) { \ - notif_msg = \ - sprintf( \ - "seta notification_%s \"%s\" \"%s\"\n", \ - cvar, default, description \ - ); \ - NOTIF_WRITE(notif_msg) } - - string notif_msg; - int i; - entity e; - - // Note: This warning only applies to the notifications.cfg file that is output... - - // You ARE supposed to manually edit this function to add i.e. hard coded - // notification variables for mutators or game modes or such and then - // regenerate the notifications.cfg file from the new code. - - NOTIF_WRITE("// ********************************************** //\n"); - NOTIF_WRITE("// ** WARNING - DO NOT MANUALLY EDIT THIS FILE ** //\n"); - NOTIF_WRITE("// ** ** //\n"); - NOTIF_WRITE("// ** This file is automatically generated ** //\n"); - NOTIF_WRITE("// ** by code with the command 'dumpnotifs'. ** //\n"); - NOTIF_WRITE("// ** ** //\n"); - NOTIF_WRITE("// ** If you add a new notification, please ** //\n"); - NOTIF_WRITE("// ** regenerate this file with that command ** //\n"); - NOTIF_WRITE("// ** making sure that the output matches ** //\n"); - NOTIF_WRITE("// ** with the lists and defaults in code. ** //\n"); - NOTIF_WRITE("// ** ** //\n"); - NOTIF_WRITE("// ********************************************** //\n"); - - // These notifications will also append their string as a comment... - // This is not necessary, and does not matter if they vary between config versions, - // it is just a semi-helpful tool for those who want to manually change their user settings. - - NOTIF_WRITE(sprintf("\n// MSG_ANNCE notifications (count = %d):\n", NOTIF_ANNCE_COUNT)); - for(i = 1; i <= NOTIF_ANNCE_COUNT; ++i) - { - e = Get_Notif_Ent(MSG_ANNCE, i); - if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - - NOTIF_WRITE_ENTITY( - "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" - ); - } - - NOTIF_WRITE(sprintf("\n// MSG_INFO notifications (count = %d):\n", NOTIF_INFO_COUNT)); - for(i = 1; i <= NOTIF_INFO_COUNT; ++i) - { - e = Get_Notif_Ent(MSG_INFO, i); - if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - - NOTIF_WRITE_ENTITY( - "0 = off, 1 = print to console, " - "2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" - ); - } - - NOTIF_WRITE(sprintf("\n// MSG_CENTER notifications (count = %d):\n", NOTIF_CENTER_COUNT)); - for(i = 1; i <= NOTIF_CENTER_COUNT; ++i) - { - e = Get_Notif_Ent(MSG_CENTER, i); - if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - - NOTIF_WRITE_ENTITY( - "0 = off, 1 = centerprint" - ); - } - - NOTIF_WRITE(sprintf("\n// MSG_MULTI notifications (count = %d):\n", NOTIF_MULTI_COUNT)); - for(i = 1; i <= NOTIF_MULTI_COUNT; ++i) - { - e = Get_Notif_Ent(MSG_MULTI, i); - if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - - NOTIF_WRITE_ENTITY( - "Enable this multiple notification" - ); - } - - NOTIF_WRITE(sprintf("\n// MSG_CHOICE notifications (count = %d):\n", NOTIF_CHOICE_COUNT)); - for(i = 1; i <= NOTIF_CHOICE_COUNT; ++i) - { - e = Get_Notif_Ent(MSG_CHOICE, i); - if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; } - - NOTIF_WRITE_ENTITY_CHOICE( - "Choice for this notification 0 = off, 1 = default message, 2 = verbose message", - "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" - ); - } - - // edit these to match whichever cvars are used for specific notification options - NOTIF_WRITE("\n// HARD CODED notification variables:\n"); - - NOTIF_WRITE_HARDCODED( - "allow_chatboxprint", "1", - "Allow INFO notifications to be printed to chat box" - "0 = do not allow, " - "1 = allow only if allowed by individual notification_INFO* cvars, " - "2 = force all INFO notifications to be printed to the chatbox" - ); - - NOTIF_WRITE_HARDCODED( - "debug", "0", - "Print extra debug information on all notification function calls " - "(Requires -DNOTIFICATIONS_DEBUG flag to be enabled on QCSRC compilation)... " - "0 = disabled, 1 = dprint, 2 = print" - ); - - NOTIF_WRITE_HARDCODED( - "errors_are_fatal", "1", - "If a notification fails upon initialization, cause a Host_Error to stop the program" - ); - - NOTIF_WRITE_HARDCODED( - "item_centerprinttime", "1.5", - "How long to show item information centerprint messages (like 'You got the Electro' or such)" - ); - - NOTIF_WRITE_HARDCODED( - "lifetime_mapload", "10", - "Amount of time that notification entities last immediately at mapload (in seconds) " - "to help prevent notifications from being lost on early init (like gamestart countdown)" - ); - - NOTIF_WRITE_HARDCODED( - "lifetime_runtime", "0.5", - "Amount of time that notification entities last on the server during runtime (In seconds)" - ); - - NOTIF_WRITE_HARDCODED( - "server_allows_location", "1", - "Server side cvar for allowing death messages to show location information too" - ); - - NOTIF_WRITE_HARDCODED( - "show_location", "0", - "Append location information to MSG_INFO death/kill messages" - ); - - NOTIF_WRITE_HARDCODED( - "show_location_string", "", - "Replacement string piped into sprintf, " - "so you can do different messages like this: ' at the %s' or ' (near %s)'" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees", "1", - "Print information about sprees in death/kill messages" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_center", "1", - "Show spree information in MSG_CENTER messages... " - "0 = off, 1 = target (but only for first victim) and attacker" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_center_specialonly", "1", - "Don't show spree information in MSG_CENTER messages if it isn't an achievement" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_info", "3", - "Show spree information in MSG_INFO messages... " - "0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_info_newline", "1", - "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself" - ); - - NOTIF_WRITE_HARDCODED( - "show_sprees_info_specialonly", "1", - "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement" - ); - - NOTIF_WRITE(sprintf( - strcat( - "\n// Notification counts (total = %d): ", - "MSG_ANNCE = %d, MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d, MSG_CHOICE = %d\n" - ), - ( - NOTIF_ANNCE_COUNT + - NOTIF_INFO_COUNT + - NOTIF_CENTER_COUNT + - NOTIF_MULTI_COUNT + - NOTIF_CHOICE_COUNT - ), - NOTIF_ANNCE_COUNT, - NOTIF_INFO_COUNT, - NOTIF_CENTER_COUNT, - NOTIF_MULTI_COUNT, - NOTIF_CHOICE_COUNT - )); - - return; - #undef NOTIF_WRITE_HARDCODED - #undef NOTIF_WRITE_ENTITY - #undef NOTIF_WRITE -} - - -// =============================== -// Frontend Notification Pushing -// =============================== - -#ifdef NOTIFICATIONS_DEBUG -void Debug_Notification(string input) -{ - switch(autocvar_notification_debug) - { - case 1: { LOG_TRACE(input); break; } - case 2: { LOG_INFO(input); break; } - } -} -#endif - -string Local_Notification_sprintf( - string input, string args, - string s1, string s2, string s3, string s4, - int f1, float f2, float f3, float f4) -{ - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification_sprintf('%s^7', '%s', %s, %s);\n", - MakeConsoleSafe(input), - args, - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - string selected; - int sel_num; - for(sel_num = 0; sel_num < NOTIF_MAX_ARGS; ++sel_num) { arg_slot[sel_num] = ""; } - - string tmp_s; - - for(sel_num = 0;(args != "");) - { - selected = car(args); args = cdr(args); - NOTIF_HIT_MAX(NOTIF_MAX_ARGS, "Local_Notification_sprintf"); - switch(strtolower(selected)) - { - #ifdef CSQC - #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_CS(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_SV(selected,result) - #define ARG_CASE_ARG_DC(selected,result) - #else - #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_CS(selected,result) - #define ARG_CASE_ARG_SV(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_DC(selected,result) - #endif - #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_ARGS, "Local_Notification_sprintf") - } - } - return sprintf( - strcat(input, "\n"), - arg_slot[0], - arg_slot[1], - arg_slot[2], - arg_slot[3], - arg_slot[4], - arg_slot[5], - arg_slot[6] - ); -} - -#ifdef CSQC -void Local_Notification_sound( - float soundchannel, string soundfile, - float soundvolume, float soundposition) -{ - if((soundfile != prev_soundfile) || (time >= (prev_soundtime + autocvar_cl_announcer_antispam))) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification_sound(world, %f, '%s', %f, %f);\n", - soundchannel, - sprintf( - "announcer/%s/%s.wav", - AnnouncerOption(), - soundfile - ), - soundvolume, - soundposition - )); - #endif - - _sound( - world, - soundchannel, - sprintf( - "announcer/%s/%s.wav", - AnnouncerOption(), - soundfile - ), - soundvolume, - soundposition - ); - - if(prev_soundfile) { strunzone(prev_soundfile); } - prev_soundfile = strzone(soundfile); - prev_soundtime = time; - } - else - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - strcat( - "Local_Notification_sound(world, %f, '%s', %f, %f) ", - "^1BLOCKED BY ANTISPAM:^7 prevsnd: '%s', timediff: %f, limit: %f\n" - ), - soundchannel, - sprintf( - "announcer/%s/%s.wav", - AnnouncerOption(), - soundfile - ), - soundvolume, - soundposition, - prev_soundfile, - (time - prev_soundtime), - autocvar_cl_announcer_antispam - )); - #endif - } -} - -void Local_Notification_HUD_Notify_Push( - string icon, string hudargs, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4) -{ - string selected; - arg_slot[0] = ""; arg_slot[1] = ""; - - int sel_num; - for(sel_num = 0;(hudargs != "");) - { - selected = car(hudargs); hudargs = cdr(hudargs); - NOTIF_HIT_MAX(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push"); - switch(strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV_DC(selected,result) - #define ARG_CASE_ARG_CS_SV(selected,result) - #define ARG_CASE_ARG_CS(selected,result) - #define ARG_CASE_ARG_SV(selected,result) - #define ARG_CASE_ARG_DC(selected,result) - #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push") - } - } - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification_HUD_Notify_Push('%s^7', '%s', %s, %s, %s);\n", - icon, - hudargs, - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4), - MakeConsoleSafe(sprintf("'%s^7', '%s^7'", stof(arg_slot[0]), stof(arg_slot[1]))) - )); - #endif - HUD_Notify_Push(icon, arg_slot[0], arg_slot[1]); -} - -void Local_Notification_centerprint_generic( - string input, string durcnt, - int cpid, float f1, float f2) -{ - arg_slot[0] = ""; arg_slot[1] = ""; - - for(int sel_num = 0;(durcnt != "");) - { - string selected = car(durcnt); durcnt = cdr(durcnt); - NOTIF_HIT_MAX(NOTIF_MAX_DURCNT, "Local_Notification_centerprint_generic"); - switch(strtolower(selected)) - { - #define ARG_CASE_ARG_CS_SV_HA(selected,result) - #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE_ARG_CS_SV(selected,result) - #define ARG_CASE_ARG_CS(selected,result) - #define ARG_CASE_ARG_SV(selected,result) - #define ARG_CASE_ARG_DC(selected,result) case selected: { arg_slot[sel_num] = result; ++sel_num; break; } - #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) - NOTIF_ARGUMENT_LIST - #undef ARG_CASE - #undef ARG_CASE_ARG_DC - #undef ARG_CASE_ARG_SV - #undef ARG_CASE_ARG_CS - #undef ARG_CASE_ARG_CS_SV - #undef ARG_CASE_ARG_CS_SV_DC - #undef ARG_CASE_ARG_CS_SV_HA - default: - { - if(ftos(stof(selected)) != "") { arg_slot[sel_num] = selected; ++sel_num; } - else { NOTIF_HIT_UNKNOWN(NOTIF_MAX_DURCNT, "Local_Notification_centerprint_generic") } - break; - } - } - } - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification_centerprint_generic('%s^7', '%s', %d, %d, %d, %d);\n", - MakeConsoleSafe(input), - durcnt, - f1, f2, - stof(arg_slot[0]), - stof(arg_slot[1]) - )); - #endif - centerprint_generic(cpid, input, stof(arg_slot[0]), stof(arg_slot[1])); -} -#endif - -void Local_Notification(int net_type, int net_name, ...count) -{ - // check if this should be aborted - if(net_name == NOTIF_ABORT) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification(%s, %s, ...);\n", - Get_Notif_TypeName(net_type), - "NOTIF_ABORT" - )); - #endif - return; - } - - // check supplied type and name for errors - string checkargs = Notification_CheckArgs_TypeName(net_type, net_name); - if(checkargs != "") - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification(%s, %d, ...);\n", - Get_Notif_TypeName(net_type), - Get_Notif_Ent(net_type, net_name).nent_name - )); - #endif - backtrace(sprintf("Incorrect usage of Local_Notification: %s\n", checkargs)); - return; - } - - // retreive entity of this notification - entity notif = Get_Notif_Ent(net_type, net_name); - if (!notif) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification(%s, %d, ...);\n", - Get_Notif_TypeName(net_type), - net_name - )); - #endif - backtrace("Local_Notification: Could not find notification entity!\n"); - return; - } - - // check if the notification is enabled - if (!notif.nent_enabled) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification(%s, %s, ...): Entity was disabled...\n", - Get_Notif_TypeName(net_type), - notif.nent_name - )); - #endif - return; - } - - string s1 = ((0 < notif.nent_stringcount) ? ...(0, string) : ""); - string s2 = ((1 < notif.nent_stringcount) ? ...(1, string) : ""); - string s3 = ((2 < notif.nent_stringcount) ? ...(2, string) : ""); - string s4 = ((3 < notif.nent_stringcount) ? ...(3, string) : ""); - float f1 = ((0 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 0), float) : 0); - float f2 = ((1 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 1), float) : 0); - float f3 = ((2 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 2), float) : 0); - float f4 = ((3 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 3), float) : 0); - - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Local_Notification(%s, %s, %s, %s);\n", - Get_Notif_TypeName(net_type), - notif.nent_name, - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - if((notif.nent_stringcount + notif.nent_floatcount) > count) - { - backtrace(sprintf( - strcat( - "Not enough arguments for Local_Notification(%s, %s, ...)! ", - "stringcount(%d) + floatcount(%d) > count(%d)\n", - "Check the definition and function call for accuracy...?\n" - ), - Get_Notif_TypeName(net_type), - notif.nent_name, - notif.nent_stringcount, - notif.nent_floatcount, - count - )); - return; - } - else if((notif.nent_stringcount + notif.nent_floatcount) < count) - { - backtrace(sprintf( - strcat( - "Too many arguments for Local_Notification(%s, %s, ...)! ", - "stringcount(%d) + floatcount(%d) < count(%d)\n", - "Check the definition and function call for accuracy...?\n" - ), - Get_Notif_TypeName(net_type), - notif.nent_name, - notif.nent_stringcount, - notif.nent_floatcount, - count - )); - return; - } - - switch(net_type) - { - case MSG_ANNCE: - { - #ifdef CSQC - Local_Notification_sound( - notif.nent_channel, - notif.nent_snd, - notif.nent_vol, - notif.nent_position - ); - #else - backtrace("MSG_ANNCE on server?... Please notify Samual immediately!\n"); - #endif - break; - } - - case MSG_INFO: - { - print( - Local_Notification_sprintf( - notif.nent_string, - notif.nent_args, - s1, s2, s3, s4, - f1, f2, f3, f4) - ); - #ifdef CSQC - if(notif.nent_icon != "") - { - if ( notif.nent_iconargs != "" ) - { - notif.nent_icon = Local_Notification_sprintf( - notif.nent_icon,notif.nent_iconargs, - s1, s2, s3, s4, f1, f2, f3, f4); - // remove the newline added by Local_Notification_sprintf - notif.nent_icon = strzone(substring(notif.nent_icon,0,strlen(notif.nent_icon)-1)); - } - Local_Notification_HUD_Notify_Push( - notif.nent_icon, - notif.nent_hudargs, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - #endif - break; - } - - #ifdef CSQC - case MSG_CENTER: - { - Local_Notification_centerprint_generic( - Local_Notification_sprintf( - notif.nent_string, - notif.nent_args, - s1, s2, s3, s4, - f1, f2, f3, f4), - notif.nent_durcnt, - notif.nent_cpid, - f1, f2); - break; - } - #endif - - case MSG_MULTI: - { - if(notif.nent_msginfo) - if(notif.nent_msginfo.nent_enabled) - { - Local_Notification_WOVA( - MSG_INFO, - notif.nent_msginfo.nent_id, - notif.nent_msginfo.nent_stringcount, - notif.nent_msginfo.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - #ifdef CSQC - if(notif.nent_msgannce) - if(notif.nent_msgannce.nent_enabled) - { - Local_Notification_WOVA( - MSG_ANNCE, - notif.nent_msgannce.nent_id, - 0, 0, - "", "", "", "", - 0, 0, 0, 0); - } - if(notif.nent_msgcenter) - if(notif.nent_msgcenter.nent_enabled) - { - Local_Notification_WOVA( - MSG_CENTER, - notif.nent_msgcenter.nent_id, - notif.nent_msgcenter.nent_stringcount, - notif.nent_msgcenter.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - #endif - break; - } - - case MSG_CHOICE: - { - entity found_choice; - - if(notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) - { - switch(cvar(sprintf("notification_%s", notif.nent_name))) - { - case 1: found_choice = notif.nent_optiona; break; - case 2: found_choice = notif.nent_optionb; break; - default: return; // not enabled anyway - } - } - else { found_choice = notif.nent_optiona; } - - Local_Notification_WOVA( - found_choice.nent_type, - found_choice.nent_id, - found_choice.nent_stringcount, - found_choice.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - } -} - -// WOVA = Without Variable Arguments -void Local_Notification_WOVA( - int net_type, float net_name, - float stringcount, float floatcount, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4) -{ - #define VARITEM(stringc,floatc,args) \ - if((stringcount == stringc) && (floatcount == floatc)) \ - { Local_Notification(net_type, net_name, args); return; } - EIGHT_VARS_TO_VARARGS_VARLIST - #undef VARITEM - Local_Notification(net_type, net_name); // some notifications don't have any arguments at all -} - - -// ========================= -// Notification Networking -// ========================= - -REGISTER_NET_LINKED(ENT_CLIENT_NOTIFICATION) - -#ifdef CSQC -NET_HANDLE(ENT_CLIENT_NOTIFICATION, bool is_new) -{ - int net_type = ReadByte(); - int net_name = ReadShort(); - return = true; - - entity notif; - - if(net_type == MSG_CENTER_CPID) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Read_Notification(%d) at %f: net_type = %s, net_name = %d\n", - is_new, - time, - Get_Notif_TypeName(net_type), - net_name - )); - #endif - - if(is_new) - { - if(net_name == 0) { reset_centerprint_messages(); } - else if(net_name != NO_CPID) - { - // in this case, net_name IS the cpid we want to kill - centerprint_generic(net_name, "", 0, 0); - } - else - { - backtrace(sprintf( - "Read_Notification(%d) at %f: ^1TRIED TO KILL NO_CPID CENTERPRINT!\n", - is_new, - time - )); - } - } - } - else - { - notif = Get_Notif_Ent(net_type, net_name); - if (!notif) { backtrace("Read_Notification: Could not find notification entity!\n"); return; } - - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Read_Notification(%d) at %f: net_type = %s, net_name = %s\n", - is_new, - time, - Get_Notif_TypeName(net_type), - notif.nent_name - )); - #endif - - string s1 = ((0 < notif.nent_stringcount) ? ReadString() : ""); - string s2 = ((1 < notif.nent_stringcount) ? ReadString() : ""); - string s3 = ((2 < notif.nent_stringcount) ? ReadString() : ""); - string s4 = ((3 < notif.nent_stringcount) ? ReadString() : ""); - float f1 = ((0 < notif.nent_floatcount) ? ReadLong() : 0); - float f2 = ((1 < notif.nent_floatcount) ? ReadLong() : 0); - float f3 = ((2 < notif.nent_floatcount) ? ReadLong() : 0); - float f4 = ((3 < notif.nent_floatcount) ? ReadLong() : 0); - - if(is_new) - { - Local_Notification_WOVA( - net_type, net_name, - notif.nent_stringcount, - notif.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - } -} -#endif - -#ifdef SVQC -void Net_Notification_Remove() -{SELFPARAM(); - if (!self) { backtrace(sprintf("Net_Notification_Remove() at %f: Missing self!?\n", time)); return; } - - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Net_Notification_Remove() at %f: %s '%s - %s' notification\n", - time, - ((self.nent_net_name == -1) ? "Killed" : "Removed"), - Get_Notif_TypeName(self.nent_net_type), - self.owner.nent_name - )); - #endif - - for(int i = 0; i < 4; ++i) { if(self.nent_strings[i]) { strunzone(self.nent_strings[i]); } } - remove(self); -} - -bool Net_Write_Notification(entity this, entity client, int sf) -{ - if(Notification_ShouldSend(self.nent_broadcast, client, self.nent_client)) - { - WriteHeader(MSG_ENTITY, ENT_CLIENT_NOTIFICATION); - WriteByte(MSG_ENTITY, self.nent_net_type); - WriteShort(MSG_ENTITY, self.nent_net_name); - for(int i = 0; i < self.nent_stringcount; ++i) { WriteString(MSG_ENTITY, self.nent_strings[i]); } - for(int i = 0; i < self.nent_floatcount; ++i) { WriteLong(MSG_ENTITY, self.nent_floats[i]); } - return true; - } - else { return false; } -} - -void Kill_Notification( - float broadcast, entity client, - float net_type, float net_name) -{ - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Kill_Notification(%s, '%s', %s, %d);\n", - Get_Notif_BroadcastName(broadcast), - client.netname, - (net_type ? Get_Notif_TypeName(net_type) : "0"), - net_name - )); - #endif - - string checkargs = Notification_CheckArgs(broadcast, client, 1, 1); - if(checkargs != "") { backtrace(sprintf("Incorrect usage of Kill_Notification: %s\n", checkargs)); return; } - - entity net_notif; - float killed_cpid = NO_CPID; - - switch(net_type) - { - case 0: - { - killed_cpid = 0; // kill ALL centerprints - break; - } - - case MSG_CENTER: - { - if(net_name) - { - entity notif = Get_Notif_Ent(net_type, net_name); - if (!notif) { backtrace("Kill_Notification: Could not find notification entity!\n"); return; } - - if(notif.nent_cpid) - killed_cpid = notif.nent_cpid; - else - killed_cpid = NO_CPID; - } - else - { - killed_cpid = 0; // kill ALL centerprints - } - break; - } - - case MSG_CENTER_CPID: - { - killed_cpid = net_name; - break; - } - } - - if(killed_cpid != NO_CPID) - { - net_notif = new(net_kill_notification); - make_pure(net_notif); - net_notif.nent_broadcast = broadcast; - net_notif.nent_client = client; - net_notif.nent_net_type = MSG_CENTER_CPID; - net_notif.nent_net_name = killed_cpid; - Net_LinkEntity(net_notif, false, autocvar_notification_lifetime_runtime, Net_Write_Notification); - } - - FOREACH_ENTITY_CLASS("net_notification", true, - { - if(net_type) - { - if((killed_cpid != NO_CPID) && (it.nent_net_type == MSG_CENTER)) - { - if(it.owner.nent_cpid == killed_cpid) - { - it.nent_net_name = -1; - it.nextthink = time; - } - else { continue; } // we ARE looking for a specific CPID, don't kill everything else too - } - else if(it.nent_net_type == net_type) - { - if(net_name) - { - if(it.nent_net_name == net_name) { it.nent_net_name = -1; it.nextthink = time; } - else { continue; } // we ARE looking for a certain net_name, don't kill everything else too - } - else { it.nent_net_name = -1; it.nextthink = time; } - } - else { continue; } // we ARE looking for a certain net_type, don't kill everything else too - } - else { it.nent_net_name = -1; it.nextthink = time; } - }); -} - -void Send_Notification( - float broadcast, entity client, - float net_type, float net_name, - ...count) -{ - // check if this should be aborted - if(net_name == NOTIF_ABORT) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Send_Notification(%s, '%s', %s, %s, ...);\n", - Get_Notif_BroadcastName(broadcast), - client.classname, - Get_Notif_TypeName(net_type), - "NOTIF_ABORT" - )); - #endif - return; - } - - // check supplied broadcast, target, type, and name for errors - string checkargs = Notification_CheckArgs(broadcast, client, net_type, net_name); - if(checkargs != "") - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Send_Notification(%s, '%s', %s, %s, ...);\n", - Get_Notif_BroadcastName(broadcast), - client.classname, - Get_Notif_TypeName(net_type), - Get_Notif_Ent(net_type, net_name).nent_name - )); - #endif - backtrace(sprintf("Incorrect usage of Send_Notification: %s\n", checkargs)); - return; - } - - // retreive entity of this notification - entity notif = Get_Notif_Ent(net_type, net_name); - if (!notif) - { - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Send_Notification(%s, '%s', %s, %d, ...);\n", - Get_Notif_BroadcastName(broadcast), - client.classname, - Get_Notif_TypeName(net_type), - net_name - )); - #endif - backtrace("Send_Notification: Could not find notification entity!\n"); - return; - } - - string s1 = ((0 < notif.nent_stringcount) ? ...(0, string) : ""); - string s2 = ((1 < notif.nent_stringcount) ? ...(1, string) : ""); - string s3 = ((2 < notif.nent_stringcount) ? ...(2, string) : ""); - string s4 = ((3 < notif.nent_stringcount) ? ...(3, string) : ""); - float f1 = ((0 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 0), float) : 0); - float f2 = ((1 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 1), float) : 0); - float f3 = ((2 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 2), float) : 0); - float f4 = ((3 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 3), float) : 0); - - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Send_Notification(%s, %s, %s);\n", - sprintf( - "%s, '%s', %s, %s", - Get_Notif_BroadcastName(broadcast), - client.classname, - Get_Notif_TypeName(net_type), - notif.nent_name - ), - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - if((notif.nent_stringcount + notif.nent_floatcount) > count) - { - string s = - #ifdef NOTIFICATIONS_DEBUG - Get_Notif_BroadcastName(broadcast); - #else - ftos(broadcast); - #endif - backtrace(sprintf( - strcat( - "Not enough arguments for Send_Notification(%s, ...)! ", - "stringcount(%d) + floatcount(%d) > count(%d)\n", - "Check the definition and function call for accuracy...?\n" - ), - sprintf( - "%s, '%s', %s, %s", - s, - client.classname, - Get_Notif_TypeName(net_type), - notif.nent_name - ), - notif.nent_stringcount, - notif.nent_floatcount, - count - )); - return; - } - else if((notif.nent_stringcount + notif.nent_floatcount) < count) - { - string s = - #ifdef NOTIFICATIONS_DEBUG - Get_Notif_BroadcastName(broadcast); - #else - ftos(broadcast); - #endif - backtrace(sprintf( - strcat( - "Too many arguments for Send_Notification(%s, ...)! ", - "stringcount(%d) + floatcount(%d) < count(%d)\n", - "Check the definition and function call for accuracy...?\n" - ), - sprintf( - "%s, '%s', %s, %s", - s, - client.classname, - Get_Notif_TypeName(net_type), - notif.nent_name - ), - notif.nent_stringcount, - notif.nent_floatcount, - count - )); - return; - } - - if( - server_is_dedicated - && - ( - broadcast == NOTIF_ALL - || - broadcast == NOTIF_ALL_EXCEPT - ) - && - !( - net_type == MSG_ANNCE - || - net_type == MSG_CENTER - ) - ) - { - Local_Notification_WOVA( - net_type, net_name, - notif.nent_stringcount, - notif.nent_floatcount, - s1, s2, s3, s4, - f1, f2, f3, f4); - } - - if(net_type == MSG_CHOICE) - { - // THIS GETS TRICKY... now we have to cycle through each possible player (checking broadcast) - // and then do an individual NOTIF_ONE_ONLY recursive call for each one depending on their option... - // It's slow, but it's better than the alternatives: - // 1. Constantly networking all info and letting client decide - // 2. Manually handling each separate call on per-usage basis (See old CTF usage of verbose) - entity found_choice; - - #define RECURSE_FROM_CHOICE(ent,action) MACRO_BEGIN { \ - if(notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) \ - { \ - switch(ent.msg_choice_choices[net_name - 1]) \ - { \ - case 1: found_choice = notif.nent_optiona; break; \ - case 2: found_choice = notif.nent_optionb; break; \ - default: action; \ - } \ - } \ - else { found_choice = notif.nent_optiona; } \ - Send_Notification_WOVA( \ - NOTIF_ONE_ONLY, \ - ent, \ - found_choice.nent_type, \ - found_choice.nent_id, \ - found_choice.nent_stringcount, \ - found_choice.nent_floatcount, \ - s1, s2, s3, s4, \ - f1, f2, f3, f4); \ - } MACRO_END - - switch(broadcast) - { - case NOTIF_ONE_ONLY: // we can potentially save processing power with this broadcast method - { - if(IS_REAL_CLIENT(client)) - { - RECURSE_FROM_CHOICE(client, return); - } - break; - } - default: - { - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA( - if(Notification_ShouldSend(broadcast, it, client)) - { - RECURSE_FROM_CHOICE(it, continue); - } - )); - break; - } - } - } - else - { - entity net_notif = new(net_notification); - make_pure(net_notif); - net_notif.owner = notif; - net_notif.nent_broadcast = broadcast; - net_notif.nent_client = client; - net_notif.nent_net_type = net_type; - net_notif.nent_net_name = net_name; - net_notif.nent_stringcount = notif.nent_stringcount; - net_notif.nent_floatcount = notif.nent_floatcount; - - for(int i = 0; i < net_notif.nent_stringcount; ++i) - { net_notif.nent_strings[i] = strzone(...(i, string)); } - for(int i = 0; i < net_notif.nent_floatcount; ++i) - { net_notif.nent_floats[i] = ...((net_notif.nent_stringcount + i), float); } - - net_notif.think = Net_Notification_Remove; - net_notif.nextthink = - ((time > autocvar_notification_lifetime_mapload) - ? - (time + autocvar_notification_lifetime_runtime) - : - autocvar_notification_lifetime_mapload - ); - - Net_LinkEntity(net_notif, false, 0, Net_Write_Notification); - } -} - -// WOVA = Without Variable Arguments -void Send_Notification_WOVA( - float broadcast, entity client, - float net_type, float net_name, - float stringcount, float floatcount, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4) -{ - #ifdef NOTIFICATIONS_DEBUG - entity notif = Get_Notif_Ent(net_type, net_name); - Debug_Notification(sprintf( - "Send_Notification_WOVA(%s, %d, %d, %s, %s);\n", - sprintf( - "%s, '%s', %s, %s", - Get_Notif_BroadcastName(broadcast), - client.classname, - Get_Notif_TypeName(net_type), - notif.nent_name - ), - stringcount, - floatcount, - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - #define VARITEM(stringc,floatc,args) \ - if((stringcount == stringc) && (floatcount == floatc)) \ - { Send_Notification(broadcast, client, net_type, net_name, args); return; } - EIGHT_VARS_TO_VARARGS_VARLIST - #undef VARITEM - Send_Notification(broadcast, client, net_type, net_name); // some notifications don't have any arguments at all -} - -// WOCOVA = Without Counts Or Variable Arguments -void Send_Notification_WOCOVA( - float broadcast, entity client, - float net_type, float net_name, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4) -{ - entity notif = Get_Notif_Ent(net_type, net_name); - - #ifdef NOTIFICATIONS_DEBUG - Debug_Notification(sprintf( - "Send_Notification_WOCOVA(%s, %s, %s);\n", - sprintf( - "%s, '%s', %s, %s", - Get_Notif_BroadcastName(broadcast), - client.classname, - Get_Notif_TypeName(net_type), - notif.nent_name - ), - MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), - sprintf("%d, %d, %d, %d", f1, f2, f3, f4) - )); - #endif - - #define VARITEM(stringc,floatc,args) \ - if((notif.nent_stringcount == stringc) && (notif.nent_floatcount == floatc)) \ - { Send_Notification(broadcast, client, net_type, net_name, args); return; } - EIGHT_VARS_TO_VARARGS_VARLIST - #undef VARITEM - Send_Notification(broadcast, client, net_type, net_name); // some notifications don't have any arguments at all -} -#endif // ifdef SVQC diff --git a/qcsrc/common/notifications.qh b/qcsrc/common/notifications.qh deleted file mode 100644 index 1b27775d4..000000000 --- a/qcsrc/common/notifications.qh +++ /dev/null @@ -1,923 +0,0 @@ -#ifndef NOTIFICATIONS_H -#define NOTIFICATIONS_H - -#include - -#include "constants.qh" -#include "teams.qh" -#include "util.qh" - -// ================================================ -// Unified notification system, written by Samual -// Last updated: March, 2013 -// ================================================ - -// main types/groups of notifications -const int MSG_ANNCE = 1; // "Global" AND "personal" announcer messages -const int MSG_INFO = 2; // "Global" information messages -const int MSG_CENTER = 3; // "Personal" centerprint messages -const int MSG_CENTER_CPID = 4; // Kill centerprint message -const int MSG_MULTI = 5; // Subcall MSG_INFO and/or MSG_CENTER notifications -const int MSG_CHOICE = 6; // Choose which subcall wrapper to activate - -// negative confirmations -const int NO_MSG = -12345; // allows various things to know when no information is added -const int NOTIF_ABORT = -1234; // allows Send_Notification to safely abort sending - -#define EIGHT_VARS_TO_VARARGS_VARLIST \ - VARITEM(1, 0, s1) \ - VARITEM(2, 0, XPD(s1, s2)) \ - VARITEM(3, 0, XPD(s1, s2, s3)) \ - VARITEM(4, 0, XPD(s1, s2, s3, s4)) \ - VARITEM(0, 1, f1) \ - VARITEM(1, 1, XPD(s1, f1)) \ - VARITEM(2, 1, XPD(s1, s2, f1)) \ - VARITEM(3, 1, XPD(s1, s2, s3, f1)) \ - VARITEM(4, 1, XPD(s1, s2, s3, s4, f1)) \ - VARITEM(0, 2, XPD(f1, f2)) \ - VARITEM(1, 2, XPD(s1, f1, f2)) \ - VARITEM(2, 2, XPD(s1, s2, f1, f2)) \ - VARITEM(3, 2, XPD(s1, s2, s3, f1, f2)) \ - VARITEM(4, 2, XPD(s1, s2, s3, s4, f1, f2)) \ - VARITEM(0, 3, XPD(f1, f2, f3)) \ - VARITEM(1, 3, XPD(s1, f1, f2, f3)) \ - VARITEM(2, 3, XPD(s1, s2, f1, f2, f3)) \ - VARITEM(3, 3, XPD(s1, s2, s3, f1, f2, f3)) \ - VARITEM(4, 3, XPD(s1, s2, s3, s4, f1, f2, f3)) \ - VARITEM(0, 4, XPD(f1, f2, f3, f4)) \ - VARITEM(1, 4, XPD(s1, f1, f2, f3, f4)) \ - VARITEM(2, 4, XPD(s1, s2, f1, f2, f3, f4)) \ - VARITEM(3, 4, XPD(s1, s2, s3, f1, f2, f3, f4)) \ - VARITEM(4, 4, XPD(s1, s2, s3, s4, f1, f2, f3, f4)) - -void Destroy_All_Notifications(); -void Create_Notification_Entity( - float var_default, - float var_cvar, - float typeId, - float nameid, - string namestring, - int strnum, - int flnum, - /* MSG_ANNCE */ - float channel, - string snd, - float vol, - float position, - /* MSG_INFO & MSG_CENTER */ - string args, - string hudargs, - string icon, - float cpid, - string durcnt, - string normal, - string gentle, - /* MSG_MULTI */ - float anncename, - float infoname, - float centername, - /* MSG_CHOICE */ - float challow_def, - float challow_var, - float chtype, - float optiona, - float optionb); - -void Dump_Notifications(float fh, float alsoprint); - - -GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt") -{ - switch(request) - { - case CMD_REQUEST_COMMAND: - { - #ifndef MENUQC - float fh, alsoprint = false; - string filename = argv(1); - - if(filename == "") - { - filename = "notifications_dump.cfg"; - alsoprint = false; - } - else if(filename == "-") - { - filename = "notifications_dump.cfg"; - alsoprint = true; - } - fh = fopen(filename, FILE_WRITE); - - if(fh >= 0) - { - Dump_Notifications(fh, alsoprint); - LOG_INFOF("Dumping notifications... File located in ^2data/data/%s^7.\n", filename); - fclose(fh); - } - else - { - LOG_INFOF("^1Error: ^7Could not open file '%s'!\n", filename); - } - #else - LOG_INFO(_("Notification dump command only works with cl_cmd and sv_cmd.\n")); - #endif - return; - } - - default: - case CMD_REQUEST_USAGE: - { - LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpnotifs [filename]")); - LOG_INFO(" Where 'filename' is the file to write (default is notifications_dump.cfg),\n"); - LOG_INFO(" if supplied with '-' output to console as well as default,\n"); - LOG_INFO(" if left blank, it will only write to default.\n"); - return; - } - } -} - -#ifdef NOTIFICATIONS_DEBUG -void Debug_Notification(string input); -#endif - -void Local_Notification(int net_type, int net_name, ...count); -void Local_Notification_WOVA( - float net_type, float net_name, - float stringcount, float floatcount, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4); - -#ifdef CSQC // CLIENT ONLY -string prev_soundfile; -float prev_soundtime; -#endif - -#ifdef SVQC // SERVER ONLY -const float NOTIF_ONE = 1; -const float NOTIF_ONE_ONLY = 2; -const float NOTIF_TEAM = 3; -const float NOTIF_TEAM_EXCEPT = 4; -const float NOTIF_ALL = 5; -const float NOTIF_ALL_EXCEPT = 6; - -void Kill_Notification( - float broadcast, entity client, - float net_type, float net_name); -void Send_Notification( - float broadcast, entity client, - float net_type, float net_name, - ...count); -void Send_Notification_WOVA( - float broadcast, entity client, - float net_type, float net_name, - float stringcount, float floatcount, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4); -void Send_Notification_WOCOVA( - float broadcast, entity client, - float net_type, float net_name, - string s1, string s2, string s3, string s4, - float f1, float f2, float f3, float f4); -#endif - -// =========================== -// Special CVAR Declarations -// =========================== - -// MAKE SURE THIS IS ALWAYS SYNCHRONIZED WITH THE DUMP -// NOTIFICATIONS FUNCTION IN THE .QC FILE! - -#define NOTIF_ADD_AUTOCVAR(name,default) float autocvar_notification_##name = default; - -float autocvar_notification_show_location = false; -string autocvar_notification_show_location_string = ""; //_(" at the %s"); -float autocvar_notification_show_sprees = true; -float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker -float autocvar_notification_show_sprees_info_newline = true; -float autocvar_notification_show_sprees_info_specialonly = true; -float autocvar_notification_errors_are_fatal = true; -float autocvar_notification_lifetime_runtime = 0.5; -float autocvar_notification_lifetime_mapload = 10; -float autocvar_notification_debug = false; - -#ifdef SVQC -.float FRAG_VERBOSE; -void Notification_GetCvars(); -float autocvar_notification_server_allows_location = 1; // 0 = no, 1 = yes -#else -float autocvar_notification_item_centerprinttime = 1.5; - -// 0 = no, 1 = yes, 2 = forced on for all MSG_INFO notifs -// DISABLED IN CODE, BUT ENABLED IN CONFIG FOR COMPATIBILITY WITH OLD CLIENTS -float autocvar_notification_allow_chatboxprint = 0; - -float autocvar_notification_show_sprees_center = true; -float autocvar_notification_show_sprees_center_specialonly = true; -#endif - - -// ============================ -// Notification Argument List -// ============================ -/* - These arguments get replaced with the Local_Notification_sprintf - and other such functions found in notifications.qc to supply data - from networked notifications to their usage in sprintf... It - allows for more dynamic data to be inferred by the local - notification parser, so that the server does not have to network - anything too crazy on a per-client/per-situation basis. - - Pay attention to the CSQC/SVQC relations, some of these are redefined - in slightly different ways for different programs, this is because the - server does a more conservative approach to the notifs than the client. - - All arguments are swapped into strings, so be sure that your - sprintf usage matches with proper %s placement. - - Argument descriptions: - s1-s4: string arguments to be literally swapped into sprintf - s2loc: s2 string of locations of deaths or other events - s3loc: s3 string of locations of deaths or other events - f1-f4: float arguments expanded into strings to be swapped into sprintf - f1p2dec: f1 float to string with 2 decimal places - f2p2dec: f2 float to string with 2 decimal places - f2primsec: f2 float primary or secondary selection for weapons - f3primsec: f3 float primary or secondary selection for weapons - f1secs: count_seconds of f1 - f1points: point or points depending on f1 - f1ord: count_ordinal of f1 - f1time: process_time of f1 - f1race_time: mmssss of f1 - f2race_time: mmssss of f2 - race_col: color of race time/position (i.e. good or bad) - race_diff: show time difference between f2 and f3 - missing_teams: show which teams still need players - pass_key: find the keybind for "passing" or "dropping" in CTF game mode - frag_ping: show the ping of a player - frag_stats: show health/armor/ping of a player - frag_pos: show score status and position in the match of a player - spree_cen: centerprint notif for kill spree/how many kills they have - spree_inf: info notif for kill spree/how many kills they have - spree_end: placed at the end of murder messages to show ending of sprees - spree_lost: placed at the end of suicide messages to show losing of sprees - item_wepname: return full name of a weapon from weaponid - item_wepammo: ammo display for weapon from string - item_centime: amount of time to display weapon message in centerprint - item_buffname: return full name of a buff from buffid - death_team: show the full name of the team a player is switching from - minigame1_name: return human readable name of a minigame from its id(s1) - minigame1_d: return descriptor name of a minigame from its id(s1) -*/ - -const float NOTIF_MAX_ARGS = 7; -const float NOTIF_MAX_HUDARGS = 2; -const float NOTIF_MAX_DURCNT = 2; - -string arg_slot[NOTIF_MAX_ARGS]; - -const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs -const float ARG_CS_SV_DC = 2; // enabled on CSQC, SVQC, and durcnt centerprint -const float ARG_CS_SV = 3; // enabled on CSQC and SVQC -const float ARG_CS = 4; // unique result to CSQC -const float ARG_SV = 5; // unique result to SVQC -const float ARG_DC = 6; // unique result to durcnt/centerprint - -// todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input -// this way, we don't need to have duplicates like i.e. s2loc and s3loc? - -string BUFF_NAME(int i); - -#define NOTIF_ARGUMENT_LIST \ - ARG_CASE(ARG_CS_SV_HA, "s1", s1) \ - ARG_CASE(ARG_CS_SV_HA, "s2", s2) \ - ARG_CASE(ARG_CS_SV_HA, "s3", s3) \ - ARG_CASE(ARG_CS_SV_HA, "s4", s4) \ - ARG_CASE(ARG_CS_SV, "s2loc", ((autocvar_notification_show_location && (s2 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s2) : "")) \ - ARG_CASE(ARG_CS_SV, "s3loc", ((autocvar_notification_show_location && (s3 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s3) : "")) \ - ARG_CASE(ARG_CS_SV_DC, "f1", ftos(f1)) \ - ARG_CASE(ARG_CS_SV_DC, "f2", ftos(f2)) \ - ARG_CASE(ARG_CS_SV, "f3", ftos(f3)) \ - ARG_CASE(ARG_CS_SV, "f4", ftos(f4)) \ - ARG_CASE(ARG_CS_SV, "f1p2dec", ftos_decimals(f1/100, 2)) \ - ARG_CASE(ARG_CS_SV, "f2p2dec", ftos_decimals(f2/100, 2)) \ - ARG_CASE(ARG_CS, "f2primsec", (f2 ? _("secondary") : _("primary"))) \ - ARG_CASE(ARG_CS, "f3primsec", (f3 ? _("secondary") : _("primary"))) \ - ARG_CASE(ARG_CS, "f1secs", count_seconds(f1)) \ - ARG_CASE(ARG_CS, "f1points", (f1 == 1 ? _("point") : _("points"))) \ - ARG_CASE(ARG_CS_SV, "f1ord", count_ordinal(f1)) \ - ARG_CASE(ARG_CS, "f1time", process_time(2, f1)) \ - ARG_CASE(ARG_CS_SV_HA, "f1race_time", mmssss(f1)) \ - ARG_CASE(ARG_CS_SV_HA, "f2race_time", mmssss(f2)) \ - ARG_CASE(ARG_CS_SV_HA, "f3race_time", mmssss(f3)) \ - ARG_CASE(ARG_CS_SV, "race_col", CCR(((f1 == 1) ? "^F1" : "^F2"))) \ - ARG_CASE(ARG_CS_SV, "race_diff", ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2)))) \ - ARG_CASE(ARG_CS, "missing_teams", notif_arg_missing_teams(f1)) \ - ARG_CASE(ARG_CS, "pass_key", ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \ - ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(true, f2)) \ - ARG_CASE(ARG_CS, "frag_stats", notif_arg_frag_stats(f2, f3, f4)) \ - /*ARG_CASE(ARG_CS, "frag_pos", ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \ - ARG_CASE(ARG_CS, "spree_cen", (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \ - ARG_CASE(ARG_CS_SV, "spree_inf", (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \ - ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \ - ARG_CASE(ARG_CS_SV, "spree_lost", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \ - ARG_CASE(ARG_CS_SV, "item_wepname", Weapons_from(f1).m_name) \ - ARG_CASE(ARG_CS_SV, "item_buffname", BUFF_NAME(f1)) \ - ARG_CASE(ARG_CS_SV, "f3buffname", BUFF_NAME(f3)) \ - ARG_CASE(ARG_CS_SV, "item_wepammo", (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \ - ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \ - ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \ - ARG_CASE(ARG_CS, "death_team", Team_ColoredFullName(f1 - 1)) \ - ARG_CASE(ARG_CS_SV_HA, "minigame1_name",find(world,netname,s1).descriptor.message) \ - ARG_CASE(ARG_CS_SV_HA, "minigame1_d", find(world,netname,s1).descriptor.netname) - -#define NOTIF_HIT_MAX(count,funcname) MACRO_BEGIN { \ - if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; } \ -} MACRO_END -#define NOTIF_HIT_UNKNOWN(token,funcname) { backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); break; } - -#define KILL_SPREE_LIST \ - SPREE_ITEM(3, 03, _("TRIPLE FRAG! "), _("%s^K1 made a TRIPLE FRAG! %s^BG"), _("%s^K1 made a TRIPLE SCORE! %s^BG")) \ - SPREE_ITEM(5, 05, _("RAGE! "), _("%s^K1 unlocked RAGE! %s^BG"), _("%s^K1 made FIVE SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(10, 10, _("MASSACRE! "), _("%s^K1 started a MASSACRE! %s^BG"), _("%s^K1 made TEN SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(15, 15, _("MAYHEM! "), _("%s^K1 executed MAYHEM! %s^BG"), _("%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(20, 20, _("BERSERKER! "), _("%s^K1 is a BERSERKER! %s^BG"), _("%s^K1 made TWENTY SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(25, 25, _("CARNAGE! "), _("%s^K1 inflicts CARNAGE! %s^BG"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG")) \ - SPREE_ITEM(30, 30, _("ARMAGEDDON! "), _("%s^K1 unleashes ARMAGEDDON! %s^BG"), _("%s^K1 made THIRTY SCORES IN A ROW! %s^BG")) - -#ifdef CSQC -string notif_arg_frag_ping(float newline, float fping) -{ - if(fping == NO_MSG) - return sprintf(CCR(_("%s(^F1Bot^BG)")), (newline ? "\n" : " ")); - else - return sprintf(CCR(_("%s(Ping ^F1%d^BG)")), (newline ? "\n" : " "), fping); -} - -string notif_arg_frag_stats(float fhealth, float farmor, float fping) -{ - if (!(fhealth < 1)) - return sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), fhealth, farmor, notif_arg_frag_ping(false, fping)); - else - return sprintf(CCR(_("\n(^F4Dead^BG)%s")), notif_arg_frag_ping(false, fping)); -} - -string notif_arg_missing_teams(float f1) -{ - return sprintf("%s%s%s%s", - ((f1 & 1) ? - sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_1), ((f1 & (2 + 4 + 8)) ? ", " : "")) - : - "" - ), - ((f1 & 2) ? - sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_2), ((f1 & (4 + 8)) ? ", " : "")) - : - "" - ), - ((f1 & 4) ? - sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_3), ((f1 & 8) ? ", " : "")) - : - "" - ), - ((f1 & 8) ? - Team_ColoredFullName(NUM_TEAM_4) - : - "" - ) - ); -} - -string notif_arg_spree_cen(float spree) -{ - // 0 = off, 1 = target (but only for first victim) and attacker - if(autocvar_notification_show_sprees_center) - { - if(spree > 1) - { - #define SPREE_ITEM(counta,countb,center,normal,gentle) \ - case counta: { return normal_or_gentle(center, sprintf(_("%d score spree! "), spree)); } - - switch(spree) - { - KILL_SPREE_LIST - default: - { - if (!autocvar_notification_show_sprees_center_specialonly) - { - return - sprintf( - normal_or_gentle( - _("%d frag spree! "), - _("%d score spree! ") - ), - spree); - } - else { return ""; } // don't show spree information if it isn't an achievement - } - } - - #undef SPREE_ITEM - } - else if(spree == -1) // first blood - { - return normal_or_gentle(_("First blood! "), _("First score! ")); - } - else if(spree == -2) // first victim - { - return normal_or_gentle(_("First victim! "), _("First casualty! ")); - } - } - return ""; -} -#endif - -string notif_arg_spree_inf(float type, string input, string player, float spree) -{ - switch(type) - { - case 1: // attacker kill spree - { - // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker - // this conditional (& 2) is true for 2 and 3 - if(autocvar_notification_show_sprees_info & 2) - { - #ifdef CSQC - string spree_newline = - ( autocvar_notification_show_sprees_info_newline ? - ((substring(input, 0, 1) == "\{3}") ? "\n\{3}" : "\n") : "" ); - #else - string spree_newline = - (autocvar_notification_show_sprees_info_newline ? "\n" : ""); - #endif - - if(spree > 1) - { - #define SPREE_ITEM(counta,countb,center,normal,gentle) \ - case counta: { return sprintf(CCR(normal_or_gentle(normal, gentle)), player, spree_newline); } - - switch(spree) - { - KILL_SPREE_LIST - default: - { - if (!autocvar_notification_show_sprees_info_specialonly) - { - return - sprintf( - CCR(normal_or_gentle( - _("%s^K1 has %d frags in a row! %s^BG"), - _("%s^K1 made %d scores in a row! %s^BG") - )), - player, - spree, - spree_newline - ); - } - else { return ""; } // don't show spree information if it isn't an achievement - } - } - - #undef SPREE_ITEM - } - else if(spree == -1) // firstblood - { - return - sprintf( - CCR(normal_or_gentle( - _("%s^K1 drew first blood! %s^BG"), - _("%s^K1 got the first score! %s^BG") - )), - player, - spree_newline - ); - } - } - break; - } - - case -1: // kill spree ended - { - if((spree > 1) && (autocvar_notification_show_sprees_info & 1)) - { - return - sprintf(normal_or_gentle( - _(", ending their %d frag spree"), - _(", ending their %d score spree") - ), - spree - ); - } - break; - } - - case -2: // kill spree lost - { - if((spree > 1) && (autocvar_notification_show_sprees_info & 1)) - { - return - sprintf(normal_or_gentle( - _(", losing their %d frag spree"), - _(", losing their %d score spree") - ), - spree - ); - } - break; - } - } - return ""; -} - - -// ==================================== -// Initialization/Create Declarations -// ==================================== - -enum { - NO_CPID -, CPID_ASSAULT_ROLE -, CPID_ROUND -, CPID_CAMPCHECK -, CPID_CTF_CAPSHIELD -, CPID_CTF_LOWPRIO -, CPID_CTF_PASS -, CPID_STALEMATE -, CPID_NADES -, CPID_IDLING -, CPID_ITEM -, CPID_PREVENT_JOIN -, CPID_KEEPAWAY -, CPID_KEEPAWAY_WARN -, CPID_KEYHUNT -, CPID_KEYHUNT_OTHER -, CPID_LMS -, CPID_MISSING_TEAMS -, CPID_MISSING_PLAYERS -, CPID_INSTAGIB_FINDAMMO -, CPID_MOTD -, CPID_NIX -, CPID_ONSLAUGHT -, CPID_ONS_CAPSHIELD -, CPID_OVERTIME -, CPID_POWERUP -, CPID_RACE_FINISHLAP -, CPID_TEAMCHANGE -, CPID_TIMEOUT -, CPID_VEHICLES -, CPID_VEHICLES_OTHER -// always last -, NOTIF_CPID_COUNT -}; -// notification counts -const float NOTIF_FIRST = 1; -float NOTIF_ANNCE_COUNT; -float NOTIF_INFO_COUNT; -float NOTIF_CENTER_COUNT; -float NOTIF_MULTI_COUNT; -float NOTIF_CHOICE_COUNT; - -// notification limits -- INCREASE AS NECESSARY -const float NOTIF_ANNCE_MAX = 400; -const float NOTIF_INFO_MAX = 450; -const float NOTIF_CENTER_MAX = 350; -const float NOTIF_MULTI_MAX = 300; -const float NOTIF_CHOICE_MAX = 50; - -// notification entities -entity msg_annce_notifs[NOTIF_ANNCE_MAX]; -entity msg_info_notifs[NOTIF_INFO_MAX]; -entity msg_center_notifs[NOTIF_CENTER_MAX]; -entity msg_multi_notifs[NOTIF_MULTI_MAX]; -entity msg_choice_notifs[NOTIF_CHOICE_MAX]; - -// common notification entity values -.float nent_default; -.float nent_enabled; -.float nent_type; -.float nent_id; -.string nent_name; -.int nent_stringcount; -.int nent_floatcount; - -// MSG_ANNCE entity values -.float nent_channel; -.string nent_snd; -.float nent_vol; -.float nent_position; - -// MSG_INFO and MSG_CENTER entity values -.string nent_args; // used by both -.string nent_hudargs; // used by info -.string nent_icon; // used by info -.float nent_cpid; // used by center -.string nent_durcnt; // used by center -.string nent_string; // used by both - -// MSG_MULTI entity values -.entity nent_msgannce; -.entity nent_msginfo; -.entity nent_msgcenter; - -// MSG_CHOICE entity values -.float nent_challow_def; -.float nent_challow_var; -.entity nent_optiona; -.entity nent_optionb; - -// networked notification entity values -.float nent_broadcast; -.entity nent_client; -.float nent_net_type; -.float nent_net_name; -.string nent_strings[4]; -.float nent_floats[4]; - -// other notification properties -.float msg_choice_choices[NOTIF_CHOICE_MAX]; // set on each player containing MSG_CHOICE choices - -// initialization error detection -float notif_error; -float notif_global_error; - -#define MSG_ANNCE_NOTIF(default,name,channel,sound,volume,position) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - float name; \ - void RegisterNotification_##name() \ - { \ - SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_ANNCE_COUNT) \ - CHECK_MAX_COUNT(name, NOTIF_ANNCE_MAX, NOTIF_ANNCE_COUNT, "MSG_ANNCE") \ - Create_Notification_Entity( \ - /* COMMON ======================== */ \ - default, /* var_default */ \ - ACVNN(name), /* var_cvar */ \ - MSG_ANNCE, /* typeId */ \ - name, /* nameid */ \ - strtoupper(#name), /* namestring */ \ - NO_MSG, /* strnum */ \ - NO_MSG, /* flnum */ \ - /* ANNCE ============= */ \ - channel, /* channel */ \ - sound, /* snd */ \ - volume, /* vol */ \ - position, /* position */ \ - /* INFO & CENTER == */ \ - "", /* args */ \ - "", /* hudargs */ \ - "", /* icon */ \ - NO_MSG, /* cpid */ \ - "", /* durcnt */ \ - "", /* normal */ \ - "", /* gentle */ \ - /* MULTI ============= */ \ - NO_MSG, /* anncename */ \ - NO_MSG, /* infoname */ \ - NO_MSG, /* centername */ \ - /* MSG_CHOICE ========== */ \ - NO_MSG, /* challow_def */ \ - NO_MSG, /* challow_var */ \ - NO_MSG, /* chtype */ \ - NO_MSG, /* optiona */ \ - NO_MSG); /* optionb */ \ - } \ - ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name) - -#define MSG_INFO_NOTIF(default,name,strnum,flnum,args,hudargs,icon,normal,gentle) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - int name; \ - void RegisterNotification_##name() \ - { \ - SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \ - CHECK_MAX_COUNT(name, NOTIF_INFO_MAX, NOTIF_INFO_COUNT, "MSG_INFO") \ - Create_Notification_Entity( \ - /* COMMON ======================== */ \ - default, /* var_default */ \ - ACVNN(name), /* var_cvar */ \ - MSG_INFO, /* typeId */ \ - name, /* nameid */ \ - strtoupper(#name), /* namestring */ \ - strnum, /* strnum */ \ - flnum, /* flnum */ \ - /* ANNCE =========== */ \ - NO_MSG, /* channel */ \ - "", /* snd */ \ - NO_MSG, /* vol */ \ - NO_MSG, /* position */ \ - /* INFO & CENTER === */ \ - args, /* args */ \ - hudargs, /* hudargs */ \ - icon, /* icon */ \ - NO_MSG, /* cpid */ \ - "", /* durcnt */ \ - normal, /* normal */ \ - gentle, /* gentle */ \ - /* MULTI ============= */ \ - NO_MSG, /* anncename */ \ - NO_MSG, /* infoname */ \ - NO_MSG, /* centername */ \ - /* CHOICE ============== */ \ - NO_MSG, /* challow_def */ \ - NO_MSG, /* challow_var */ \ - NO_MSG, /* chtype */ \ - NO_MSG, /* optiona */ \ - NO_MSG); /* optionb */ \ - } \ - ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name) - -.string nent_iconargs; -#define MULTIICON_INFO(default,name,strnum,flnum,args,hudargs,iconargs,icon,normal,gentle) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - int name; \ - void RegisterNotification_##name() \ - { \ - SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_INFO_COUNT) \ - CHECK_MAX_COUNT(name, NOTIF_INFO_MAX, NOTIF_INFO_COUNT, "MSG_INFO") \ - Create_Notification_Entity( \ - /* COMMON ======================== */ \ - default, /* var_default */ \ - ACVNN(name), /* var_cvar */ \ - MSG_INFO, /* typeid */ \ - name, /* nameid */ \ - strtoupper(#name), /* namestring */ \ - strnum, /* strnum */ \ - flnum, /* flnum */ \ - /* ANNCE =========== */ \ - NO_MSG, /* channel */ \ - "", /* snd */ \ - NO_MSG, /* vol */ \ - NO_MSG, /* position */ \ - /* INFO & CENTER === */ \ - args, /* args */ \ - hudargs, /* hudargs */ \ - icon, /* icon */ \ - NO_MSG, /* cpid */ \ - "", /* durcnt */ \ - normal, /* normal */ \ - gentle, /* gentle */ \ - /* MULTI ============= */ \ - NO_MSG, /* anncename */ \ - NO_MSG, /* infoname */ \ - NO_MSG, /* centername */ \ - /* CHOICE ============== */ \ - NO_MSG, /* challow_def */ \ - NO_MSG, /* challow_var */ \ - NO_MSG, /* chtype */ \ - NO_MSG, /* optiona */ \ - NO_MSG); /* optionb */ \ - msg_info_notifs[name - 1].nent_iconargs = iconargs; \ - } \ - ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name) - -#define MSG_CENTER_NOTIF(default,name,strnum,flnum,args,cpid,durcnt,normal,gentle) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - float name; \ - void RegisterNotification_##name() \ - { \ - SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CENTER_COUNT) \ - CHECK_MAX_COUNT(name, NOTIF_CENTER_MAX, NOTIF_CENTER_COUNT, "MSG_CENTER") \ - Create_Notification_Entity( \ - /* COMMON ======================== */ \ - default, /* var_default */ \ - ACVNN(name), /* var_cvar */ \ - MSG_CENTER, /* typeId */ \ - name, /* nameid */ \ - strtoupper(#name), /* namestring */ \ - strnum, /* strnum */ \ - flnum, /* flnum */ \ - /* ANNCE =========== */ \ - NO_MSG, /* channel */ \ - "", /* snd */ \ - NO_MSG, /* vol */ \ - NO_MSG, /* position */ \ - /* INFO & CENTER == */ \ - args, /* args */ \ - "", /* hudargs */ \ - "", /* icon */ \ - cpid, /* cpid */ \ - durcnt, /* durcnt */ \ - normal, /* normal */ \ - gentle, /* gentle */ \ - /* MULTI ============= */ \ - NO_MSG, /* anncename */ \ - NO_MSG, /* infoname */ \ - NO_MSG, /* centername */ \ - /* CHOICE ============== */ \ - NO_MSG, /* challow_def */ \ - NO_MSG, /* challow_var */ \ - NO_MSG, /* chtype */ \ - NO_MSG, /* optiona */ \ - NO_MSG); /* optionb */ \ - } \ - ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name) - -#define MSG_MULTI_NOTIF(default,name,anncename,infoname,centername) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - int name; \ - void RegisterNotification_##name() \ - { \ - SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_MULTI_COUNT) \ - CHECK_MAX_COUNT(name, NOTIF_MULTI_MAX, NOTIF_MULTI_COUNT, "MSG_MULTI") \ - Create_Notification_Entity( \ - /* COMMON ======================== */ \ - default, /* var_default */ \ - ACVNN(name), /* var_cvar */ \ - MSG_MULTI, /* typeId */ \ - name, /* nameid */ \ - strtoupper(#name), /* namestring */ \ - NO_MSG, /* strnum */ \ - NO_MSG, /* flnum */ \ - /* ANNCE =========== */ \ - NO_MSG, /* channel */ \ - "", /* snd */ \ - NO_MSG, /* vol */ \ - NO_MSG, /* position */ \ - /* INFO & CENTER == */ \ - "", /* args */ \ - "", /* hudargs */ \ - "", /* icon */ \ - NO_MSG, /* cpid */ \ - "", /* durcnt */ \ - "", /* normal */ \ - "", /* gentle */ \ - /* MULTI ================= */ \ - anncename, /* anncename */ \ - infoname, /* infoname */ \ - centername, /* centername */ \ - /* CHOICE ============== */ \ - NO_MSG, /* challow_def */ \ - NO_MSG, /* challow_var */ \ - NO_MSG, /* chtype */ \ - NO_MSG, /* optiona */ \ - NO_MSG); /* optionb */ \ - } \ - ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name) - -#define ACVNN(name) autocvar_notification_##name - -#define MSG_CHOICE_NOTIF(default,challow,name,chtype,optiona,optionb) \ - NOTIF_ADD_AUTOCVAR(name, default) \ - NOTIF_ADD_AUTOCVAR(name##_ALLOWED, challow) \ - float name; \ - void RegisterNotification_##name() \ - { \ - SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_CHOICE_COUNT) \ - CHECK_MAX_COUNT(name, NOTIF_CHOICE_MAX, NOTIF_CHOICE_COUNT, "MSG_CHOICE") \ - Create_Notification_Entity( \ - /* COMMON ======================== */ \ - default, /* var_default */ \ - ACVNN(name), /* var_cvar */ \ - MSG_CHOICE, /* typeId */ \ - name, /* nameid */ \ - strtoupper(#name), /* namestring */ \ - NO_MSG, /* strnum */ \ - NO_MSG, /* flnum */ \ - /* ANNCE =========== */ \ - NO_MSG, /* channel */ \ - "", /* snd */ \ - NO_MSG, /* vol */ \ - NO_MSG, /* position */ \ - /* INFO & CENTER == */ \ - "", /* args */ \ - "", /* hudargs */ \ - "", /* icon */ \ - NO_MSG, /* cpid */ \ - "", /* durcnt */ \ - "", /* normal */ \ - "", /* gentle */ \ - /* MULTI ============= */ \ - NO_MSG, /* anncename */ \ - NO_MSG, /* infoname */ \ - NO_MSG, /* centername */ \ - /* CHOICE ============================================= */ \ - challow, /* challow_def */ \ - autocvar_notification_##name##_ALLOWED, /* challow_var */ \ - chtype, /* chtype */ \ - optiona, /* optiona */ \ - optionb); /* optionb */ \ - } \ - ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name) - -void RegisterNotifications_First() -{ - notif_global_error = false; -} - -void RegisterNotifications_Done() -{ - if(notif_global_error) - { - // shit happened... stop the loading of the program now if this is unacceptable - if(autocvar_notification_errors_are_fatal) - LOG_FATAL("Notification initialization failed! Read above and fix the errors!\n"); - else - LOG_SEVERE("Notification initialization failed! Read above and fix the errors!\n"); - } -} - -// NOW we actually activate the declarations -ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotifications_First) -#include "notifications.inc" -ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotifications_Done) - -STATIC_INIT(RegisterNotifications) { CALL_ACCUMULATED_FUNCTION(RegisterNotifications); } - -#endif diff --git a/qcsrc/common/notifications/all.inc b/qcsrc/common/notifications/all.inc new file mode 100644 index 000000000..e723b8933 --- /dev/null +++ b/qcsrc/common/notifications/all.inc @@ -0,0 +1,926 @@ +// ==================================== +// Notifications List and Information +// ==================================== +/* + List of all notifications (including identifiers and display information) + Possible Tokens: + default, name, strnum, flnum, + channel, sound, volume, position, + args, hudargs, icon, cpid, durcnt, normal, gentle, + anncename, infoname, centername, + challow, chtype, optiona, optionb + Format Specifications: + name: VAR: Name of notification + MSG_ANNCE: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = enabled if gentle is disabled, 2 = always enabled + sound: STRING: Filename for the announcement sound + channel: FLOAT: Sound channel to broadcast on to + volume: FLOAT: Volume setting for the announcement sound + position: FLOAT: Attenuation/positioning value + MSG_INFO: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = enabled, 2 = also print to chat box + strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive) + flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive) + args: STRING: Arguments for Local_Notification_sprintf() + hudargs: STRING: Arguments for Local_Notification_HUD_Notify_Push() + icon: STRING: icon string name for the hud notify panel, "" if no icon is used + normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled) + gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled) + MSG_CENTER: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = enabled + strnum: FLOAT: Number of STRING arguments (so that networking knows how many to send/receive) + flnum: FLOAT: Number of FLOAT arguments (so that networking knows how many to send/receive) + args: STRING: Arguments for Local_Notification_sprintf() + cpid: FLOAT: centerprint ID number (CPID_*), CPID_Null if no CPID is needed + durcnt: XPD(FLOAT, FLOAT): Duration/Countdown: extra arguments for centerprint messages + normal: STRING: Normal message (string for sprintf when gentle messages are NOT enabled) + gentle: STRING: Gentle message (string for sprintf when gentle messages ARE enabled) + MSG_MULTI: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = enabled + anncename: VAR: Name of announcer notification for reference + infoname: VAR: Name of info notification for reference + centername: VAR: Name of centerprint notification for reference + MSG_CHOICE: + default: FLOAT: Default setting for whether the notification is enabled or not + ^-> 0 = disabled, 1 = select option A, 2 = selection option B + challow: FLOAT: Default setting for server allowing choices other than A + ^-> 0 = no choice, 1 = allowed in warmup, 2 = always allowed + chtype: VAR: Notification message type for options + optiona: VAR: Name of choice "A" notification for reference + optionb: VAR: Name of choice "B" notification for reference + + Messages with ^F1, ^BG, ^TC, etc etc in them will replace those strings + with colors according to the cvars the user has chosen. This allows for + users to create unique color profiles for their HUD, giving more customization + options to HUD designers and end users who want such a feature. + + Check out the definitions in util.qc/util.qh/teams.qh for string CCR(...) and + string TCR(...) to better understand how these code replacements work. + + Additionally, you can find all the definitions and explanations for + the argument values and what they return down below in this file. + + Guidlines for notification declaration (please try and follow these): + Specific rules: + - ALWAYS start the string with a color, preferably background. + - ALWAYS reset a color after a name (this way they don't set it for the whole string). + - NEVER add or remove tokens from the format, it SHOULD already work. + - MSG_INFO hudargs must always be ATTACKER -> VICTIM + - MSG_INFO and MSG_CENTER should NOT end with a new line + + General rules: + - Be clean and simple with your notification naming, + nothing too long for the name field... Abbreviations are your friend. :D + - Keep the spacing as clean as possible... if the arguments are abnormally long, + it's okay to go out of line a bit... but try and keep it clean still. + - Use ONLY spaces for spacing in the notification list, tabs are too inconsistent + with keeping alignment on different mediums. + - Sort the notifications in the most appropriate order for their tasks. + + Final note: DO NOT PROVIDE MORE ARGUMENTS THAN NECESSARY FOR THE NOTIFICATION YOU'RE CALLING! + The system is designed to save as much networking bandwidth as possible, + so please dynamically control your argument sending to fit *exactly* what is required. + If you send a notification with mismatching arguments, Send_Notification() will error. +*/ + +#define MULTITEAM_ANNCE2(prefix, default, sound, channel, volume, position) \ + MSG_ANNCE_NOTIF(prefix##RED, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), channel, volume, position) \ + MSG_ANNCE_NOTIF(prefix##BLUE, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), channel, volume, position) +#define MULTITEAM_ANNCE3(prefix, default, sound, channel, volume, position) \ + MULTITEAM_ANNCE2(prefix, default, sound, channel, volume, position) \ + MSG_ANNCE_NOTIF(prefix##YELLOW, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_3)), channel, volume, position) +#define MULTITEAM_ANNCE4(prefix, default, sound, channel, volume, position) \ + MULTITEAM_ANNCE3(prefix, default, sound, channel, volume, position) \ + MSG_ANNCE_NOTIF(prefix##PINK, default, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), channel, volume, position) +#define MULTITEAM_ANNCE(prefix, teams, default, sound, channel, volume, position) \ + MULTITEAM_ANNCE##teams(prefix, default, sound, channel, volume, position) + +// MSG_ANNCE_NOTIFICATIONS + MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, 1, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, 1, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, 1, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, 1, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, 2, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, 1, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, 1, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(BEGIN, 2, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(KILLSTREAK_03, 1, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_05, 1, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_10, 1, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_15, 1, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_20, 1, "20kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_25, 1, "25kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(KILLSTREAK_30, 1, "30kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, 1, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, 1, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, 1, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(MULTIFRAG, 0, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_1, 2, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_2, 2, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_3, 2, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_4, 2, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_5, 2, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_6, 2, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_7, 2, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_8, 2, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_9, 2, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_10, 2, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_GAMESTART_1, 2, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_2, 2, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_3, 2, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_4, 2, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_5, 2, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_GAMESTART_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_IDLE_1, 0, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_2, 0, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_3, 0, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_IDLE_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_KILL_1, 0, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_2, 0, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_3, 0, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_KILL_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_RESPAWN_1, 0, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_2, 0, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_3, 0, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_RESPAWN_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, 2, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, 2, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, 2, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, 0, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, 0, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, 0, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, 0, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, 0, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, 0, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, 0, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(PREPARE, 2, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(REMAINING_FRAG_1, 1, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(REMAINING_FRAG_2, 1, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(REMAINING_FRAG_3, 1, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(REMAINING_MIN_1, 2, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(REMAINING_MIN_5, 2, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(TIMEOUT, 2, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + + MSG_ANNCE_NOTIF(VOTE_ACCEPT, 2, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(VOTE_CALL, 2, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + MSG_ANNCE_NOTIF(VOTE_FAIL, 2, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE) + +#define MULTITEAM_INFO2(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MSG_INFO_NOTIF(prefix##_RED, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ + MSG_INFO_NOTIF(prefix##_BLUE, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) +#define MULTITEAM_INFO3(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MULTITEAM_INFO2(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MSG_INFO_NOTIF(prefix##_YELLOW, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) +#define MULTITEAM_INFO4(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MULTITEAM_INFO3(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MSG_INFO_NOTIF(prefix##_PINK, default, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) +#define MULTITEAM_INFO(prefix, teams, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MULTITEAM_INFO##teams(prefix, default, strnum, flnum, args, hudargs, icon, normal, gentle) + +// MSG_INFO_NOTIFICATIONS + MSG_INFO_NOTIF(CHAT_NOSPECTATORS, 2, 0, 0, "", "", "", _("^F4NOTE: ^BGSpectator chat is not sent to players during the match"), "") + + MULTITEAM_INFO(CTF_CAPTURE, 4, 1, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag"), "") + MULTITEAM_INFO(CTF_CAPTURE_BROKEN, 4, 1, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds"), "") + MSG_INFO_NOTIF(CTF_CAPTURE_NEUTRAL, 1, 1, 0, "s1", "s1", "notify_neutral_captured", _("^BG%s^BG captured the flag"), "") + MULTITEAM_INFO(CTF_CAPTURE_TIME, 4, 1, 1, 1, "s1 f1p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "") + MULTITEAM_INFO(CTF_CAPTURE_UNBROKEN, 4, 1, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_ABORTRUN, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_ABORTRUN_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag was returned by its owner"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_DAMAGED, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_DAMAGED_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag was destroyed and returned to base"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_DROPPED, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_DROPPED_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag was dropped in the base and returned itself"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_NEEDKILL, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_NEEDKILL_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag fell somewhere it couldn't be reached and returned to base"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_SPEEDRUN, 4, 1, 0, 1, "f1p2dec", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_SPEEDRUN_NEUTRAL, 1, 0, 1, "f1p2dec", "", "", _("^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") + MULTITEAM_INFO(CTF_FLAGRETURN_TIMEOUT, 4, 1, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag has returned to the base"), "") + MSG_INFO_NOTIF(CTF_FLAGRETURN_TIMEOUT_NEUTRAL, 1, 0, 0, "", "", "", _("^BGThe flag has returned to the base"), "") + MULTITEAM_INFO(CTF_LOST, 4, 1, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag"), "") + MSG_INFO_NOTIF(CTF_LOST_NEUTRAL, 1, 1, 0, "s1", "s1", "notify_neutral_lost", _("^BG%s^BG lost the flag"), "") + MULTITEAM_INFO(CTF_PICKUP, 4, 1, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag"), "") + MSG_INFO_NOTIF(CTF_PICKUP_NEUTRAL, 1, 1, 0, "s1", "s1", "notify_neutral_taken", _("^BG%s^BG got the flag"), "") + MULTITEAM_INFO(CTF_RETURN, 4, 1, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") + MULTITEAM_INFO(CTF_RETURN_MONSTER, 4, 1, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") + + MSG_INFO_NOTIF(COINTOSS, 2, 1, 0, "s1", "", "", _("^F2Throwing coin... Result: %s^F2!"), "") + + MSG_INFO_NOTIF(JETPACK_NOFUEL, 1, 0, 0, "", "", "", _("^BGYou don't have any fuel for the ^F1Jetpack"), "") + + MSG_INFO_NOTIF(SUPERSPEC_MISSING_UID, 2, 0, 0, "", "", "", _("^F2You lack a UID, superspec options will not be saved/restored"), "") + + MSG_INFO_NOTIF(CA_JOIN_LATE, 1, 0, 0, "", "", "", _("^F1Round already started, you will join the game in the next round"), "") + MSG_INFO_NOTIF(CA_LEAVE, 1, 0, 0, "", "", "", _("^F2You will spectate in the next round"), "") + + MSG_INFO_NOTIF(DEATH_MURDER_BUFF, 1, 3, 3, "spree_inf s1 s2 f3buffname s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"), _("^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s")) + MSG_INFO_NOTIF(DEATH_MURDER_CHEAT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_DROWN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_water", _("^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_FALL, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_fall", _("^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_FIRE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"), _("^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s")) + MSG_INFO_NOTIF(DEATH_MURDER_LAVA, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_lava", _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_MONSTER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was pushed infront of a monster by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_NADE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_normal", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_NADE_NAPALM, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_napalm", _("^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"), _("^BG%s%s^K1 got too close to a napalm explosion%s%s")) + MSG_INFO_NOTIF(DEATH_MURDER_NADE_ICE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_NADE_ICE_FREEZE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_ice", _("^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_NADE_HEAL, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "nade_heal", _("^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_SHOOTING_STAR, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_shootingstar", _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_SLIME, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_SWAMP, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_TELEFRAG, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_telefrag", _("^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s"), _("^BG%s%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s")) + MSG_INFO_NOTIF(DEATH_MURDER_TOUCHEXPLODE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_BUMB_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_BUMB_GUN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_CRUSH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was crushed by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_RAPT_BOMB, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_RAPT_CANNON, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_RAPT_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_SPID_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_SPID_MINIGUN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_SPID_ROCKET, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_WAKI_DEATH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_WAKI_GUN, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VH_WAKI_ROCKET, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"), "") + MSG_INFO_NOTIF(DEATH_MURDER_VOID, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_void", _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"), "") + + MSG_INFO_NOTIF(DEATH_SELF_AUTOTEAMCHANGE, 1, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 was moved into the %s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_BETRAYAL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_teamkill_red", _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_CAMP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_camping", _("^BG%s^K1 thought they found a nice camping ground%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_CHEAT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 unfairly eliminated themself%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_CUSTOM, 1, 3, 1, "s1 s2 s3loc spree_lost", "s1", "notify_void", "^BG%s^K1 %s^K1%s%s", "") + MSG_INFO_NOTIF(DEATH_SELF_DROWN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_water", _("^BG%s^K1 couldn't catch their breath%s%s"), _("^BG%s^K1 was in the water for too long%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_FALL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_fall", _("^BG%s^K1 hit the ground with a crunch%s%s"), _("^BG%s^K1 hit the ground with a bit too much force%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_FIRE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 became a bit too crispy%s%s"), _("^BG%s^K1 felt a little hot%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_GENERIC, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 died%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_LAVA, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_lava", _("^BG%s^K1 turned into hot slag%s%s"), _("^BG%s^K1 found a hot place%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_MON_MAGE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was exploded by a Mage%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_SHAMBLER_CLAW, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1's innards became outwards by a Shambler%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_SHAMBLER_SMASH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was smashed by a Shambler%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_SHAMBLER_ZAP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was zapped to death by a Shambler%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_SPIDER, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was bitten by a Spider%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_WYVERN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was fireballed by a Wyvern%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_ZOMBIE_JUMP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 joins the Zombies%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_MON_ZOMBIE_MELEE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_NADE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_normal", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_NADE_NAPALM, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_napalm", _("^BG%s^K1 was burned to death by their own Napalm Nade%s%s"), _("^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_NADE_ICE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_NADE_ICE_FREEZE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_ice", _("^BG%s^K1 was frozen to death by their own Ice Nade%s%s"), _("^BG%s^K1 felt a little chilly%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_NADE_HEAL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "nade_heal", _("^BG%s^K1's Healing Nade didn't quite heal them%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_NOAMMO, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_outofammo", _("^BG%s^K1 died%s%s. What's the point of living without ammo?"), _("^BG%s^K1 ran out of ammo%s%s")) + MSG_INFO_NOTIF(DEATH_SELF_ROT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 rotted away%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_SHOOTING_STAR, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_shootingstar", _("^BG%s^K1 became a shooting star%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_SLIME, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_slime", _("^BG%s^K1 was slimed%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 couldn't take it anymore%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_SWAMP, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_slime", _("^BG%s^K1 is now preserved for centuries to come%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TEAMCHANGE, 1, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 switched to the %s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TOUCHEXPLODE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 died in an accident%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 ran into a turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_EWHEEL, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by an eWheel turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_FLAC, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught up in the FLAC turret fire%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_HELLION, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by a Hellion turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_HK, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 could not hide from the Hunter turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_MACHINEGUN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_MLRS, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_PHASER, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was phased out by a turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_PLASMA, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served some superheated plasma from a turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_TESLA, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was electrocuted by a Tesla turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_WALK_GUN, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got served a lead enrichment by a Walker turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_WALK_MELEE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was impaled by a Walker turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_TURRET_WALK_ROCKET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted away by a Walker turret%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_BUMB_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_CRUSH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was crushed by a vehicle%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_RAPT_BOMB, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was caught in a Raptor cluster bomb%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_RAPT_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Raptor explosion%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_SPID_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_SPID_ROCKET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_WAKI_DEATH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 got caught in the blast of a Racer explosion%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VH_WAKI_ROCKET, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"), "") + MSG_INFO_NOTIF(DEATH_SELF_VOID, 1, 3, 1, "s1 s2 s2loc spree_lost", "s1", "notify_void", "^BG%s^K1 %s^K1%s%s", "") + + MULTITEAM_INFO(DEATH_TEAMKILL, 4, 1, 3, 1, "s1 s2 s3loc spree_end", "s2 s1", "notify_teamkill_%s", _("^BG%s^K1 was betrayed by ^BG%s^K1%s%s"), "") + + MSG_INFO_NOTIF(DOMINATION_CAPTURE_TIME, 1, 2, 2, "s1 s2 f1 f1points f2", "", "", _("^BG%s^BG%s^BG (%s %s every %s seconds)"), "") + + MSG_INFO_NOTIF(FREEZETAG_FREEZE, 1, 2, 0, "s1 s2", "", "", _("^BG%s^K1 was frozen by ^BG%s"), "") + MSG_INFO_NOTIF(FREEZETAG_REVIVED, 1, 2, 0, "s1 s2", "", "", _("^BG%s^K3 was revived by ^BG%s"), "") + MSG_INFO_NOTIF(FREEZETAG_REVIVED_FALL, 1, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by falling"), "") + MSG_INFO_NOTIF(FREEZETAG_REVIVED_NADE, 1, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by their Nade explosion"), "") + MSG_INFO_NOTIF(FREEZETAG_AUTO_REVIVED, 1, 1, 1, "s1 f1", "", "", _("^BG%s^K3 was automatically revived after %s second(s)"), "") + MSG_INFO_NOTIF(FREEZETAG_SELF, 1, 1, 0, "s1", "", "", _("^BG%s^K1 froze themself"), "") + + MULTITEAM_INFO(ROUND_TEAM_WIN, 4, 1, 0, 0, "", "", "", _("^TC^TT^BG team wins the round"), "") + MSG_INFO_NOTIF(ROUND_PLAYER_WIN, 1, 1, 0, "s1", "", "", _("^BG%s^BG wins the round"), "") + MSG_INFO_NOTIF(ROUND_TIED, 1, 0, 0, "", "", "", _("^BGRound tied"), "") + MSG_INFO_NOTIF(ROUND_OVER, 1, 0, 0, "", "", "", _("^BGRound over, there's no winner"), "") + + MSG_INFO_NOTIF(GODMODE_OFF, 1, 0, 1, "f1", "", "", _("^BGGodmode saved you %s units of damage, cheater!"), "") + + MSG_INFO_NOTIF(ITEM_BUFF, 1, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG got the %s^BG buff!"), "") + MSG_INFO_NOTIF(ITEM_BUFF_LOST, 1, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG lost the %s^BG buff!"), "") + MSG_INFO_NOTIF(ITEM_BUFF_DROP, 1, 0, 1, "item_buffname", "", "", _("^BGYou dropped the %s^BG buff!"), "") + MSG_INFO_NOTIF(ITEM_BUFF_GOT, 1, 0, 1, "item_buffname", "", "", _("^BGYou got the %s^BG buff!"), "") + + MSG_INFO_NOTIF(ITEM_WEAPON_DONTHAVE, 0, 0, 1, "item_wepname", "", "", _("^BGYou do not have the ^F1%s"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_DROP, 0, 1, 1, "item_wepname item_wepammo", "", "", _("^BGYou dropped the ^F1%s^BG%s"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_GOT, 0, 0, 1, "item_wepname", "", "", _("^BGYou got the ^F1%s"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_NOAMMO, 0, 0, 1, "item_wepname", "", "", _("^BGYou don't have enough ammo for the ^F1%s"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_PRIMORSEC, 0, 0, 3, "item_wepname f2primsec f3primsec", "", "", _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") + MSG_INFO_NOTIF(ITEM_WEAPON_UNAVAILABLE, 0, 0, 1, "item_wepname", "", "", _("^F1%s^BG is ^F4not available^BG on this map"), "") + + MSG_INFO_NOTIF(CONNECTING, 1, 1, 0, "s1", "", "", _("^BG%s^BG is connecting..."), "") + MSG_INFO_NOTIF(JOIN_CONNECT, 2, 1, 0, "s1", "", "", _("^BG%s^F3 connected"), "") + MULTITEAM_INFO(JOIN_CONNECT_TEAM, 4, 2, 1, 0, "s1", "", "", _("^BG%s^F3 connected and joined the ^TC^TT team"), "") + MSG_INFO_NOTIF(JOIN_PLAY, 1, 1, 0, "s1", "", "", _("^BG%s^F3 is now playing"), "") + MULTITEAM_INFO(JOIN_PLAY_TEAM, 4, 2, 1, 0, "s1", "", "", _("^BG%s^F3 is now playing on the ^TC^TT team"), "") + + MSG_INFO_NOTIF(KEEPAWAY_DROPPED, 1, 1, 0, "s1", "s1", "notify_balldropped", _("^BG%s^BG has dropped the ball!"), "") + MSG_INFO_NOTIF(KEEPAWAY_PICKUP, 1, 1, 0, "s1", "s1", "notify_ballpickedup", _("^BG%s^BG has picked up the ball!"), "") + + MULTITEAM_INFO(KEYHUNT_CAPTURE, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG captured the keys for the ^TC^TT team"), "") + MULTITEAM_INFO(KEYHUNT_DROP, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG dropped the ^TC^TT Key"), "") + MULTITEAM_INFO(KEYHUNT_LOST, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG lost the ^TC^TT Key"), "") + MULTITEAM_INFO(KEYHUNT_PICKUP, 4, 1, 1, 0, "s1", "", "", _("^BG%s^BG picked up the ^TC^TT Key"), "") + + MSG_INFO_NOTIF(LMS_FORFEIT, 1, 1, 0, "s1", "", "", _("^BG%s^F3 forfeited"), "") + MSG_INFO_NOTIF(LMS_NOLIVES, 1, 1, 0, "s1", "", "", _("^BG%s^F3 has no more lives left"), "") + + MSG_INFO_NOTIF(MONSTERS_DISABLED, 1, 0, 0, "", "", "", _("^BGMonsters are currently disabled"), "") + + MSG_INFO_NOTIF(ONSLAUGHT_CAPTURE, 1, 2, 0, "s1 s2", "", "", _("^BG%s^BG captured %s^BG control point"), "") + MULTITEAM_INFO(ONSLAUGHT_CPDESTROYED, 4, 1, 2, 0, "s1 s2", "", "", _("^TC^TT^BG team %s^BG control point has been destroyed by %s"), "") + MULTITEAM_INFO(ONSLAUGHT_GENDESTROYED, 4, 1, 0, 0, "", "", "", _("^TC^TT^BG generator has been destroyed"), "") + MULTITEAM_INFO(ONSLAUGHT_GENDESTROYED_OVERTIME, 4, 1, 0, 0, "", "", "", _("^TC^TT^BG generator spontaneously combusted due to overtime!"), "") + + MSG_INFO_NOTIF(POWERUP_INVISIBILITY, 1, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Invisibility"), "") + MSG_INFO_NOTIF(POWERUP_SHIELD, 1, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Shield"), "") + MSG_INFO_NOTIF(POWERUP_SPEED, 1, 1, 0, "s1", "s1", "shield", _("^BG%s^K1 picked up Speed"), "") + MSG_INFO_NOTIF(POWERUP_STRENGTH, 1, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Strength"), "") + + MSG_INFO_NOTIF(QUIT_DISCONNECT, 2, 1, 0, "s1", "", "", _("^BG%s^F3 disconnected"), "") + MSG_INFO_NOTIF(QUIT_KICK_IDLING, 2, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked for idling"), "") + MSG_INFO_NOTIF(QUIT_KICK_SPECTATING, 1, 0, 0, "", "", "", _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "") + MSG_INFO_NOTIF(QUIT_SPECTATE, 1, 1, 0, "s1", "", "", _("^BG%s^F3 is now spectating"), "") + + MSG_INFO_NOTIF(RACE_ABANDONED, 1, 1, 0, "s1", "", "", _("^BG%s^BG has abandoned the race"), "") + MSG_INFO_NOTIF(RACE_FAIL_RANKED, 1, 1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1 f3race_time", "race_newfail", _("^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s"), "") + MSG_INFO_NOTIF(RACE_FAIL_UNRANKED, 1, 1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1 f3race_time", "race_newfail", _("^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s"), "") + MSG_INFO_NOTIF(RACE_FINISHED, 1, 1, 0, "s1", "", "", _("^BG%s^BG has finished the race"), "") + MSG_INFO_NOTIF(RACE_NEW_BROKEN, 1, 2, 3, "s1 s2 race_col f1ord race_col f2race_time race_diff", "s1 f2race_time", "race_newrankyellow", _("^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s"), "") + MSG_INFO_NOTIF(RACE_NEW_IMPROVED, 1, 1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1 f2race_time", "race_newtime", _("^BG%s^BG improved their %s%s^BG place record with %s%s %s"), "") + MSG_INFO_NOTIF(RACE_NEW_MISSING_UID, 1, 1, 1, "s1 f1race_time", "s1 f1race_time", "race_newfail", _("^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID and will be lost."), "") + MSG_INFO_NOTIF(RACE_NEW_SET, 1, 1, 2, "s1 race_col f1ord race_col f2race_time", "s1 f2race_time", "race_newrecordserver", _("^BG%s^BG set the %s%s^BG place record with %s%s"), "") + + MULTIICON_INFO(MINIGAME_INVITE, 1, 2, 0, "s2 minigame1_name s1", "s2", "minigame1_d", "minigames/%s/icon_notif", _("^F4You have been invited by ^BG%s^F4 to join their game of ^F2%s^F4 (^F1%s^F4)"), "") + + MULTITEAM_INFO(SCORES, 4, 1, 0, 0, "", "", "", _("^TC^TT ^BGteam scores!"), "") + + MSG_INFO_NOTIF(SPECTATE_WARNING, 1, 0, 1, "f1secs", "", "", _("^F2You have to become a player within the next %s, otherwise you will be kicked, because spectating isn't allowed at this time!"), "") + + MSG_INFO_NOTIF(SUPERWEAPON_PICKUP, 1, 1, 0, "s1", "s1", "superweapons", _("^BG%s^K1 picked up a Superweapon"), "") + + MSG_INFO_NOTIF(TEAMCHANGE_LARGERTEAM, 1, 0, 0, "", "", "", _("^BGYou cannot change to a larger team"), "") + MSG_INFO_NOTIF(TEAMCHANGE_NOTALLOWED, 1, 0, 0, "", "", "", _("^BGYou are not allowed to change teams"), "") + + MSG_INFO_NOTIF(VERSION_BETA, 2, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s"), "") + MSG_INFO_NOTIF(VERSION_OLD, 2, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"), "") + MSG_INFO_NOTIF(VERSION_OUTDATED, 2, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!"), "") + + MSG_INFO_NOTIF(WATERMARK, 1, 1, 0, "s1", "", "", _("^F3SVQC Build information: ^F4%s"), "") + + MSG_INFO_NOTIF(WEAPON_ACCORDEON_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ACCORDEON_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ARC_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponarc", _("^BG%s%s^K1 was electrocuted by ^BG%s^K1's Arc%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ARC_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponarc", _("^BG%s%s^K1 was blasted by ^BG%s^K1's Arc bolts%s%s"), "") + MSG_INFO_NOTIF(WEAPON_BLASTER_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponlaser", _("^BG%s%s^K1 was shot to death by ^BG%s^K1's Blaster%s%s"), "") + MSG_INFO_NOTIF(WEAPON_BLASTER_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponlaser", _("^BG%s^K1 shot themself to hell with their Blaster%s%s"), "") + MSG_INFO_NOTIF(WEAPON_CRYLINK_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponcrylink", _("^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s"), "") + MSG_INFO_NOTIF(WEAPON_CRYLINK_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponcrylink", _("^BG%s^K1 felt the strong pull of their Crylink%s%s"), "") + MSG_INFO_NOTIF(WEAPON_DEVASTATOR_MURDER_DIRECT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrocketlauncher", _("^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s"), "") + MSG_INFO_NOTIF(WEAPON_DEVASTATOR_MURDER_SPLASH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrocketlauncher", _("^BG%s%s^K1 got too close ^BG%s^K1's rocket%s%s"), "") + MSG_INFO_NOTIF(WEAPON_DEVASTATOR_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrocketlauncher", _("^BG%s^K1 blew themself up with their Devastator%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_MURDER_BOLT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_MURDER_COMBO, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_MURDER_ORBS, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponelectro", _("^BG%s%s^K1 got too close to ^BG%s^K1's Electro orb%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_SUICIDE_BOLT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponelectro", _("^BG%s^K1 played with Electro bolts%s%s"), "") + MSG_INFO_NOTIF(WEAPON_ELECTRO_SUICIDE_ORBS, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponelectro", _("^BG%s^K1 could not remember where they put their Electro orb%s%s"), "") + MSG_INFO_NOTIF(WEAPON_FIREBALL_MURDER_BLAST, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponfireball", _("^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s"), "") + MSG_INFO_NOTIF(WEAPON_FIREBALL_MURDER_FIREMINE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponfireball", _("^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s"), "") + MSG_INFO_NOTIF(WEAPON_FIREBALL_SUICIDE_BLAST, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponfireball", _("^BG%s^K1 should have used a smaller gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_FIREBALL_SUICIDE_FIREMINE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponfireball", _("^BG%s^K1 forgot about their firemine%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HAGAR_MURDER_BURST, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhagar", _("^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HAGAR_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhagar", _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HAGAR_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponhagar", _("^BG%s^K1 played with tiny Hagar rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HLAC_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhlac", _("^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HLAC_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponhlac", _("^BG%s^K1 got a little jumpy with their HLAC%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HMG_MURDER_SNIPE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhmg", _("^BG%s%s^K1 was sniped by ^BG%s^K1's Heavy Machine Gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HMG_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhmg", _("^BG%s%s^K1 was torn to bits by ^BG%s^K1's Heavy Machine Gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_HOOK_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponhook", _("^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s"), "") + MSG_INFO_NOTIF(WEAPON_KLEINBOTTLE_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s"), "") + MSG_INFO_NOTIF(WEAPON_KLEINBOTTLE_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MACHINEGUN_MURDER_SNIPE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponuzi", _("^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MACHINEGUN_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponuzi", _("^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MINELAYER_LIMIT, 1, 0, 1, "f1", "", "", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "") + MSG_INFO_NOTIF(WEAPON_MINELAYER_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponminelayer", _("^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MINELAYER_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponminelayer", _("^BG%s^K1 forgot about their mine%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MORTAR_MURDER_BOUNCE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapongrenadelauncher", _("^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MORTAR_MURDER_EXPLODE, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapongrenadelauncher", _("^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MORTAR_SUICIDE_BOUNCE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapongrenadelauncher", _("^BG%s^K1 didn't see their own Mortar grenade%s%s"), "") + MSG_INFO_NOTIF(WEAPON_MORTAR_SUICIDE_EXPLODE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapongrenadelauncher", _("^BG%s^K1 blew themself up with their own Mortar%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER_HAIL, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER_HAIL_PIERCING, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RIFLE_MURDER_PIERCING, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrifle", _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RPC_MURDER_DIRECT, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrpc", _("^BG%s%s^K1 was sawn in half by ^BG%s^K1's Rocket Propelled Chainsaw%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RPC_MURDER_SPLASH, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponrpc", _("^BG%s%s^K1 almost dodged ^BG%s^K1's Rocket Propelled Chainsaw%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RPC_SUICIDE_DIRECT, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrpc", _("^BG%s^K1 was sawn in half by their own Rocket Propelled Chainsaw%s%s"), "") + MSG_INFO_NOTIF(WEAPON_RPC_SUICIDE_SPLASH, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponrpc", _("^BG%s^K1 blew themself up with their Rocket Propelled Chainsaw%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_SPRAY, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponseeker", _("^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SEEKER_MURDER_TAG, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponseeker", _("^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SEEKER_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weaponseeker", _("^BG%s^K1 played with tiny Seeker rockets%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponshotgun", _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SHOCKWAVE_MURDER_SLAP, 1, 3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1", "notify_melee_shotgun", _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shockwave%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponshotgun", _("^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_SHOTGUN_MURDER_SLAP, 1, 3, 2, "spree_inf s2 s1 s3loc spree_end", "s2 s1", "notify_melee_shotgun", _("^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"), "") + MSG_INFO_NOTIF(WEAPON_THINKING_WITH_PORTALS, 1, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 is now thinking with portals%s%s"), "") + MSG_INFO_NOTIF(WEAPON_TUBA_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weapontuba", _("^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s"), "") + MSG_INFO_NOTIF(WEAPON_TUBA_SUICIDE, 1, 2, 1, "s1 s2loc spree_lost", "s1", "weapontuba", _("^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s"), "") + MSG_INFO_NOTIF(WEAPON_VAPORIZER_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponminstanex", _("^BG%s%s^K1 has been sublimated by ^BG%s^K1's Vaporizer%s%s"), "") + MSG_INFO_NOTIF(WEAPON_VORTEX_MURDER, 1, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "weaponnex", _("^BG%s%s^K1 has been vaporized by ^BG%s^K1's Vortex%s%s"), "") + +#define MULTITEAM_CENTER2(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MSG_CENTER_NOTIF(prefix##_RED, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \ + MSG_CENTER_NOTIF(prefix##_BLUE, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) +#define MULTITEAM_CENTER3(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MULTITEAM_CENTER2(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MSG_CENTER_NOTIF(prefix##_YELLOW, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) +#define MULTITEAM_CENTER4(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MULTITEAM_CENTER3(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MSG_CENTER_NOTIF(prefix##_PINK, default, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) +#define MULTITEAM_CENTER(prefix, teams, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MULTITEAM_CENTER##teams(prefix, default, strnum, flnum, args, cpid, durcnt, normal, gentle) + +// MSG_CENTER_NOTIFICATIONS + MSG_CENTER_NOTIF(ALONE, 1, 0, 0, "", CPID_Null, "0 0", _("^F4You are now alone!"), "") + + MSG_CENTER_NOTIF(ASSAULT_ATTACKING, 1, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are attacking!"), "") + MSG_CENTER_NOTIF(ASSAULT_DEFENDING, 1, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are defending!"), "") + + MSG_CENTER_NOTIF(COUNTDOWN_BEGIN, 1, 0, 0, "", CPID_ROUND, "2 0", _("^F4Begin!"), "") + MSG_CENTER_NOTIF(COUNTDOWN_GAMESTART, 1, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Game starts in ^COUNT"), "") + MSG_CENTER_NOTIF(COUNTDOWN_ROUNDSTART, 1, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Round starts in ^COUNT"), "") + MSG_CENTER_NOTIF(COUNTDOWN_ROUNDSTOP, 1, 0, 0, "", CPID_ROUND, "2 0", _("^F4Round cannot start"), "") + + MSG_CENTER_NOTIF(ROUND_TIED, 1, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound tied"), "") + MSG_CENTER_NOTIF(ROUND_OVER, 1, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound over, there's no winner"), "") + + MSG_CENTER_NOTIF(CAMPCHECK, 1, 0, 0, "", CPID_CAMPCHECK, "0 0", _("^F2Don't camp!"), "") + + MSG_CENTER_NOTIF(COINTOSS, 1, 1, 0, "s1", CPID_Null, "0 0", _("^F2Throwing coin... Result: %s^F2!"), "") + + MSG_CENTER_NOTIF(CTF_CAPTURESHIELD_FREE, 1, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") + MSG_CENTER_NOTIF(CTF_CAPTURESHIELD_INACTIVE, 1, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGThis flag is currently inactive"), "") + MSG_CENTER_NOTIF(CTF_CAPTURESHIELD_SHIELDED, 1, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now ^F1shielded^BG from the flag(s)\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") + MULTITEAM_CENTER(CTF_CAPTURE, 4, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") + MSG_CENTER_NOTIF(CTF_CAPTURE_NEUTRAL, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the flag!"), "") + MSG_CENTER_NOTIF(CTF_FLAG_THROW_PUNISH, 1, 0, 1, "f1secs", CPID_CTF_LOWPRIO, "0 0", _("^BGToo many flag throws! Throwing disabled for %s."), "") + MULTITEAM_CENTER(CTF_PASS_OTHER, 4, 1, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") + MSG_CENTER_NOTIF(CTF_PASS_OTHER_NEUTRAL, 1, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the flag to %s"), "") + MULTITEAM_CENTER(CTF_PASS_RECEIVED, 4, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the ^TC^TT^BG flag from %s"), "") + MSG_CENTER_NOTIF(CTF_PASS_RECEIVED_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the flag from %s"), "") + MSG_CENTER_NOTIF(CTF_PASS_REQUESTED, 1, 1, 0, "s1 pass_key", CPID_CTF_PASS, "0 0", _("^BG%s^BG requests you to pass the flag%s"), "") + MSG_CENTER_NOTIF(CTF_PASS_REQUESTING, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGRequesting %s^BG to pass you the flag"), "") + MULTITEAM_CENTER(CTF_PASS_SENT, 4, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the ^TC^TT^BG flag to %s"), "") + MSG_CENTER_NOTIF(CTF_PASS_SENT_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the flag to %s"), "") + MULTITEAM_CENTER(CTF_PICKUP, 4, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_NEUTRAL, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the flag!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_TEAM, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got your %steam^BG's flag, return it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_TEAM_ENEMY, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the %senemy^BG's flag, return it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_VERBOSE, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_NEUTRAL, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got the flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_TEAM, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got their flag! Retrieve it!"), "") + MSG_CENTER_NOTIF(CTF_PICKUP_ENEMY_TEAM_VERBOSE, 1, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"), "") + MULTITEAM_CENTER(CTF_PICKUP_TEAM, 4, 1, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"), "") + 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!"), "") + 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!"), "") + MULTITEAM_CENTER(CTF_RETURN, 4, 1, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou returned the ^TC^TT^BG 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!"), "") + + MSG_CENTER_NOTIF(DEATH_MURDER_FRAG, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K3%sYou fragged ^BG%s"), _("^K3%sYou scored against ^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K1%sYou were fragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED_VERBOSE, 1, 1, 4, "spree_cen s1 frag_stats", CPID_Null, "0 0", _("^K1%sYou were fragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_VERBOSE, 1, 1, 2, "spree_cen s1 frag_ping", CPID_Null, "0 0", _("^K3%sYou fragged ^BG%s^BG%s"), _("^K3%sYou scored against ^BG%s^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAG, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K1%sYou typefragged ^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing")) + MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAGGED, 1, 1, 1, "spree_cen s1", CPID_Null, "0 0", _("^K1%sYou were typefragged by ^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing!")) + MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAGGED_VERBOSE, 1, 1, 4, "spree_cen s1 frag_stats", CPID_Null, "0 0", _("^K1%sYou were typefragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing^BG%s")) + MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAG_VERBOSE, 1, 1, 2, "spree_cen s1 frag_ping", CPID_Null, "0 0", _("^K1%sYou typefragged ^BG%s^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing^BG%s")) + + MSG_CENTER_NOTIF(NADE_THROW, 1, 0, 0, "", CPID_NADES, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the nade!"), "") + MSG_CENTER_NOTIF(NADE_BONUS, 1, 0, 0, "", CPID_NADES, "0 0", _("^F2You got a ^K1BONUS GRENADE^F2!"), "") + + MSG_CENTER_NOTIF(DEATH_SELF_AUTOTEAMCHANGE, 1, 0, 1, "death_team", CPID_Null, "0 0", _("^BGYou have been moved into a different team\nYou are now on: %s"), "") + MSG_CENTER_NOTIF(DEATH_SELF_BETRAYAL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Don't shoot your team mates!"), _("^K1Don't go against your team mates!")) + MSG_CENTER_NOTIF(DEATH_SELF_CAMP, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Die camper!"), _("^K1Reconsider your tactics, camper!")) + MSG_CENTER_NOTIF(DEATH_SELF_CHEAT, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You unfairly eliminated yourself!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_CUSTOM, 1, 2, 0, "s2", CPID_Null, "0 0", _("^K1You were %s"), "") + MSG_CENTER_NOTIF(DEATH_SELF_DROWN, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You couldn't catch your breath!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_FALL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You hit the ground with a crunch!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_FIRE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got a little bit too crispy!"), _("^K1You felt a little too hot!")) + MSG_CENTER_NOTIF(DEATH_SELF_GENERIC, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You killed your own dumb self!"), _("^K1You need to be more careful!")) + MSG_CENTER_NOTIF(DEATH_SELF_LAVA, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You couldn't stand the heat!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_MONSTER, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were killed by a monster!"), _("^K1You need to watch out for monsters!")) + MSG_CENTER_NOTIF(DEATH_SELF_NADE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You forgot to put the pin back in!"), _("^K1Tastes like chicken!")) + MSG_CENTER_NOTIF(DEATH_SELF_NADE_NAPALM, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Hanging around a napalm explosion is bad!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_NADE_ICE_FREEZE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got a little bit too cold!"), _("^K1You felt a little chilly!")) + MSG_CENTER_NOTIF(DEATH_SELF_NADE_HEAL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Your Healing Nade is a bit defective"), "") + MSG_CENTER_NOTIF(DEATH_SELF_NOAMMO, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were killed for running out of ammo..."), _("^K1You are respawning for running out of ammo...")) + MSG_CENTER_NOTIF(DEATH_SELF_ROT, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You grew too old without taking your medicine"), _("^K1You need to preserve your health")) + MSG_CENTER_NOTIF(DEATH_SELF_SHOOTING_STAR, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You became a shooting star!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_SLIME, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You melted away in slime!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_SUICIDE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You committed suicide!"), _("^K1You ended it all!")) + MSG_CENTER_NOTIF(DEATH_SELF_SWAMP, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got stuck in a swamp!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_TEAMCHANGE, 1, 0, 1, "death_team", CPID_Null, "0 0", _("^BGYou are now on: %s"), "") + MSG_CENTER_NOTIF(DEATH_SELF_TOUCHEXPLODE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You died in an accident!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_TURRET, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were fragged by a turret!"), _("^K1You had an unfortunate run in with a turret!")) + MSG_CENTER_NOTIF(DEATH_SELF_TURRET_EWHEEL, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were fragged by an eWheel turret!"), _("^K1You had an unfortunate run in with an eWheel turret!")) + MSG_CENTER_NOTIF(DEATH_SELF_TURRET_WALK, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were fragged by a Walker turret!"), _("^K1You had an unfortunate run in with a Walker turret!")) + MSG_CENTER_NOTIF(DEATH_SELF_VH_BUMB_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Bumblebee explosion!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_CRUSH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were crushed by a vehicle!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_RAPT_BOMB, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were caught in a Raptor cluster bomb!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_RAPT_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Raptor explosion!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_SPID_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Spiderbot explosion!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_SPID_ROCKET, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You were blasted to bits by a Spiderbot rocket!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_WAKI_DEATH, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You got caught in the blast of a Racer explosion!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VH_WAKI_ROCKET, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You couldn't find shelter from a Racer rocket!"), "") + MSG_CENTER_NOTIF(DEATH_SELF_VOID, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Watch your step!"), "") + + MSG_CENTER_NOTIF(DEATH_TEAMKILL_FRAG, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1Moron! You fragged ^BG%s^K1, a team mate!"), _("^K1Moron! You went against ^BG%s^K1, a team mate!")) + MSG_CENTER_NOTIF(DEATH_TEAMKILL_FRAGGED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1You were fragged by ^BG%s^K1, a team mate"), _("^K1You were scored against by ^BG%s^K1, a team mate")) + + MSG_CENTER_NOTIF(DISCONNECT_IDLING, 1, 0, 1, "", CPID_IDLING, "1 f1", _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") + + MSG_CENTER_NOTIF(DOOR_LOCKED_NEED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^BGYou need %s^BG!"), "") + MSG_CENTER_NOTIF(DOOR_LOCKED_ALSONEED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^BGYou also need %s^BG!"), "") + MSG_CENTER_NOTIF(DOOR_UNLOCKED, 1, 0, 0, "", CPID_Null, "0 0", _("^BGDoor unlocked!"), "") + + MSG_CENTER_NOTIF(EXTRALIVES, 1, 0, 0, "", CPID_Null, "0 0", _("^F2You picked up some extra lives"), "") + + MSG_CENTER_NOTIF(FREEZETAG_FREEZE, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K3You froze ^BG%s"), "") + MSG_CENTER_NOTIF(FREEZETAG_FROZEN, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1You were frozen by ^BG%s"), "") + MSG_CENTER_NOTIF(FREEZETAG_REVIVE, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K3You revived ^BG%s"), "") + MSG_CENTER_NOTIF(FREEZETAG_REVIVE_SELF, 1, 0, 0, "", CPID_Null, "0 0", _("^K3You revived yourself"), "") + MSG_CENTER_NOTIF(FREEZETAG_REVIVED, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K3You were revived by ^BG%s"), "") + MSG_CENTER_NOTIF(FREEZETAG_AUTO_REVIVED, 1, 0, 1, "f1", CPID_Null, "0 0", _("^K3You were automatically revived after %s second(s)"), "") + + MSG_CENTER_NOTIF(GENERATOR_UNDERATTACK, 1, 0, 0, "", CPID_Null, "0 0", _("^BGThe generator is under attack!"), "") + + MULTITEAM_CENTER(ROUND_TEAM_WIN, 4, 1, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team wins the round"), "") + MSG_CENTER_NOTIF(ROUND_PLAYER_WIN, 1, 1, 0, "s1", CPID_ROUND, "0 0", _("^BG%s^BG wins the round"), "") + + MSG_CENTER_NOTIF(FREEZETAG_SELF, 1, 0, 0, "", CPID_Null, "0 0", _("^K1You froze yourself"), "") + MSG_CENTER_NOTIF(FREEZETAG_SPAWN_LATE, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Round already started, you spawn as frozen"), "") + + MSG_CENTER_NOTIF(INVASION_SUPERMONSTER, 1, 1, 0, "s1", CPID_Null, "0 0", _("^K1A %s has arrived!"), "") + + MSG_CENTER_NOTIF(ITEM_BUFF_DROP, 1, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou dropped the %s^BG buff!"), "") + MSG_CENTER_NOTIF(ITEM_BUFF_GOT, 1, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou got the %s^BG buff!"), "") + MSG_CENTER_NOTIF(ITEM_FUELREGEN_GOT, 1, 0, 0, "", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1Fuel regenerator"), "") + MSG_CENTER_NOTIF(ITEM_JETPACK_GOT, 1, 0, 0, "", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1Jet pack"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_DONTHAVE, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou do not have the ^F1%s"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_DROP, 1, 1, 1, "item_wepname item_wepammo", CPID_ITEM, "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_GOT, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1%s"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_NOAMMO, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou don't have enough ammo for the ^F1%s"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_PRIMORSEC, 1, 0, 3, "item_wepname f2primsec f3primsec", CPID_ITEM, "item_centime 0", _("^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"), "") + MSG_CENTER_NOTIF(ITEM_WEAPON_UNAVAILABLE, 1, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^F1%s^BG is ^F4not available^BG on this map"), "") + + MSG_CENTER_NOTIF(JOIN_NOSPAWNS, 1, 0, 0, "", CPID_PREVENT_JOIN, "0 0", _("^K1No spawnpoints available!\nHope your team can fix it..."), "") + MSG_CENTER_NOTIF(JOIN_PREVENT, 1, 0, 0, "", CPID_PREVENT_JOIN, "0 0", _("^K1You may not join the game at this time.\nThe player limit reached maximum capacity."), "") + + MSG_CENTER_NOTIF(KEEPAWAY_DROPPED, 1, 1, 0, "s1", CPID_KEEPAWAY, "0 0", _("^BG%s^BG has dropped the ball!"), "") + MSG_CENTER_NOTIF(KEEPAWAY_PICKUP, 1, 1, 0, "s1", CPID_KEEPAWAY, "0 0", _("^BG%s^BG has picked up the ball!"), "") + MSG_CENTER_NOTIF(KEEPAWAY_PICKUP_SELF, 1, 0, 0, "", CPID_KEEPAWAY, "0 0", _("^BGYou picked up the ball"), "") + MSG_CENTER_NOTIF(KEEPAWAY_WARN, 1, 0, 0, "", CPID_KEEPAWAY_WARN, "0 0", _("^BGKilling people while you don't have the ball gives no points!"), "") + + MSG_CENTER_NOTIF(KEYHUNT_HELP, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in your team's hands!\nHelp the key carriers to meet!"), "") + MULTITEAM_CENTER(KEYHUNT_INTERFERE, 4, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in ^TC^TT team^BG's hands!\nInterfere ^F4NOW^BG!"), "") + MSG_CENTER_NOTIF(KEYHUNT_MEET, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGAll keys are in your team's hands!\nMeet the other key carriers ^F4NOW^BG!"), "") + MSG_CENTER_NOTIF(KEYHUNT_ROUNDSTART, 1, 0, 1, "", CPID_KEYHUNT_OTHER, "1 f1", _("^F4Round will start in ^COUNT"), "") + MSG_CENTER_NOTIF(KEYHUNT_SCAN, 1, 0, 1, "", CPID_KEYHUNT_OTHER, "f1 0", _("^BGScanning frequency range..."), "") + MULTITEAM_CENTER(KEYHUNT_START, 4, 1, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGYou are starting with the ^TC^TT Key"), "") + + MSG_CENTER_NOTIF(LMS_NOLIVES, 1, 0, 0, "", CPID_LMS, "0 0", _("^BGYou have no lives left, you must wait until the next match"), "") + + MSG_CENTER_NOTIF(MISSING_TEAMS, 1, 0, 1, "missing_teams", CPID_MISSING_TEAMS, "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") + MSG_CENTER_NOTIF(MISSING_PLAYERS, 1, 0, 1, "f1", CPID_MISSING_PLAYERS, "-1 0", _("^BGWaiting for %s player(s) to join..."), "") + + MSG_CENTER_NOTIF(INSTAGIB_DOWNGRADE, 1, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "5 0", _("^BGYour weapon has been downgraded until you find some ammo!"), "") + MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO, 1, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "1 9", _("^F4^COUNT^BG left to find some ammo!"), "") + MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO_FIRST, 1, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "1 10", _("^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"), _("^BGGet some ammo! ^F4^COUNT^BG left!")) + MSG_CENTER_NOTIF(INSTAGIB_LIVES_REMAINING, 1, 0, 1, "f1", CPID_Null, "0 0", _("^F2Extra lives remaining: ^K1%s"), "") + + MSG_CENTER_NOTIF(MOTD, 1, 1, 0, "s1", CPID_MOTD, "-1 0", "^BG%s", "") + + MSG_CENTER_NOTIF(NIX_COUNTDOWN, 1, 0, 2, "item_wepname", CPID_NIX, "1 f2", _("^F2^COUNT^BG until weapon change...\nNext weapon: ^F1%s"), "") + MSG_CENTER_NOTIF(NIX_NEWWEAPON, 1, 0, 1, "item_wepname", CPID_NIX, "0 0", _("^F2Active weapon: ^F1%s"), "") + + MSG_CENTER_NOTIF(NADE, 1, 0, 0, "", CPID_Null, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the grenade!"), "") + + MSG_CENTER_NOTIF(ONS_CAPTURE, 1, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^BGYou captured %s^BG control point"), "") + MULTITEAM_CENTER(ONS_CAPTURE, 4, 1, 1, 0, "s1", CPID_ONSLAUGHT, "0 0", _("^TC^TT^BG team captured %s^BG control point"), "") + MSG_CENTER_NOTIF(ONS_CONTROLPOINT_SHIELDED, 1, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThis control point currently cannot be captured"), "") + MSG_CENTER_NOTIF(ONS_GENERATOR_SHIELDED, 1, 0, 0, "", CPID_ONS_CAPSHIELD, "0 0", _("^BGThe enemy generator cannot be destroyed yet\n^F2Capture some control points to unshield it"), "") + MULTITEAM_CENTER(ONS_NOTSHIELDED, 4, 1, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^BGThe ^TCenemy^BG generator is no longer shielded!"), "") + MSG_CENTER_NOTIF(ONS_NOTSHIELDED_TEAM, 1, 0, 0, "", CPID_ONSLAUGHT, "0 0", _("^K1Your generator is NOT shielded!\n^BGRe-capture control points to shield it!"), "") + MSG_CENTER_NOTIF(ONS_TELEPORT, 1, 0, 0, "pass_key", CPID_ONSLAUGHT, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to teleport"), "") + MSG_CENTER_NOTIF(ONS_TELEPORT_ANTISPAM, 1, 0, 1, "f1secs", CPID_ONSLAUGHT, "0 0", _("^BGTeleporting disabled for %s"), "") + + MSG_CENTER_NOTIF(OVERTIME_FRAG, 1, 0, 0, "", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\nKeep fragging until we have a winner!"), _("^F2Now playing ^F4OVERTIME^F2!\nKeep scoring until we have a winner!")) + MSG_CENTER_NOTIF(OVERTIME_CONTROLPOINT, 1, 0, 0, "", CPID_OVERTIME, "5 0", _("^F2Now playing ^F4OVERTIME^F2!\n\nGenerators are now decaying.\nThe more control points your team holds,\nthe faster the enemy generator decays"), "") + MSG_CENTER_NOTIF(OVERTIME_TIME, 1, 0, 1, "f1time", CPID_OVERTIME, "0 0", _("^F2Now playing ^F4OVERTIME^F2!\n^BGAdded ^F4%s^BG to the game!"), "") + + MSG_CENTER_NOTIF(PORTO_CREATED_IN, 1, 0, 0, "", CPID_Null, "0 0", _("^K1In^BG-portal created"), "") + MSG_CENTER_NOTIF(PORTO_CREATED_OUT, 1, 0, 0, "", CPID_Null, "0 0", _("^F3Out^BG-portal created"), "") + MSG_CENTER_NOTIF(PORTO_FAILED, 1, 0, 0, "", CPID_Null, "0 0", _("^F1Portal creation failed"), "") + + MSG_CENTER_NOTIF(POWERUP_STRENGTH, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Strength infuses your weapons with devastating power"), "") + MSG_CENTER_NOTIF(POWERDOWN_STRENGTH, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Strength has worn off"), "") + + MSG_CENTER_NOTIF(POWERUP_SHIELD, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Shield surrounds you"), "") + MSG_CENTER_NOTIF(POWERDOWN_SHIELD, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Shield has worn off"), "") + + MSG_CENTER_NOTIF(POWERUP_SPEED, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You are on speed"), "") + MSG_CENTER_NOTIF(POWERDOWN_SPEED, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Speed has worn off"), "") + + MSG_CENTER_NOTIF(POWERUP_INVISIBILITY, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You are invisible"), "") + MSG_CENTER_NOTIF(POWERDOWN_INVISIBILITY, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Invisibility has worn off"), "") + + MSG_CENTER_NOTIF(RACE_FINISHLAP, 1, 0, 0, "", CPID_RACE_FINISHLAP, "0 0", _("^F2The race is over, finish your lap!"), "") + + MSG_CENTER_NOTIF(SECONDARY_NODAMAGE, 1, 0, 0, "", CPID_Null, "0 0", _("^BGSecondary fire inflicts no damage!"), "") + + MSG_CENTER_NOTIF(SEQUENCE_COMPLETED, 1, 0, 0, "", CPID_Null, "0 0", _("^BGSequence completed!"), "") + MSG_CENTER_NOTIF(SEQUENCE_COUNTER, 1, 0, 0, "", CPID_Null, "0 0", _("^BGThere are more to go..."), "") + MSG_CENTER_NOTIF(SEQUENCE_COUNTER_FEWMORE, 1, 0, 1, "f1", CPID_Null, "0 0", _("^BGOnly %s^BG more to go..."), "") + + MSG_CENTER_NOTIF(SUPERWEAPON_BROKEN, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have broken down"), "") + MSG_CENTER_NOTIF(SUPERWEAPON_LOST, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have been lost"), "") + MSG_CENTER_NOTIF(SUPERWEAPON_PICKUP, 1, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You now have a superweapon"), "") + + MULTITEAM_CENTER(TEAMCHANGE, 4, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Changing to ^TC^TT^K1 in ^COUNT"), "") + MSG_CENTER_NOTIF(TEAMCHANGE_AUTO, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Changing team in ^COUNT"), "") + MSG_CENTER_NOTIF(TEAMCHANGE_SPECTATE, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Spectating in ^COUNT"), "") + MSG_CENTER_NOTIF(TEAMCHANGE_SUICIDE, 1, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Suicide in ^COUNT"), "") + + MSG_CENTER_NOTIF(TIMEOUT_BEGINNING, 1, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout begins in ^COUNT"), "") + MSG_CENTER_NOTIF(TIMEOUT_ENDING, 1, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout ends in ^COUNT"), "") + + MSG_CENTER_NOTIF(JOIN_PREVENT_MINIGAME, 1, 0, 0, "", CPID_Null, "0 0", _("^K1Cannot join given minigame session!"), "" ) + + MSG_CENTER_NOTIF(VEHICLE_ENTER, 1, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter/exit the vehicle"), "") + MSG_CENTER_NOTIF(VEHICLE_ENTER_GUNNER, 1, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter the vehicle gunner"), "") + MSG_CENTER_NOTIF(VEHICLE_ENTER_STEAL, 1, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to steal this vehicle"), "") + MSG_CENTER_NOTIF(VEHICLE_STEAL, 1, 0, 0, "", CPID_VEHICLES_OTHER, "0 0", _("^F2The enemy is stealing one of your vehicles!\n^F4Stop them!"), "") + MSG_CENTER_NOTIF(VEHICLE_STEAL_SELF, 1, 0, 0, "", CPID_VEHICLES_OTHER, "4 0", _("^F2You have stolen the enemy's vehicle, you are now visible on their radar!"), "") + + MSG_CENTER_NOTIF(WEAPON_MINELAYER_LIMIT, 1, 0, 1, "f1", CPID_Null, "0 0", _("^BGYou cannot place more than ^F2%s^BG mines at a time"), "") + +#define MULTITEAM_MULTI2(prefix, default, anncepre, infopre, centerpre) \ + MSG_MULTI_NOTIF(prefix##_RED, default, anncepre##_RED, infopre##_RED, centerpre##_RED) \ + MSG_MULTI_NOTIF(prefix##_BLUE, default, anncepre##_BLUE, infopre##_BLUE, centerpre##_BLUE) +#define MULTITEAM_MULTI3(prefix, default, anncepre, infopre, centerpre) \ + MULTITEAM_MULTI2(prefix, default, anncepre, infopre, centerpre) \ + MSG_MULTI_NOTIF(default, prefix##_YELLOW, anncepre##YELLOW, infopre##YELLOW, centerpre##YELLOW) +#define MULTITEAM_MULTI4(prefix, default, anncepre, infopre, centerpre) \ + MULTITEAM_MULTI3(prefix, default, anncepre, infopre, centerpre) \ + MSG_MULTI_NOTIF(prefix##_PINK, default, anncepre##PINK, infopre##PINK, centerpre##PINK) +#define MULTITEAM_MULTI(prefix, teams, default, anncepre, infopre, centerpre) \ + MULTITEAM_MULTI##teams(prefix, default, anncepre, infopre, centerpre) + +// MSG_MULTI_NOTIFICATIONS + MSG_MULTI_NOTIF(DEATH_MURDER_BUFF, 1, NULL, INFO_DEATH_MURDER_BUFF, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_CHEAT, 1, NULL, INFO_DEATH_MURDER_CHEAT, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_DROWN, 1, NULL, INFO_DEATH_MURDER_DROWN, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_FALL, 1, NULL, INFO_DEATH_MURDER_FALL, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_FIRE, 1, NULL, INFO_DEATH_MURDER_FIRE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_LAVA, 1, NULL, INFO_DEATH_MURDER_LAVA, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_MONSTER, 1, NULL, INFO_DEATH_MURDER_MONSTER, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE, 1, NULL, INFO_DEATH_MURDER_NADE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE_NAPALM, 1, NULL, INFO_DEATH_MURDER_NADE_NAPALM, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE_ICE, 1, NULL, INFO_DEATH_MURDER_NADE_ICE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE_ICE_FREEZE, 1, NULL, INFO_DEATH_MURDER_NADE_ICE_FREEZE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_NADE_HEAL, 1, NULL, INFO_DEATH_MURDER_NADE_HEAL, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_SHOOTING_STAR, 1, NULL, INFO_DEATH_MURDER_SHOOTING_STAR, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_SLIME, 1, NULL, INFO_DEATH_MURDER_SLIME, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_SWAMP, 1, NULL, INFO_DEATH_MURDER_SWAMP, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_TELEFRAG, 1, NULL, INFO_DEATH_MURDER_TELEFRAG, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_TOUCHEXPLODE, 1, NULL, INFO_DEATH_MURDER_TOUCHEXPLODE, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_BUMB_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_BUMB_DEATH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_BUMB_GUN, 1, NULL, INFO_DEATH_MURDER_VH_BUMB_GUN, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_CRUSH, 1, NULL, INFO_DEATH_MURDER_VH_CRUSH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_RAPT_BOMB, 1, NULL, INFO_DEATH_MURDER_VH_RAPT_BOMB, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_RAPT_CANNON, 1, NULL, INFO_DEATH_MURDER_VH_RAPT_CANNON, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_RAPT_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_RAPT_DEATH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_SPID_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_SPID_DEATH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_SPID_MINIGUN, 1, NULL, INFO_DEATH_MURDER_VH_SPID_MINIGUN, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_SPID_ROCKET, 1, NULL, INFO_DEATH_MURDER_VH_SPID_ROCKET, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_WAKI_DEATH, 1, NULL, INFO_DEATH_MURDER_VH_WAKI_DEATH, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_WAKI_GUN, 1, NULL, INFO_DEATH_MURDER_VH_WAKI_GUN, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VH_WAKI_ROCKET, 1, NULL, INFO_DEATH_MURDER_VH_WAKI_ROCKET, NULL) + MSG_MULTI_NOTIF(DEATH_MURDER_VOID, 1, NULL, INFO_DEATH_MURDER_VOID, NULL) + + MSG_MULTI_NOTIF(DEATH_SELF_AUTOTEAMCHANGE, 1, NULL, INFO_DEATH_SELF_AUTOTEAMCHANGE, CENTER_DEATH_SELF_AUTOTEAMCHANGE) + MSG_MULTI_NOTIF(DEATH_SELF_BETRAYAL, 1, NULL, INFO_DEATH_SELF_BETRAYAL, CENTER_DEATH_SELF_BETRAYAL) + MSG_MULTI_NOTIF(DEATH_SELF_CAMP, 1, NULL, INFO_DEATH_SELF_CAMP, CENTER_DEATH_SELF_CAMP) + MSG_MULTI_NOTIF(DEATH_SELF_CHEAT, 1, NULL, INFO_DEATH_SELF_CHEAT, CENTER_DEATH_SELF_CHEAT) + MSG_MULTI_NOTIF(DEATH_SELF_CUSTOM, 1, NULL, INFO_DEATH_SELF_GENERIC, CENTER_DEATH_SELF_CUSTOM) + MSG_MULTI_NOTIF(DEATH_SELF_DROWN, 1, NULL, INFO_DEATH_SELF_DROWN, CENTER_DEATH_SELF_DROWN) + MSG_MULTI_NOTIF(DEATH_SELF_FALL, 1, NULL, INFO_DEATH_SELF_FALL, CENTER_DEATH_SELF_FALL) + MSG_MULTI_NOTIF(DEATH_SELF_FIRE, 1, NULL, INFO_DEATH_SELF_FIRE, CENTER_DEATH_SELF_FIRE) + MSG_MULTI_NOTIF(DEATH_SELF_GENERIC, 1, NULL, INFO_DEATH_SELF_GENERIC, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(DEATH_SELF_LAVA, 1, NULL, INFO_DEATH_SELF_LAVA, CENTER_DEATH_SELF_LAVA) + MSG_MULTI_NOTIF(DEATH_SELF_MON_MAGE, 1, NULL, INFO_DEATH_SELF_MON_MAGE, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_SHAMBLER_CLAW, 1, NULL, INFO_DEATH_SELF_MON_SHAMBLER_CLAW, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_SHAMBLER_SMASH, 1, NULL, INFO_DEATH_SELF_MON_SHAMBLER_SMASH, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_SHAMBLER_ZAP, 1, NULL, INFO_DEATH_SELF_MON_SHAMBLER_ZAP, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_SPIDER, 1, NULL, INFO_DEATH_SELF_MON_SPIDER, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_WYVERN, 1, NULL, INFO_DEATH_SELF_MON_WYVERN, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_ZOMBIE_JUMP, 1, NULL, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_MON_ZOMBIE_MELEE, 1, NULL, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, CENTER_DEATH_SELF_MONSTER) + MSG_MULTI_NOTIF(DEATH_SELF_NADE, 1, NULL, INFO_DEATH_SELF_NADE, CENTER_DEATH_SELF_NADE) + MSG_MULTI_NOTIF(DEATH_SELF_NADE_NAPALM, 1, NULL, INFO_DEATH_SELF_NADE_NAPALM, CENTER_DEATH_SELF_NADE_NAPALM) + MSG_MULTI_NOTIF(DEATH_SELF_NADE_ICE, 1, NULL, INFO_DEATH_SELF_NADE_ICE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) + MSG_MULTI_NOTIF(DEATH_SELF_NADE_ICE_FREEZE, 1, NULL, INFO_DEATH_SELF_NADE_ICE_FREEZE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) + MSG_MULTI_NOTIF(DEATH_SELF_NADE_HEAL, 1, NULL, INFO_DEATH_SELF_NADE_HEAL, CENTER_DEATH_SELF_NADE_HEAL) + MSG_MULTI_NOTIF(DEATH_SELF_NOAMMO, 1, NULL, INFO_DEATH_SELF_NOAMMO, CENTER_DEATH_SELF_NOAMMO) + MSG_MULTI_NOTIF(DEATH_SELF_ROT, 1, NULL, INFO_DEATH_SELF_ROT, CENTER_DEATH_SELF_ROT) + MSG_MULTI_NOTIF(DEATH_SELF_SHOOTING_STAR, 1, NULL, INFO_DEATH_SELF_SHOOTING_STAR, CENTER_DEATH_SELF_SHOOTING_STAR) + MSG_MULTI_NOTIF(DEATH_SELF_SLIME, 1, NULL, INFO_DEATH_SELF_SLIME, CENTER_DEATH_SELF_SLIME) + MSG_MULTI_NOTIF(DEATH_SELF_SUICIDE, 1, NULL, INFO_DEATH_SELF_SUICIDE, CENTER_DEATH_SELF_SUICIDE) + MSG_MULTI_NOTIF(DEATH_SELF_SWAMP, 1, NULL, INFO_DEATH_SELF_SWAMP, CENTER_DEATH_SELF_SWAMP) + MSG_MULTI_NOTIF(DEATH_SELF_TEAMCHANGE, 1, NULL, INFO_DEATH_SELF_TEAMCHANGE, CENTER_DEATH_SELF_TEAMCHANGE) + MSG_MULTI_NOTIF(DEATH_SELF_TOUCHEXPLODE, 1, NULL, INFO_DEATH_SELF_TOUCHEXPLODE, CENTER_DEATH_SELF_TOUCHEXPLODE) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET, 1, NULL, INFO_DEATH_SELF_TURRET, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_EWHEEL, 1, NULL, INFO_DEATH_SELF_TURRET_EWHEEL, CENTER_DEATH_SELF_TURRET_EWHEEL) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_FLAC, 1, NULL, INFO_DEATH_SELF_TURRET_FLAC, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_HELLION, 1, NULL, INFO_DEATH_SELF_TURRET_HELLION, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_HK, 1, NULL, INFO_DEATH_SELF_TURRET_HK, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_MACHINEGUN, 1, NULL, INFO_DEATH_SELF_TURRET_MACHINEGUN, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_MLRS, 1, NULL, INFO_DEATH_SELF_TURRET_MLRS, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_PHASER, 1, NULL, INFO_DEATH_SELF_TURRET_PHASER, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_PLASMA, 1, NULL, INFO_DEATH_SELF_TURRET_PLASMA, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_TESLA, 1, NULL, INFO_DEATH_SELF_TURRET_TESLA, CENTER_DEATH_SELF_TURRET) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_WALK_GUN, 1, NULL, INFO_DEATH_SELF_TURRET_WALK_GUN, CENTER_DEATH_SELF_TURRET_WALK) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_WALK_MELEE, 1, NULL, INFO_DEATH_SELF_TURRET_WALK_MELEE, CENTER_DEATH_SELF_TURRET_WALK) + MSG_MULTI_NOTIF(DEATH_SELF_TURRET_WALK_ROCKET, 1, NULL, INFO_DEATH_SELF_TURRET_WALK_ROCKET, CENTER_DEATH_SELF_TURRET_WALK) + MSG_MULTI_NOTIF(DEATH_SELF_VH_BUMB_DEATH, 1, NULL, INFO_DEATH_SELF_VH_BUMB_DEATH, CENTER_DEATH_SELF_VH_BUMB_DEATH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_CRUSH, 1, NULL, INFO_DEATH_SELF_VH_CRUSH, CENTER_DEATH_SELF_VH_CRUSH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_RAPT_BOMB, 1, NULL, INFO_DEATH_SELF_VH_RAPT_BOMB, CENTER_DEATH_SELF_VH_RAPT_BOMB) + MSG_MULTI_NOTIF(DEATH_SELF_VH_RAPT_DEATH, 1, NULL, INFO_DEATH_SELF_VH_RAPT_DEATH, CENTER_DEATH_SELF_VH_RAPT_DEATH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_SPID_DEATH, 1, NULL, INFO_DEATH_SELF_VH_SPID_DEATH, CENTER_DEATH_SELF_VH_SPID_DEATH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_SPID_ROCKET, 1, NULL, INFO_DEATH_SELF_VH_SPID_ROCKET, CENTER_DEATH_SELF_VH_SPID_ROCKET) + MSG_MULTI_NOTIF(DEATH_SELF_VH_WAKI_DEATH, 1, NULL, INFO_DEATH_SELF_VH_WAKI_DEATH, CENTER_DEATH_SELF_VH_WAKI_DEATH) + MSG_MULTI_NOTIF(DEATH_SELF_VH_WAKI_ROCKET, 1, NULL, INFO_DEATH_SELF_VH_WAKI_ROCKET, CENTER_DEATH_SELF_VH_WAKI_ROCKET) + MSG_MULTI_NOTIF(DEATH_SELF_VOID, 1, NULL, INFO_DEATH_SELF_VOID, CENTER_DEATH_SELF_VOID) + + MSG_MULTI_NOTIF(ITEM_BUFF_DROP, 1, NULL, INFO_ITEM_BUFF_DROP, CENTER_ITEM_BUFF_DROP) + MSG_MULTI_NOTIF(ITEM_BUFF_GOT, 1, NULL, INFO_ITEM_BUFF_GOT, CENTER_ITEM_BUFF_GOT) + MSG_MULTI_NOTIF(ITEM_WEAPON_DONTHAVE, 1, NULL, INFO_ITEM_WEAPON_DONTHAVE, CENTER_ITEM_WEAPON_DONTHAVE) + MSG_MULTI_NOTIF(ITEM_WEAPON_DROP, 1, NULL, INFO_ITEM_WEAPON_DROP, CENTER_ITEM_WEAPON_DROP) + MSG_MULTI_NOTIF(ITEM_WEAPON_GOT, 1, NULL, INFO_ITEM_WEAPON_GOT, CENTER_ITEM_WEAPON_GOT) + MSG_MULTI_NOTIF(ITEM_WEAPON_NOAMMO, 1, NULL, INFO_ITEM_WEAPON_NOAMMO, CENTER_ITEM_WEAPON_NOAMMO) + MSG_MULTI_NOTIF(ITEM_WEAPON_PRIMORSEC, 1, NULL, INFO_ITEM_WEAPON_PRIMORSEC, CENTER_ITEM_WEAPON_PRIMORSEC) + MSG_MULTI_NOTIF(ITEM_WEAPON_UNAVAILABLE, 1, NULL, INFO_ITEM_WEAPON_UNAVAILABLE, CENTER_ITEM_WEAPON_UNAVAILABLE) + + MSG_MULTI_NOTIF(MULTI_COINTOSS, 1, NULL, INFO_COINTOSS, CENTER_COINTOSS) + MSG_MULTI_NOTIF(MULTI_COUNTDOWN_BEGIN, 1, ANNCE_BEGIN, NULL, CENTER_COUNTDOWN_BEGIN) + MSG_MULTI_NOTIF(MULTI_INSTAGIB_FINDAMMO, 1, ANNCE_NUM_10, NULL, CENTER_INSTAGIB_FINDAMMO_FIRST) + + MSG_MULTI_NOTIF(WEAPON_ACCORDEON_MURDER, 1, NULL, INFO_WEAPON_ACCORDEON_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_ACCORDEON_SUICIDE, 1, NULL, INFO_WEAPON_ACCORDEON_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_ARC_MURDER, 1, NULL, INFO_WEAPON_ARC_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_ARC_MURDER_SPRAY, 1, NULL, INFO_WEAPON_ARC_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_BLASTER_MURDER, 1, NULL, INFO_WEAPON_BLASTER_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_BLASTER_SUICIDE, 1, NULL, INFO_WEAPON_BLASTER_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_CRYLINK_MURDER, 1, NULL, INFO_WEAPON_CRYLINK_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_CRYLINK_SUICIDE, 1, NULL, INFO_WEAPON_CRYLINK_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_DEVASTATOR_MURDER_DIRECT, 1, NULL, INFO_WEAPON_DEVASTATOR_MURDER_DIRECT, NULL) + MSG_MULTI_NOTIF(WEAPON_DEVASTATOR_MURDER_SPLASH, 1, NULL, INFO_WEAPON_DEVASTATOR_MURDER_SPLASH, NULL) + MSG_MULTI_NOTIF(WEAPON_DEVASTATOR_SUICIDE, 1, NULL, INFO_WEAPON_DEVASTATOR_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_MURDER_BOLT, 1, NULL, INFO_WEAPON_ELECTRO_MURDER_BOLT, NULL) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_MURDER_COMBO, 1, NULL, INFO_WEAPON_ELECTRO_MURDER_COMBO, NULL) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_MURDER_ORBS, 1, NULL, INFO_WEAPON_ELECTRO_MURDER_ORBS, NULL) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_SUICIDE_BOLT, 1, NULL, INFO_WEAPON_ELECTRO_SUICIDE_BOLT, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_ELECTRO_SUICIDE_ORBS, 1, NULL, INFO_WEAPON_ELECTRO_SUICIDE_ORBS, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_FIREBALL_MURDER_BLAST, 1, NULL, INFO_WEAPON_FIREBALL_MURDER_BLAST, NULL) + MSG_MULTI_NOTIF(WEAPON_FIREBALL_MURDER_FIREMINE, 1, NULL, INFO_WEAPON_FIREBALL_MURDER_FIREMINE, NULL) + MSG_MULTI_NOTIF(WEAPON_FIREBALL_SUICIDE_BLAST, 1, NULL, INFO_WEAPON_FIREBALL_SUICIDE_BLAST, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_FIREBALL_SUICIDE_FIREMINE, 1, NULL, INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_HAGAR_MURDER_BURST, 1, NULL, INFO_WEAPON_HAGAR_MURDER_BURST, NULL) + MSG_MULTI_NOTIF(WEAPON_HAGAR_MURDER_SPRAY, 1, NULL, INFO_WEAPON_HAGAR_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_HAGAR_SUICIDE, 1, NULL, INFO_WEAPON_HAGAR_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_HLAC_MURDER, 1, NULL, INFO_WEAPON_HLAC_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_HLAC_SUICIDE, 1, NULL, INFO_WEAPON_HLAC_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_HMG_MURDER_SNIPE, 1, NULL, INFO_WEAPON_HMG_MURDER_SNIPE, NULL) + MSG_MULTI_NOTIF(WEAPON_HMG_MURDER_SPRAY, 1, NULL, INFO_WEAPON_HMG_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_HOOK_MURDER, 1, NULL, INFO_WEAPON_HOOK_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_KLEINBOTTLE_MURDER, 1, NULL, INFO_WEAPON_KLEINBOTTLE_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_KLEINBOTTLE_SUICIDE, 1, NULL, INFO_WEAPON_KLEINBOTTLE_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_MACHINEGUN_MURDER_SNIPE, 1, NULL, INFO_WEAPON_MACHINEGUN_MURDER_SNIPE, NULL) + MSG_MULTI_NOTIF(WEAPON_MACHINEGUN_MURDER_SPRAY, 1, NULL, INFO_WEAPON_MACHINEGUN_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_MINELAYER_LIMIT, 1, NULL, INFO_WEAPON_MINELAYER_LIMIT, CENTER_WEAPON_MINELAYER_LIMIT) + MSG_MULTI_NOTIF(WEAPON_MINELAYER_MURDER, 1, NULL, INFO_WEAPON_MINELAYER_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_MINELAYER_SUICIDE, 1, NULL, INFO_WEAPON_MINELAYER_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_MORTAR_MURDER_BOUNCE, 1, NULL, INFO_WEAPON_MORTAR_MURDER_BOUNCE, NULL) + MSG_MULTI_NOTIF(WEAPON_MORTAR_MURDER_EXPLODE, 1, NULL, INFO_WEAPON_MORTAR_MURDER_EXPLODE, NULL) + MSG_MULTI_NOTIF(WEAPON_MORTAR_SUICIDE_BOUNCE, 1, NULL, INFO_WEAPON_MORTAR_SUICIDE_BOUNCE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_MORTAR_SUICIDE_EXPLODE, 1, NULL, INFO_WEAPON_MORTAR_SUICIDE_EXPLODE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER, 1, NULL, INFO_WEAPON_RIFLE_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER_HAIL, 1, NULL, INFO_WEAPON_RIFLE_MURDER_HAIL, NULL) + MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER_HAIL_PIERCING, 1, NULL, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING, NULL) + MSG_MULTI_NOTIF(WEAPON_RIFLE_MURDER_PIERCING, 1, NULL, INFO_WEAPON_RIFLE_MURDER_PIERCING, NULL) + MSG_MULTI_NOTIF(WEAPON_RPC_MURDER_DIRECT, 1, NULL, INFO_WEAPON_RPC_MURDER_DIRECT, NULL) + MSG_MULTI_NOTIF(WEAPON_RPC_MURDER_SPLASH, 1, NULL, INFO_WEAPON_RPC_MURDER_SPLASH, NULL) + MSG_MULTI_NOTIF(WEAPON_RPC_SUICIDE_DIRECT, 1, NULL, INFO_WEAPON_RPC_SUICIDE_DIRECT, NULL) + MSG_MULTI_NOTIF(WEAPON_RPC_SUICIDE_SPLASH, 1, NULL, INFO_WEAPON_RPC_SUICIDE_SPLASH, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_SEEKER_MURDER_SPRAY, 1, NULL, INFO_WEAPON_SEEKER_MURDER_SPRAY, NULL) + MSG_MULTI_NOTIF(WEAPON_SEEKER_MURDER_TAG, 1, NULL, INFO_WEAPON_SEEKER_MURDER_TAG, NULL) + MSG_MULTI_NOTIF(WEAPON_SEEKER_SUICIDE, 1, NULL, INFO_WEAPON_SEEKER_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_SHOCKWAVE_MURDER, 1, NULL, INFO_WEAPON_SHOCKWAVE_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_SHOCKWAVE_MURDER_SLAP, 1, NULL, INFO_WEAPON_SHOCKWAVE_MURDER_SLAP, NULL) + MSG_MULTI_NOTIF(WEAPON_SHOTGUN_MURDER, 1, NULL, INFO_WEAPON_SHOTGUN_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_SHOTGUN_MURDER_SLAP, 1, NULL, INFO_WEAPON_SHOTGUN_MURDER_SLAP, NULL) + MSG_MULTI_NOTIF(WEAPON_THINKING_WITH_PORTALS, 1, NULL, INFO_WEAPON_THINKING_WITH_PORTALS, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_TUBA_MURDER, 1, NULL, INFO_WEAPON_TUBA_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_TUBA_SUICIDE, 1, NULL, INFO_WEAPON_TUBA_SUICIDE, CENTER_DEATH_SELF_GENERIC) + MSG_MULTI_NOTIF(WEAPON_VAPORIZER_MURDER, 1, NULL, INFO_WEAPON_VAPORIZER_MURDER, NULL) + MSG_MULTI_NOTIF(WEAPON_VORTEX_MURDER, 1, NULL, INFO_WEAPON_VORTEX_MURDER, NULL) + +#define MULTITEAM_CHOICE2(prefix, default, challow, chtype, optiona, optionb) \ + MSG_CHOICE_NOTIF(prefix##_RED, default, challow, chtype, optiona##_RED, optionb##_RED) \ + MSG_CHOICE_NOTIF(prefix##_BLUE, default, challow, chtype, optiona##_BLUE, optionb##_BLUE) +#define MULTITEAM_CHOICE3(prefix, default, challow, chtype, optiona, optionb) \ + MULTITEAM_CHOICE2(prefix, default, challow, chtype, optiona, optionb) \ + MSG_CHOICE_NOTIF(prefix##_YELLOW, default, challow, chtype, optiona##_YELLOW, optionb##_YELLOW) +#define MULTITEAM_CHOICE4(prefix, default, challow, chtype, optiona, optionb) \ + MULTITEAM_CHOICE3(prefix, default, challow, chtype, optiona, optionb) \ + MSG_CHOICE_NOTIF(prefix##_PINK, default, challow, chtype, optiona##_PINK, optionb##_PINK) +#define MULTITEAM_CHOICE(prefix, teams, default, challow, chtype, optiona, optionb) \ + MULTITEAM_CHOICE##teams(prefix, default, challow, chtype, optiona, optionb) + +// MSG_CHOICE_NOTIFICATIONS + MULTITEAM_CHOICE(CTF_CAPTURE_BROKEN, 4, 1, 2, MSG_INFO, INFO_CTF_CAPTURE, INFO_CTF_CAPTURE_BROKEN) + MULTITEAM_CHOICE(CTF_CAPTURE_TIME, 4, 1, 2, MSG_INFO, INFO_CTF_CAPTURE, INFO_CTF_CAPTURE_TIME) + MULTITEAM_CHOICE(CTF_CAPTURE_UNBROKEN, 4, 1, 2, MSG_INFO, INFO_CTF_CAPTURE, INFO_CTF_CAPTURE_UNBROKEN) + MULTITEAM_CHOICE(CTF_PICKUP_TEAM, 4, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_TEAM, CENTER_CTF_PICKUP_TEAM_VERBOSE) + MSG_CHOICE_NOTIF(CTF_PICKUP_TEAM_NEUTRAL, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_NEUTRAL, CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL) + MSG_CHOICE_NOTIF(CTF_PICKUP_ENEMY, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY, CENTER_CTF_PICKUP_ENEMY_VERBOSE) + MSG_CHOICE_NOTIF(CTF_PICKUP_ENEMY_NEUTRAL, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_NEUTRAL, CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE) + MSG_CHOICE_NOTIF(CTF_PICKUP_ENEMY_TEAM, 1, 2, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_TEAM, CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE) + MSG_CHOICE_NOTIF(FRAG, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_FRAG, CENTER_DEATH_MURDER_FRAG_VERBOSE) + MSG_CHOICE_NOTIF(FRAGGED, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED, CENTER_DEATH_MURDER_FRAGGED_VERBOSE) + MSG_CHOICE_NOTIF(TYPEFRAG, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE) + MSG_CHOICE_NOTIF(TYPEFRAGGED, 1, 1, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE) diff --git a/qcsrc/common/notifications/all.qc b/qcsrc/common/notifications/all.qc new file mode 100644 index 000000000..60fd62599 --- /dev/null +++ b/qcsrc/common/notifications/all.qc @@ -0,0 +1,1775 @@ +#if defined(CSQC) + #include +#elif defined(MENUQC) +#elif defined(SVQC) + #include + #include + #include + #include + #include + #include "all.qh" + #include +#endif + +// ================================================ +// Unified notification system, written by Samual +// Last updated: August, 2013 +// ================================================ + +#ifdef SVQC +string Notification_CheckArgs( + NOTIF broadcast, entity client) +{ + // check supplied broadcast and target for errors + switch (broadcast) + { + case NOTIF_ONE: + case NOTIF_ONE_ONLY: + { + if (IS_NOT_A_CLIENT(client)) { + return "No client provided!"; + } + break; + } + + case NOTIF_ALL_EXCEPT: + { + if (IS_NOT_A_CLIENT(client)) { + return "Exception can't be a non-client!"; + } + break; + } + + case NOTIF_ALL: + { + if (client) { + return "Entity provided when world was required!"; + } + break; + } + + case NOTIF_TEAM: + { + if (!teamplay) { + return "Teamplay not active!"; + } else if (!client.team) { + // checkargs = sprintf("%sNo team provided!", checkargs); + } + break; + } + + case NOTIF_TEAM_EXCEPT: + { + if (!teamplay) { + return "Teamplay not active!"; + } else if (IS_NOT_A_CLIENT(client)) { + return "Exception can't be a non-client!"; + } + break; + } + + default: + { + return sprintf("Improper broadcast: %d!", broadcast); + } + } + return ""; +} + +bool Notification_ShouldSend(NOTIF broadcast, entity to_client, entity other_client) +{ + switch (broadcast) + { + case NOTIF_ONE: + return ( + (to_client == other_client) + || + ( + IS_SPEC(to_client) + && + (to_client.enemy == other_client) + ) + ); + case NOTIF_ONE_ONLY: + return (to_client == other_client); + case NOTIF_TEAM: + return ( + (to_client.team == other_client.team) + || + ( + IS_SPEC(to_client) + && + (to_client.enemy.team == other_client.team) + ) + ); + case NOTIF_TEAM_EXCEPT: + return ( + (to_client != other_client) + && + ( + (to_client.team == other_client.team) + || + ( + IS_SPEC(to_client) + && + ( + (to_client.enemy != other_client) + && + (to_client.enemy.team == other_client.team) + ) + ) + ) + ); + case NOTIF_ALL: + return true; + case NOTIF_ALL_EXCEPT: + return ( + (to_client != other_client) + && + !( + IS_SPEC(to_client) + && + (to_client.enemy == other_client) + ) + ); + default: + return false; + } +} + +#endif + +// =============================== +// Initialization Core Functions +// =============================== + +// used by restartnotifs command to initialize notifications +void Destroy_Notification_Entity(entity notif) +{ + if (notif.nent_name != "") strunzone(notif.nent_name); + if (notif.nent_snd != "") strunzone(notif.nent_snd); + if (notif.nent_args != "") strunzone(notif.nent_args); + if (notif.nent_hudargs != "") strunzone(notif.nent_hudargs); + if (notif.nent_icon != "") strunzone(notif.nent_icon); + if (notif.nent_durcnt != "") strunzone(notif.nent_durcnt); + if (notif.nent_string != "") strunzone(notif.nent_string); + remove(notif); +} + +void Destroy_All_Notifications() +{ + // kill all networked notifications and centerprints + #ifdef SVQC + Kill_Notification(NOTIF_ALL, NULL, MSG_Null, CPID_Null); + #else + reset_centerprint_messages(); + #endif + + // kill all real notification entities + FOREACH(Notifications, true, { Destroy_Notification_Entity(it); }); +} + +string Process_Notif_Line( + MSG typeId, + bool chat, + string input, + string notiftype, + string notifname, + string stringtype) +{ + #ifdef CSQC + if(typeId == MSG_INFO) + { + if((chat && autocvar_notification_allow_chatboxprint) + || (autocvar_notification_allow_chatboxprint == 2)) + { + // pass 1: add ETX char at beginning of line + input = strcat("\{3}", input); + + // pass 2: add ETX char at end of each new line (so that + // messages with multiple lines are put through chatbox too) + input = strreplace("\n", "\n\{3}", input); + + // pass 3: strip trailing ETX char + if(substring(input, (strlen(input) - 1), 1) == "\{3}") + { input = substring(input, 0, (strlen(input) - 1)); } + } + } + #endif + + // done to both MSG_INFO and MSG_CENTER + if(substring(input, (strlen(input) - 1), 1) == "\n") + { + LOG_INFOF( + ( + "^1TRAILING NEW LINE AT END OF NOTIFICATION: " + "^7net_type = %s, net_name = %s, string = %s.\n" + ), + notiftype, + notifname, + stringtype + ); + notif_error = true; + input = substring(input, 1, (strlen(input) - 1)); + } + + return input; +} + +string Process_Notif_Args( + float arg_type, + string args, + string notiftype, + string notifname) +{ + string selected, remaining = args; + float sel_num = 0; + + for (;(remaining != "");) + { + selected = car(remaining); remaining = cdr(remaining); + + switch(arg_type) + { + case 1: // normal args + { + if(sel_num == NOTIF_MAX_ARGS) + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS TOO MANY ARGUMENTS: " + "^7net_type = %s, net_name = %s, max args = %d.\n" + ), + notiftype, + notifname, + NOTIF_MAX_ARGS + ); + notif_error = true; + break; + } + + switch(strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_SV(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_DC(selected,result) + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: + { + LOG_INFOF( + ( + "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: " + "^7net_type = %s, net_name = %s, args arg = '%s'.\n" + ), + notiftype, + notifname, + selected + ); + notif_error = true; + break; + } + } + break; + } + case 2: // hudargs + { + if(sel_num == NOTIF_MAX_HUDARGS) + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS TOO MANY ARGUMENTS: " + "^7net_type = %s, net_name = %s, max hudargs = %d.\n" + ), + notiftype, + notifname, + NOTIF_MAX_HUDARGS + ); + notif_error = true; + break; + } + + switch(strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected,result) + #define ARG_CASE_ARG_CS_SV(selected,result) + #define ARG_CASE_ARG_CS(selected,result) + #define ARG_CASE_ARG_SV(selected,result) + #define ARG_CASE_ARG_DC(selected,result) + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: + { + LOG_INFOF( + ( + "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: " + "^7net_type = %s, net_name = %s, hudargs arg = '%s'.\n" + ), + notiftype, + notifname, + selected + ); + notif_error = true; + break; + } + } + break; + } + case 3: // durcnt + { + if(sel_num == NOTIF_MAX_DURCNT) + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS TOO MANY ARGUMENTS: " + "^7net_type = %s, net_name = %s, max durcnt = %d.\n" + ), + notiftype, + notifname, + NOTIF_MAX_DURCNT + ); + notif_error = true; + break; + } + + switch(strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected,result) + #define ARG_CASE_ARG_CS_SV_DC(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE_ARG_CS_SV(selected,result) + #define ARG_CASE_ARG_CS(selected,result) + #define ARG_CASE_ARG_SV(selected,result) + #define ARG_CASE_ARG_DC(selected,result) case selected: { ++sel_num; break; } + #define ARG_CASE(prog,selected,result) ARG_CASE_##prog(selected,result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: + { + if(ftos(stof(selected)) != "") { ++sel_num; } + else + { + LOG_INFOF( + ( + "^1NOTIFICATION WITH UNKNOWN TOKEN IN ARGUMENT STRING: " + "^7net_type = %s, net_name = %s, durcnt arg = '%s'.\n" + ), + notiftype, + notifname, + selected + ); + notif_error = true; + } + break; + } + } + break; + } + } + } + return args; +} + +void Create_Notification_Entity(entity notif, + float var_default, + float var_cvar, + MSG typeId, + string namestring) +{ + // ===================== + // Global Entity Setup + // ===================== + notif.nent_default = var_default; + notif.nent_enabled = (var_cvar >= 1); + notif.nent_type = typeId; + notif.nent_name = strzone(namestring); + + // Other pre-notif-setup requisites + notif_error = false; + + switch (typeId) + { + case MSG_ANNCE: + case MSG_INFO: + case MSG_CENTER: + case MSG_MULTI: + case MSG_CHOICE: + break; + default: + LOG_INFOF( + ( + "^1NOTIFICATION WITH IMPROPER TYPE: " + "^7net_type = %d, net_name = %s.\n" + ), + typeId, + namestring + ); + notif_error = true; + break; + } + + // now check to see if any errors happened + if (notif_error) + { + notif.nent_enabled = false; // disable the notification so it can't cause trouble + notif_global_error = true; // throw the red flag that an error happened on init + } +} + +void Create_Notification_Entity_Annce(entity notif, + float var_cvar, + string namestring, + /* MSG_ANNCE */ + float channel, + string snd, + float vol, + float position) + { + // Set MSG_ANNCE information and handle precaching + #ifdef CSQC + MSG typeId = MSG_ANNCE; + if (!(GENTLE && (var_cvar == 1))) + { + if(snd != "") + { + if(notif.nent_enabled) + { + precache_sound(sprintf("announcer/%s/%s.wav", AnnouncerOption(), snd)); + notif.nent_channel = channel; + notif.nent_snd = strzone(snd); + notif.nent_vol = vol; + notif.nent_position = position; + } + } + else + { + string typestring = Get_Notif_TypeName(typeId); + LOG_INFOF( + ( + "^1NOTIFICATION WITH NO SOUND: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + } + else { notif.nent_enabled = false; } + #else + notif.nent_enabled = false; + #endif + + } + +void Create_Notification_Entity_InfoCenter(entity notif, + float var_cvar, + string namestring, + int strnum, + int flnum, + /* MSG_INFO & MSG_CENTER */ + string args, + string hudargs, + string icon, + CPID cpid, + string durcnt, + string normal, + string gentle) + { + MSG typeId = notif.nent_type; + // Set MSG_INFO and MSG_CENTER string/float counts + notif.nent_stringcount = strnum; + notif.nent_floatcount = flnum; + + // Only initialize arguments if we're either a client or on a dedicated server + #ifdef SVQC + float should_process_args = server_is_dedicated; + #else + float should_process_args = true; + #endif + string typestring = Get_Notif_TypeName(typeId); + if(should_process_args) + { + // ======================== + // Process Main Arguments + // ======================== + if(strnum + flnum) + { + if(args != "") + { + notif.nent_args = strzone( + Process_Notif_Args(1, args, typestring, namestring)); + } + else if((hudargs == "") && (durcnt =="")) + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS ARG COUNTS BUT NO ARGS OR HUDARGS OR DURCNT: " + "^7net_type = %s, net_name = %s, strnum = %d, flnum = %d\n" + ), + typestring, + namestring, + strnum, + flnum + ); + notif_error = true; + } + } + else if(args != "") + { + notif.nent_args = strzone( + Process_Notif_Args(1, args, typestring, namestring)); + } + + + // ======================================= + // Process HUD and Centerprint Arguments + // Only processed on CSQC, as these + // args are only for HUD features. + // ======================================= + #ifdef CSQC + if(hudargs != "") + { + notif.nent_hudargs = strzone( + Process_Notif_Args(2, hudargs, typestring, namestring)); + + if(icon != "") { notif.nent_icon = strzone(icon); } + else + { + LOG_INFOF( + ( + "^1NOTIFICATION HAS HUDARGS BUT NO ICON: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + } + else if(icon != "") + { + LOG_WARNINGF( + ( + "^1NOTIFICATION HAS ICON BUT NO HUDARGS: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + + if (durcnt != "") + { + notif.nent_durcnt = strzone(Process_Notif_Args(3, durcnt, typestring, namestring)); + + if (cpid == CPID_Null && durcnt != "0 0") + { + LOG_WARNINGF( + ( + "Notification has durcnt but no cpid: " + "net_type = %s, net_name = %s." + ), + typestring, + namestring + ); + notif_error = true; + } + } + notif.nent_cpid = cpid; + #endif + + + // ====================== + // Process Notif String + // ====================== + #define SET_NOTIF_STRING(string,stringname) MACRO_BEGIN { \ + notif.nent_string = strzone(CCR( \ + Process_Notif_Line( \ + typeId, \ + (var_cvar > 1), \ + string, \ + typestring, \ + namestring, \ + stringname \ + )) \ + ); \ + } MACRO_END + + if(GENTLE) + { + if(gentle != "") { SET_NOTIF_STRING(gentle, "GENTLE"); } + else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL"); } + } + else if(normal != "") { SET_NOTIF_STRING(normal, "NORMAL"); } + #undef SET_NOTIF_STRING + + // Check to make sure a string was chosen + if(notif.nent_string == "") + { + LOG_INFOF( + ( + "^1EMPTY NOTIFICATION: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + } + } + +void Create_Notification_Entity_Multi(entity notif, + float var_cvar, + string namestring, + /* MSG_MULTI */ + Notification anncename, + Notification infoname, + Notification centername) + { + MSG typeId = MSG_MULTI; + // Set MSG_MULTI string/float counts + if (!anncename && !infoname && !centername) + { + string typestring = Get_Notif_TypeName(typeId); + LOG_INFOF( + ( + "^1NOTIFICATION WITH NO SUBCALLS: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + else + { + // announcements don't actually need any arguments, so lets not even count them. + if (anncename) { notif.nent_msgannce = anncename; } + + float infoname_stringcount = 0, infoname_floatcount = 0; + float centername_stringcount = 0, centername_floatcount = 0; + + if (infoname) + { + notif.nent_msginfo = infoname; + infoname_stringcount = notif.nent_msginfo.nent_stringcount; + infoname_floatcount = notif.nent_msginfo.nent_floatcount; + } + + if (centername) + { + notif.nent_msgcenter = centername; + centername_stringcount = notif.nent_msgcenter.nent_stringcount; + centername_floatcount = notif.nent_msgcenter.nent_floatcount; + } + + // set the requirements of THIS notification to the totals of its subcalls + notif.nent_stringcount = max(infoname_stringcount, centername_stringcount); + notif.nent_floatcount = max(infoname_floatcount, centername_floatcount); + } + } + +void Create_Notification_Entity_Choice(entity notif, + float var_cvar, + string namestring, + /* MSG_CHOICE */ + float challow_def, + float challow_var, + MSG chtype, + Notification optiona, + Notification optionb) + { + MSG typeId = MSG_CHOICE; + if (chtype == MSG_Null || !optiona || !optionb) + { + string typestring = Get_Notif_TypeName(typeId); + LOG_INFOF( + ( + "^1NOTIFICATION IS MISSING CHOICE PARAMS: " + "^7net_type = %s, net_name = %s.\n" + ), + typestring, + namestring + ); + notif_error = true; + } + else + { + notif.nent_optiona = optiona; + notif.nent_optionb = optionb; + notif.nent_challow_def = challow_def; // 0: never allowed, 1: allowed in warmup, 2: always allowed + notif.nent_challow_var = challow_var; // 0: never allowed, 1: allowed in warmup, 2: always allowed + notif.nent_stringcount = max(notif.nent_optiona.nent_stringcount, notif.nent_optionb.nent_stringcount); + notif.nent_floatcount = max(notif.nent_optiona.nent_floatcount, notif.nent_optionb.nent_floatcount); + + /*#ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Create_Notification_Entity(...): MSG_CHOICE: %s\n%s\n%s\n", + notif.nent_name, + sprintf( + "^ optiona: %s %s : %d %d", + Get_Notif_TypeName(notif.nent_optiona.nent_type), + notif.nent_optiona.nent_name, + notif.nent_optiona.nent_stringcount, + notif.nent_optiona.nent_floatcount + ), + sprintf( + "^ optionb: %s %s : %d %d", + Get_Notif_TypeName(notif.nent_optionb.nent_type), + notif.nent_optionb.nent_name, + notif.nent_optionb.nent_stringcount, + notif.nent_optionb.nent_floatcount + ) + )); + #endif*/ + } + } + + +// =============== +// Cvar Handling +// =============== + +// used by MSG_CHOICE to build list of choices +#ifdef SVQC +void Notification_GetCvars() +{ + int idx = 0; + FOREACH(Notifications, it.nent_type == MSG_CHOICE, { + GetCvars_handleFloat( + get_cvars_s, + get_cvars_f, + msg_choice_choices[idx++], + sprintf("notification_%s", it.nent_name) + ); + }); +} +#endif + +/** used to output notifications.cfg file */ +void Dump_Notifications(int fh, bool alsoprint) +{ + #define NOTIF_WRITE(a) MACRO_BEGIN { \ + fputs(fh, a); \ + if (alsoprint) LOG_INFO(a); \ + } MACRO_END + + #define NOTIF_WRITE_ENTITY(e, description) MACRO_BEGIN { \ + string notif_msg = sprintf( \ + "seta notification_%s \"%d\" \"%s\"\n", \ + e.nent_name, e.nent_default, description \ + ); \ + NOTIF_WRITE(notif_msg); \ + } MACRO_END + + #define NOTIF_WRITE_ENTITY_CHOICE(e, descriptiona, descriptionb) MACRO_BEGIN { \ + string notif_msg = sprintf( \ + "seta notification_%s \"%d\" \"%s\"\n" \ + "seta notification_%s_ALLOWED \"%d\" \"%s\"\n", \ + e.nent_name, e.nent_default, descriptiona, \ + e.nent_name, e.nent_challow_def, descriptionb \ + ); \ + NOTIF_WRITE(notif_msg); \ + } MACRO_END + + #define NOTIF_WRITE_HARDCODED(cvar, default, description) MACRO_BEGIN { \ + string notif_msg = sprintf( \ + "seta notification_%s \"%s\" \"%s\"\n", \ + cvar, default, description \ + ); \ + NOTIF_WRITE(notif_msg); \ + } MACRO_END + + // Note: This warning only applies to the notifications.cfg file that is output... + // You ARE supposed to manually edit this function to add i.e. hard coded + // notification variables for mutators or game modes or such and then + // regenerate the notifications.cfg file from the new code. + + NOTIF_WRITE("// ********************************************** //\n"); + NOTIF_WRITE("// ** WARNING - DO NOT MANUALLY EDIT THIS FILE ** //\n"); + NOTIF_WRITE("// ** ** //\n"); + NOTIF_WRITE("// ** This file is automatically generated ** //\n"); + NOTIF_WRITE("// ** by code with the command 'dumpnotifs'. ** //\n"); + NOTIF_WRITE("// ** ** //\n"); + NOTIF_WRITE("// ** If you add a new notification, please ** //\n"); + NOTIF_WRITE("// ** regenerate this file with that command ** //\n"); + NOTIF_WRITE("// ** making sure that the output matches ** //\n"); + NOTIF_WRITE("// ** with the lists and defaults in code. ** //\n"); + NOTIF_WRITE("// ** ** //\n"); + NOTIF_WRITE("// ********************************************** //\n"); + + // These notifications will also append their string as a comment... + // This is not necessary, and does not matter if they vary between config versions, + // it is just a semi-helpful tool for those who want to manually change their user settings. + + int NOTIF_ANNCE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_ANNCE, { ++NOTIF_ANNCE_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_ANNCE notifications (count = %d):\n", NOTIF_ANNCE_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_ANNCE, { + NOTIF_WRITE_ENTITY(it, + "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled" + ); + }); + + int NOTIF_INFO_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_INFO, { ++NOTIF_INFO_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_INFO notifications (count = %d):\n", NOTIF_INFO_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_INFO, { + NOTIF_WRITE_ENTITY(it, + "0 = off, 1 = print to console, " + "2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)" + ); + }); + + int NOTIF_CENTER_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CENTER, { ++NOTIF_CENTER_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_CENTER notifications (count = %d):\n", NOTIF_CENTER_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_CENTER, { + NOTIF_WRITE_ENTITY(it, + "0 = off, 1 = centerprint" + ); + }); + + int NOTIF_MULTI_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_MULTI, { ++NOTIF_MULTI_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_MULTI notifications (count = %d):\n", NOTIF_MULTI_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_MULTI, { + NOTIF_WRITE_ENTITY(it, + "Enable this multiple notification" + ); + }); + + int NOTIF_CHOICE_COUNT = 0; FOREACH(Notifications, it.nent_type == MSG_CHOICE, { ++NOTIF_CHOICE_COUNT; }); + NOTIF_WRITE(sprintf("\n// MSG_CHOICE notifications (count = %d):\n", NOTIF_CHOICE_COUNT)); + FOREACH(Notifications, it.nent_type == MSG_CHOICE, { + NOTIF_WRITE_ENTITY_CHOICE(it, + "Choice for this notification 0 = off, 1 = default message, 2 = verbose message", + "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always" + ); + }); + + // edit these to match whichever cvars are used for specific notification options + NOTIF_WRITE("\n// HARD CODED notification variables:\n"); + + NOTIF_WRITE_HARDCODED( + "allow_chatboxprint", "1", + "Allow INFO notifications to be printed to chat box" + "0 = do not allow, " + "1 = allow only if allowed by individual notification_INFO* cvars, " + "2 = force all INFO notifications to be printed to the chatbox" + ); + + NOTIF_WRITE_HARDCODED( + "debug", "0", + "Print extra debug information on all notification function calls " + "(Requires -DNOTIFICATIONS_DEBUG flag to be enabled on QCSRC compilation)... " + "0 = disabled, 1 = dprint, 2 = print" + ); + + NOTIF_WRITE_HARDCODED( + "errors_are_fatal", "1", + "If a notification fails upon initialization, cause a Host_Error to stop the program" + ); + + NOTIF_WRITE_HARDCODED( + "item_centerprinttime", "1.5", + "How long to show item information centerprint messages (like 'You got the Electro' or such)" + ); + + NOTIF_WRITE_HARDCODED( + "lifetime_mapload", "10", + "Amount of time that notification entities last immediately at mapload (in seconds) " + "to help prevent notifications from being lost on early init (like gamestart countdown)" + ); + + NOTIF_WRITE_HARDCODED( + "lifetime_runtime", "0.5", + "Amount of time that notification entities last on the server during runtime (In seconds)" + ); + + NOTIF_WRITE_HARDCODED( + "server_allows_location", "1", + "Server side cvar for allowing death messages to show location information too" + ); + + NOTIF_WRITE_HARDCODED( + "show_location", "0", + "Append location information to MSG_INFO death/kill messages" + ); + + NOTIF_WRITE_HARDCODED( + "show_location_string", "", + "Replacement string piped into sprintf, " + "so you can do different messages like this: ' at the %s' or ' (near %s)'" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees", "1", + "Print information about sprees in death/kill messages" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_center", "1", + "Show spree information in MSG_CENTER messages... " + "0 = off, 1 = target (but only for first victim) and attacker" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_center_specialonly", "1", + "Don't show spree information in MSG_CENTER messages if it isn't an achievement" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_info", "3", + "Show spree information in MSG_INFO messages... " + "0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_info_newline", "1", + "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself" + ); + + NOTIF_WRITE_HARDCODED( + "show_sprees_info_specialonly", "1", + "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement" + ); + + NOTIF_WRITE(sprintf( + ( + "\n// Notification counts (total = %d): " + "MSG_ANNCE = %d, MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d, MSG_CHOICE = %d\n" + ), + ( + NOTIF_ANNCE_COUNT + + NOTIF_INFO_COUNT + + NOTIF_CENTER_COUNT + + NOTIF_MULTI_COUNT + + NOTIF_CHOICE_COUNT + ), + NOTIF_ANNCE_COUNT, + NOTIF_INFO_COUNT, + NOTIF_CENTER_COUNT, + NOTIF_MULTI_COUNT, + NOTIF_CHOICE_COUNT + )); + #undef NOTIF_WRITE_HARDCODED + #undef NOTIF_WRITE_ENTITY + #undef NOTIF_WRITE +} + + +// =============================== +// Frontend Notification Pushing +// =============================== + +string Local_Notification_sprintf( + string input, string args, + string s1, string s2, string s3, string s4, + int f1, float f2, float f3, float f4) +{ + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification_sprintf('%s^7', '%s', %s, %s);\n", + MakeConsoleSafe(input), + args, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + for (int sel_num = 0; sel_num < NOTIF_MAX_ARGS; ++sel_num) { arg_slot[sel_num] = ""; } + + for (int sel_num = 0; (args != ""); ) + { + string selected = car(args); args = cdr(args); + NOTIF_HIT_MAX(NOTIF_MAX_ARGS, "Local_Notification_sprintf"); + string tmp_s; // used by NOTIF_ARGUMENT_LIST + switch (strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_CS_SV(selected, result) case selected: { arg_slot[sel_num++] = result; break; } +#ifdef CSQC + #define ARG_CASE_ARG_CS(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_SV(selected, result) +#else + #define ARG_CASE_ARG_CS(selected, result) + #define ARG_CASE_ARG_SV(selected, result) case selected: { arg_slot[sel_num++] = result; break; } +#endif + #define ARG_CASE_ARG_DC(selected, result) + #define ARG_CASE(prog, selected, result) ARG_CASE_##prog(selected, result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_ARGS, "Local_Notification_sprintf") + } + } + return sprintf( + strcat(input, "\n"), + arg_slot[0], + arg_slot[1], + arg_slot[2], + arg_slot[3], + arg_slot[4], + arg_slot[5], + arg_slot[6] + ); +} + +#ifdef CSQC +void Local_Notification_sound( + int soundchannel, string soundfile, + float soundvolume, float soundposition) +{ + if ((soundfile != prev_soundfile) || (time >= (prev_soundtime + autocvar_cl_announcer_antispam))) + { + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification_sound(%f, '%s', %f, %f);\n", + soundchannel, + sprintf( + "announcer/%s/%s.wav", + AnnouncerOption(), + soundfile + ), + soundvolume, + soundposition + )); + #endif + + _sound( + NULL, + soundchannel, + sprintf( + "announcer/%s/%s.wav", + AnnouncerOption(), + soundfile + ), + soundvolume, + soundposition + ); + + if (prev_soundfile) strunzone(prev_soundfile); + prev_soundfile = strzone(soundfile); + prev_soundtime = time; + } + else + { + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + ( + "Local_Notification_sound(world, %f, '%s', %f, %f) " + "^1BLOCKED BY ANTISPAM:^7 prevsnd: '%s', timediff: %f, limit: %f\n" + ), + soundchannel, + sprintf( + "announcer/%s/%s.wav", + AnnouncerOption(), + soundfile + ), + soundvolume, + soundposition, + prev_soundfile, + (time - prev_soundtime), + autocvar_cl_announcer_antispam + )); + #endif + } +} + +void Local_Notification_HUD_Notify_Push( + string icon, string hudargs, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4) +{ + arg_slot[0] = ""; arg_slot[1] = ""; + + for (int sel_num = 0; (hudargs != ""); ) + { + string selected = car(hudargs); hudargs = cdr(hudargs); + NOTIF_HIT_MAX(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push"); + switch (strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_CS_SV_DC(selected, result) + #define ARG_CASE_ARG_CS_SV(selected, result) + #define ARG_CASE_ARG_CS(selected, result) + #define ARG_CASE_ARG_SV(selected, result) + #define ARG_CASE_ARG_DC(selected, result) + #define ARG_CASE(prog, selected, result) ARG_CASE_##prog(selected, result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: NOTIF_HIT_UNKNOWN(NOTIF_MAX_HUDARGS, "Local_Notification_HUD_Notify_Push") + } + } + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification_HUD_Notify_Push('%s^7', '%s', %s, %s, %s);\n", + icon, + hudargs, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4), + MakeConsoleSafe(sprintf("'%s^7', '%s^7'", stof(arg_slot[0]), stof(arg_slot[1]))) + )); + #endif + HUD_Notify_Push(icon, arg_slot[0], arg_slot[1]); +} + +void Local_Notification_centerprint_generic( + string input, string durcnt, + CPID cpid, float f1, float f2) +{ + arg_slot[0] = ""; arg_slot[1] = ""; + + for (int sel_num = 0; (durcnt != ""); ) + { + string selected = car(durcnt); durcnt = cdr(durcnt); + NOTIF_HIT_MAX(NOTIF_MAX_DURCNT, "Local_Notification_centerprint_generic"); + switch (strtolower(selected)) + { + #define ARG_CASE_ARG_CS_SV_HA(selected, result) + #define ARG_CASE_ARG_CS_SV_DC(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE_ARG_CS_SV(selected, result) + #define ARG_CASE_ARG_CS(selected, result) + #define ARG_CASE_ARG_SV(selected, result) + #define ARG_CASE_ARG_DC(selected, result) case selected: { arg_slot[sel_num++] = result; break; } + #define ARG_CASE(prog, selected, result) ARG_CASE_##prog(selected,result) + NOTIF_ARGUMENT_LIST + #undef ARG_CASE + #undef ARG_CASE_ARG_DC + #undef ARG_CASE_ARG_SV + #undef ARG_CASE_ARG_CS + #undef ARG_CASE_ARG_CS_SV + #undef ARG_CASE_ARG_CS_SV_DC + #undef ARG_CASE_ARG_CS_SV_HA + default: + { + if (/* wtf */ ftos(stof(selected)) != "") { arg_slot[sel_num++] = selected; } + else { NOTIF_HIT_UNKNOWN(NOTIF_MAX_DURCNT, "Local_Notification_centerprint_generic") } + break; + } + } + } + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification_centerprint_generic('%s^7', '%s', %d, %d, %d, %d);\n", + MakeConsoleSafe(input), + durcnt, + f1, f2, + stof(arg_slot[0]), + stof(arg_slot[1]) + )); + #endif + centerprint_generic(ORDINAL(cpid), input, stof(arg_slot[0]), stof(arg_slot[1])); +} +#endif + +void Local_Notification(MSG net_type, Notification net_name, ...count) +{ + // retreive entity of this notification + entity notif = net_name; + if (!notif) + { + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification(%s, NULL, ...);\n", + Get_Notif_TypeName(net_type) + )); + #endif + LOG_WARNINGF("Incorrect usage of Local_Notification: %s\n", "Null notification"); + return; + } + + // check if the notification is enabled + if (!notif.nent_enabled) + { + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification(%s, %s, ...): Entity was disabled...\n", + Get_Notif_TypeName(net_type), + notif.nent_name + )); + #endif + return; + } + + string s1 = ((notif.nent_stringcount > 0) ? ...(0, string) : ""); + string s2 = ((notif.nent_stringcount > 1) ? ...(1, string) : ""); + string s3 = ((notif.nent_stringcount > 2) ? ...(2, string) : ""); + string s4 = ((notif.nent_stringcount > 3) ? ...(3, string) : ""); + float f1 = ((notif.nent_floatcount > 0) ? ...((notif.nent_stringcount + 0), float) : 0); + float f2 = ((notif.nent_floatcount > 1) ? ...((notif.nent_stringcount + 1), float) : 0); + float f3 = ((notif.nent_floatcount > 2) ? ...((notif.nent_stringcount + 2), float) : 0); + float f4 = ((notif.nent_floatcount > 3) ? ...((notif.nent_stringcount + 3), float) : 0); + + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Local_Notification(%s, %s, %s, %s);\n", + Get_Notif_TypeName(net_type), + notif.nent_name, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + if ((notif.nent_stringcount + notif.nent_floatcount) != count) + { + backtrace(sprintf( + ( + "Arguments mismatch for Local_Notification(%s, %s, ...)! " + "stringcount(%d) + floatcount(%d) != count(%d)\n" + "Check the definition and function call for accuracy...?\n" + ), + Get_Notif_TypeName(net_type), + notif.nent_name, + notif.nent_stringcount, + notif.nent_floatcount, + count + )); + return; + } + + switch (net_type) + { + case MSG_ANNCE: + { + #ifdef CSQC + Local_Notification_sound( + notif.nent_channel, + notif.nent_snd, + notif.nent_vol, + notif.nent_position + ); + #else + backtrace("MSG_ANNCE on server?... Please notify Samual immediately!\n"); + #endif + break; + } + + case MSG_INFO: + { + print( + Local_Notification_sprintf( + notif.nent_string, + notif.nent_args, + s1, s2, s3, s4, + f1, f2, f3, f4) + ); + #ifdef CSQC + if (notif.nent_icon != "") + { + if (notif.nent_iconargs != "") + { + string s = Local_Notification_sprintf( + notif.nent_icon,notif.nent_iconargs, + s1, s2, s3, s4, f1, f2, f3, f4); + // remove the trailing newline + notif.nent_icon = strzone(substring(s, 0, -1)); + } + Local_Notification_HUD_Notify_Push( + notif.nent_icon, + notif.nent_hudargs, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + #endif + break; + } + + #ifdef CSQC + case MSG_CENTER: + { + Local_Notification_centerprint_generic( + Local_Notification_sprintf( + notif.nent_string, + notif.nent_args, + s1, s2, s3, s4, + f1, f2, f3, f4), + notif.nent_durcnt, + notif.nent_cpid, + f1, f2); + break; + } + #endif + + case MSG_MULTI: + { + if (notif.nent_msginfo && notif.nent_msginfo.nent_enabled) + { + Local_Notification_WOVA( + MSG_INFO, + notif.nent_msginfo, + notif.nent_msginfo.nent_stringcount, + notif.nent_msginfo.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + #ifdef CSQC + if (notif.nent_msgannce && notif.nent_msgannce.nent_enabled) + { + Local_Notification_WOVA( + MSG_ANNCE, + notif.nent_msgannce, + 0, 0, + "", "", "", "", + 0, 0, 0, 0); + } + if (notif.nent_msgcenter && notif.nent_msgcenter.nent_enabled) + { + Local_Notification_WOVA( + MSG_CENTER, + notif.nent_msgcenter, + notif.nent_msgcenter.nent_stringcount, + notif.nent_msgcenter.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + #endif + break; + } + + case MSG_CHOICE: + { + entity found_choice = notif.nent_optiona; + if (notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) { + switch (cvar(sprintf("notification_%s", notif.nent_name))) + { + case 1: break; + case 2: found_choice = notif.nent_optionb; break; + default: return; // not enabled anyway + } + } + + Local_Notification_WOVA( + found_choice.nent_type, + found_choice, + found_choice.nent_stringcount, + found_choice.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + } +} + +// WOVA = Without Variable Arguments +void Local_Notification_WOVA( + MSG net_type, Notification net_name, + float stringcount, float floatcount, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4) +{ + #define VARITEM(stringc, floatc, args) \ + if ((stringcount == stringc) && (floatcount == floatc)) \ + { Local_Notification(net_type, net_name, args); return; } + EIGHT_VARS_TO_VARARGS_VARLIST + #undef VARITEM + Local_Notification(net_type, net_name); // some notifications don't have any arguments at all +} + + +// ========================= +// Notification Networking +// ========================= + +/** networked as a linked entity to give newly connecting clients some notification context */ +REGISTER_NET_LINKED(ENT_CLIENT_NOTIFICATION) + +#ifdef CSQC +NET_HANDLE(ENT_CLIENT_NOTIFICATION, bool is_new) +{ + make_pure(this); + MSG net_type = ENUMCAST(MSG, ReadByte()); + int net_name = ReadShort(); + return = true; + + if (net_type == MSG_CENTER_KILL) + { + if (!is_new) return; + // killing + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Read_Notification(%d) at %f: net_type = %s, cpid = %d\n", + is_new, + time, + Get_Notif_TypeName(net_type), + net_name + )); + #endif + int _net_name = net_name; + CPID net_name = ENUMCAST(CPID, _net_name); + if (net_name == CPID_Null) { + // kill all + reset_centerprint_messages(); + } else { + // kill group + centerprint_generic(ORDINAL(net_name), "", 0, 0); + } + return; + } + + Notification notif = Get_Notif_Ent(net_type, net_name); + + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Read_Notification(%d) at %f: net_type = %s, net_name = %s (%d)\n", + is_new, + time, + Get_Notif_TypeName(net_type), + notif.registered_id, + net_name + )); + #endif + + if (!notif) { + backtrace("Read_Notification: Could not find notification entity!\n"); + return false; + } + + string s1 = ((notif.nent_stringcount > 0) ? ReadString() : ""); + string s2 = ((notif.nent_stringcount > 1) ? ReadString() : ""); + string s3 = ((notif.nent_stringcount > 2) ? ReadString() : ""); + string s4 = ((notif.nent_stringcount > 3) ? ReadString() : ""); + float f1 = ((notif.nent_floatcount > 0) ? ReadLong() : 0); + float f2 = ((notif.nent_floatcount > 1) ? ReadLong() : 0); + float f3 = ((notif.nent_floatcount > 2) ? ReadLong() : 0); + float f4 = ((notif.nent_floatcount > 3) ? ReadLong() : 0); + + if (!is_new) return; + Local_Notification_WOVA( + net_type, notif, + notif.nent_stringcount, + notif.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); +} +#endif + +#ifdef SVQC +void Net_Notification_Remove() +{ + SELFPARAM(); + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Net_Notification_Remove() at %f: %s '%s - %s' notification\n", + time, + ((this.nent_net_name == -1) ? "Killed" : "Removed"), + Get_Notif_TypeName(this.nent_net_type), + this.owner.nent_name + )); + #endif + for (int i = 0; i < this.nent_stringcount; ++i) { if (this.nent_strings[i]) strunzone(this.nent_strings[i]); } + remove(this); +} + +bool Net_Write_Notification(entity this, entity client, int sf) +{ + if (!Notification_ShouldSend(this.nent_broadcast, client, this.nent_client)) return false; + WriteHeader(MSG_ENTITY, ENT_CLIENT_NOTIFICATION); + WriteByte(MSG_ENTITY, ORDINAL(this.nent_net_type)); + WriteShort(MSG_ENTITY, this.nent_net_name); + for (int i = 0; i < this.nent_stringcount; ++i) { WriteString(MSG_ENTITY, this.nent_strings[i]); } + for (int i = 0; i < this.nent_floatcount; ++i) { WriteLong(MSG_ENTITY, this.nent_floats[i]); } + return true; +} + +void Kill_Notification( + NOTIF broadcast, entity client, + /** message group, MSG_Null for all */ + MSG net_type, + /** cpid group, CPID_Null for all */ + CPID net_cpid) +{ + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Kill_Notification(%s, '%s', %s, %d);\n", + Get_Notif_BroadcastName(broadcast), + client.netname, + (net_type ? Get_Notif_TypeName(net_type) : "0"), + net_cpid + )); + #endif + + string checkargs = Notification_CheckArgs(broadcast, client); + if (checkargs != "") { LOG_WARNINGF("Incorrect usage of Kill_Notification: %s", checkargs); return; } + + entity net_notif = new_pure(net_kill_notification); + net_notif.nent_broadcast = broadcast; + net_notif.nent_client = client; + net_notif.nent_net_type = MSG_CENTER_KILL; + net_notif.nent_net_name = ORDINAL(net_cpid); + Net_LinkEntity(net_notif, false, autocvar_notification_lifetime_runtime, Net_Write_Notification); + + FOREACH_ENTITY_CLASS( + "net_notification", + (it.owner.nent_type == net_type || net_type == MSG_Null) && (it.owner.nent_cpid == net_cpid || net_cpid == CPID_Null), + { + it.nent_net_name = -1; + it.nextthink = time; + } + ); +} + +void Send_Notification( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + ...count) +{ + if (!IS_REAL_CLIENT(client)) return; + entity notif = net_name; + string parms = sprintf("%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + client.classname, + Get_Notif_TypeName(net_type), + net_name.registered_id + ); + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf("Send_Notification(%s, ...%d);\n", parms, count)); + #endif + + if (!notif) + { + LOG_WARNING("Send_Notification: Could not find notification entity!"); + return; + } + + // check supplied broadcast, target, type, and name for errors + string checkargs = Notification_CheckArgs(broadcast, client); + if (!net_name) { checkargs = sprintf("No notification provided! %s", checkargs); } + if (checkargs != "") + { + LOG_WARNINGF("Incorrect usage of Send_Notification: %s", checkargs); + return; + } + + string s1 = ((0 < notif.nent_stringcount) ? ...(0, string) : ""); + string s2 = ((1 < notif.nent_stringcount) ? ...(1, string) : ""); + string s3 = ((2 < notif.nent_stringcount) ? ...(2, string) : ""); + string s4 = ((3 < notif.nent_stringcount) ? ...(3, string) : ""); + float f1 = ((0 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 0), float) : 0); + float f2 = ((1 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 1), float) : 0); + float f3 = ((2 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 2), float) : 0); + float f4 = ((3 < notif.nent_floatcount) ? ...((notif.nent_stringcount + 3), float) : 0); + + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Send_Notification(%s, %s, %s);\n", + parms, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + if ((notif.nent_stringcount + notif.nent_floatcount) != count) + { + LOG_WARNINGF( + "Argument mismatch for Send_Notification(%s, ...)! " + "stringcount(%d) + floatcount(%d) != count(%d)\n" + "Check the definition and function call for accuracy...?\n", + parms, + notif.nent_stringcount, + notif.nent_floatcount, + count + ); + return; + } + + if ( + server_is_dedicated + && + ( + broadcast == NOTIF_ALL + || + broadcast == NOTIF_ALL_EXCEPT + ) + && + !( + net_type == MSG_ANNCE + || + net_type == MSG_CENTER + ) + ) + { + Local_Notification_WOVA( + net_type, net_name, + notif.nent_stringcount, + notif.nent_floatcount, + s1, s2, s3, s4, + f1, f2, f3, f4); + } + + if (net_type == MSG_CHOICE) + { + // THIS GETS TRICKY... now we have to cycle through each possible player (checking broadcast) + // and then do an individual NOTIF_ONE_ONLY recursive call for each one depending on their option... + // It's slow, but it's better than the alternatives: + // 1. Constantly networking all info and letting client decide + // 2. Manually handling each separate call on per-usage basis (See old CTF usage of verbose) + entity found_choice; + + #define RECURSE_FROM_CHOICE(ent,action) MACRO_BEGIN { \ + if (notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) { \ + switch (ent.msg_choice_choices[net_name.nent_choice_idx]) \ + { \ + case 1: found_choice = notif.nent_optiona; break; \ + case 2: found_choice = notif.nent_optionb; break; \ + default: action; \ + } \ + } else { \ + found_choice = notif.nent_optiona; \ + } \ + Send_Notification_WOVA( \ + NOTIF_ONE_ONLY, \ + ent, \ + found_choice.nent_type, \ + found_choice, \ + found_choice.nent_stringcount, \ + found_choice.nent_floatcount, \ + s1, s2, s3, s4, \ + f1, f2, f3, f4); \ + } MACRO_END + + switch (broadcast) + { + case NOTIF_ONE_ONLY: // we can potentially save processing power with this broadcast method + { + if (IS_REAL_CLIENT(client)) { + RECURSE_FROM_CHOICE(client, return); + } + break; + } + default: + { + FOREACH_CLIENT(IS_REAL_CLIENT(it) && Notification_ShouldSend(broadcast, it, client), { + RECURSE_FROM_CHOICE(it, continue); + }); + break; + } + } + } + else + { + entity net_notif = new_pure(net_notification); + net_notif.owner = notif; + net_notif.nent_broadcast = broadcast; + net_notif.nent_client = client; + net_notif.nent_net_type = net_type; + net_notif.nent_net_name = notif.m_id; + net_notif.nent_stringcount = notif.nent_stringcount; + net_notif.nent_floatcount = notif.nent_floatcount; + + for (int i = 0; i < net_notif.nent_stringcount; ++i) { + net_notif.nent_strings[i] = strzone(...(i, string)); + } + for (int i = 0; i < net_notif.nent_floatcount; ++i) { + net_notif.nent_floats[i] = ...((net_notif.nent_stringcount + i), float); + } + + net_notif.think = Net_Notification_Remove; + net_notif.nextthink = (time > autocvar_notification_lifetime_mapload) + ? (time + autocvar_notification_lifetime_runtime) + : autocvar_notification_lifetime_mapload; + + Net_LinkEntity(net_notif, false, 0, Net_Write_Notification); + } +} + +// WOVA = Without Variable Arguments +void Send_Notification_WOVA( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + float stringcount, float floatcount, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4) +{ + #ifdef NOTIFICATIONS_DEBUG + entity notif = net_name; + Debug_Notification(sprintf( + "Send_Notification_WOVA(%s, %d, %d, %s, %s);\n", + sprintf( + "%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + client.classname, + Get_Notif_TypeName(net_type), + notif.nent_name + ), + stringcount, + floatcount, + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + #define VARITEM(stringc, floatc, args) \ + if ((stringcount == stringc) && (floatcount == floatc)) \ + { Send_Notification(broadcast, client, net_type, net_name, args); return; } + EIGHT_VARS_TO_VARARGS_VARLIST + #undef VARITEM + Send_Notification(broadcast, client, net_type, net_name); // some notifications don't have any arguments at all +} + +// WOCOVA = Without Counts Or Variable Arguments +void Send_Notification_WOCOVA( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4) +{ + entity notif = net_name; + + #ifdef NOTIFICATIONS_DEBUG + Debug_Notification(sprintf( + "Send_Notification_WOCOVA(%s, %s, %s);\n", + sprintf( + "%s, '%s', %s, %s", + Get_Notif_BroadcastName(broadcast), + client.classname, + Get_Notif_TypeName(net_type), + notif.nent_name + ), + MakeConsoleSafe(sprintf("'%s^7', '%s^7', '%s^7', '%s^7'", s1, s2, s3, s4)), + sprintf("%d, %d, %d, %d", f1, f2, f3, f4) + )); + #endif + + #define VARITEM(stringc, floatc, args) \ + if ((notif.nent_stringcount == stringc) && (notif.nent_floatcount == floatc)) \ + { Send_Notification(broadcast, client, net_type, net_name, args); return; } + EIGHT_VARS_TO_VARARGS_VARLIST + #undef VARITEM + Send_Notification(broadcast, client, net_type, net_name); // some notifications don't have any arguments at all +} +#endif // ifdef SVQC diff --git a/qcsrc/common/notifications/all.qh b/qcsrc/common/notifications/all.qh new file mode 100644 index 000000000..8f00087c0 --- /dev/null +++ b/qcsrc/common/notifications/all.qh @@ -0,0 +1,804 @@ +#ifndef NOTIFICATIONS_H +#define NOTIFICATIONS_H + +#include + +#include +#include +#include + +/** main types/groups of notifications */ +ENUMCLASS(MSG) + /** "Global" AND "personal" announcer messages */ + CASE(MSG, ANNCE) + /** "Global" information messages */ + CASE(MSG, INFO) + /** "Personal" centerprint messages */ + CASE(MSG, CENTER) + /** Subcall MSG_INFO and/or MSG_CENTER notifications */ + CASE(MSG, MULTI) + /** Choose which subcall wrapper to activate */ + CASE(MSG, CHOICE) + /** Kill centerprint message @deprecated */ + CASE(MSG, CENTER_KILL) +ENUMCLASS_END(MSG) + +string Get_Notif_TypeName(MSG net_type) +{ + switch (net_type) + { + case MSG_ANNCE: return "MSG_ANNCE"; + case MSG_INFO: return "MSG_INFO"; + case MSG_CENTER: return "MSG_CENTER"; + case MSG_MULTI: return "MSG_MULTI"; + case MSG_CHOICE: return "MSG_CHOICE"; + } + LOG_WARNINGF("Get_Notif_TypeName(%d): Improper net type!\n", ORDINAL(net_type)); + return ""; +} + +ENUMCLASS(CPID) + CASE(CPID, ASSAULT_ROLE) + CASE(CPID, ROUND) + CASE(CPID, CAMPCHECK) + CASE(CPID, CTF_CAPSHIELD) + CASE(CPID, CTF_LOWPRIO) + CASE(CPID, CTF_PASS) + CASE(CPID, STALEMATE) + CASE(CPID, NADES) + CASE(CPID, IDLING) + CASE(CPID, ITEM) + CASE(CPID, PREVENT_JOIN) + CASE(CPID, KEEPAWAY) + CASE(CPID, KEEPAWAY_WARN) + CASE(CPID, KEYHUNT) + CASE(CPID, KEYHUNT_OTHER) + CASE(CPID, LMS) + CASE(CPID, MISSING_TEAMS) + CASE(CPID, MISSING_PLAYERS) + CASE(CPID, INSTAGIB_FINDAMMO) + CASE(CPID, MOTD) + CASE(CPID, NIX) + CASE(CPID, ONSLAUGHT) + CASE(CPID, ONS_CAPSHIELD) + CASE(CPID, OVERTIME) + CASE(CPID, POWERUP) + CASE(CPID, RACE_FINISHLAP) + CASE(CPID, TEAMCHANGE) + CASE(CPID, TIMEOUT) + CASE(CPID, VEHICLES) + CASE(CPID, VEHICLES_OTHER) + /** always last */ + CASE(CPID, LAST) +ENUMCLASS_END(CPID) + +typedef entity Notification; + +// used for notification system multi-team identifiers +#define APP_TEAM_NUM(num, prefix) ((num == NUM_TEAM_1) ? prefix##_RED : ((num == NUM_TEAM_2) ? prefix##_BLUE : ((num == NUM_TEAM_3) ? prefix##_YELLOW : prefix##_PINK))) +/** @deprecated use APP_TEAM_NUM */ +#define APP_TEAM_ENT(ent, prefix) APP_TEAM_NUM(ent.team, prefix) + +#define EIGHT_VARS_TO_VARARGS_VARLIST \ + VARITEM(1, 0, s1) \ + VARITEM(2, 0, XPD(s1, s2)) \ + VARITEM(3, 0, XPD(s1, s2, s3)) \ + VARITEM(4, 0, XPD(s1, s2, s3, s4)) \ + VARITEM(0, 1, f1) \ + VARITEM(1, 1, XPD(s1, f1)) \ + VARITEM(2, 1, XPD(s1, s2, f1)) \ + VARITEM(3, 1, XPD(s1, s2, s3, f1)) \ + VARITEM(4, 1, XPD(s1, s2, s3, s4, f1)) \ + VARITEM(0, 2, XPD(f1, f2)) \ + VARITEM(1, 2, XPD(s1, f1, f2)) \ + VARITEM(2, 2, XPD(s1, s2, f1, f2)) \ + VARITEM(3, 2, XPD(s1, s2, s3, f1, f2)) \ + VARITEM(4, 2, XPD(s1, s2, s3, s4, f1, f2)) \ + VARITEM(0, 3, XPD(f1, f2, f3)) \ + VARITEM(1, 3, XPD(s1, f1, f2, f3)) \ + VARITEM(2, 3, XPD(s1, s2, f1, f2, f3)) \ + VARITEM(3, 3, XPD(s1, s2, s3, f1, f2, f3)) \ + VARITEM(4, 3, XPD(s1, s2, s3, s4, f1, f2, f3)) \ + VARITEM(0, 4, XPD(f1, f2, f3, f4)) \ + VARITEM(1, 4, XPD(s1, f1, f2, f3, f4)) \ + VARITEM(2, 4, XPD(s1, s2, f1, f2, f3, f4)) \ + VARITEM(3, 4, XPD(s1, s2, s3, f1, f2, f3, f4)) \ + VARITEM(4, 4, XPD(s1, s2, s3, s4, f1, f2, f3, f4)) + +void Destroy_All_Notifications(); +void Create_Notification_Entity(entity notif, + float var_default, + float var_cvar, + MSG typeId, + string namestring); +void Create_Notification_Entity_Annce(entity notif, + float var_cvar, + string namestring, + /* MSG_ANNCE */ + float channel, + string snd, + float vol, + float position); + +void Create_Notification_Entity_InfoCenter(entity notif, + float var_cvar, + string namestring, + int strnum, + int flnum, + /* MSG_INFO & MSG_CENTER */ + string args, + string hudargs, + string icon, + CPID cpid, + string durcnt, + string normal, + string gentle); + +void Create_Notification_Entity_Multi(entity notif, + float var_cvar, + string namestring, + /* MSG_MULTI */ + Notification anncename, + Notification infoname, + Notification centername); + +void Create_Notification_Entity_Choice(entity notif, + float var_cvar, + string namestring, + /* MSG_CHOICE */ + float challow_def, + float challow_var, + MSG chtype, + Notification optiona, + Notification optionb); + +void Dump_Notifications(int fh, bool alsoprint); + +GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt") +{ + switch (request) + { + case CMD_REQUEST_COMMAND: + { + #ifndef MENUQC + string filename = argv(1); + bool alsoprint = false; + if (filename == "") + { + filename = "notifications_dump.cfg"; + alsoprint = false; + } + else if (filename == "-") + { + filename = "notifications_dump.cfg"; + alsoprint = true; + } + int fh = fopen(filename, FILE_WRITE); + if (fh >= 0) + { + Dump_Notifications(fh, alsoprint); + LOG_INFOF("Dumping notifications... File located in ^2data/data/%s^7.\n", filename); + fclose(fh); + } + else + { + LOG_INFOF("^1Error: ^7Could not open file '%s'!\n", filename); + } + #else + LOG_INFO(_("Notification dump command only works with cl_cmd and sv_cmd.\n")); + #endif + return; + } + default: + case CMD_REQUEST_USAGE: + { + LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpnotifs [filename]")); + LOG_INFO(" Where 'filename' is the file to write (default is notifications_dump.cfg),\n"); + LOG_INFO(" if supplied with '-' output to console as well as default,\n"); + LOG_INFO(" if left blank, it will only write to default.\n"); + return; + } + } +} + +#ifdef NOTIFICATIONS_DEBUG +void Debug_Notification(string input) +{ + switch (autocvar_notification_debug) + { + case 1: { LOG_TRACE(input); break; } + case 2: { LOG_INFO(input); break; } + } +} +#endif + +void Local_Notification(MSG net_type, Notification net_name, ...count); +/** glue for networking, forwards to `Local_Notification` */ +void Local_Notification_WOVA( + MSG net_type, Notification net_name, + float stringcount, float floatcount, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4); + +#ifdef CSQC +string prev_soundfile; +float prev_soundtime; +#endif + +#ifdef SVQC +ENUMCLASS(NOTIF) + /** send to one client and their spectators */ + CASE(NOTIF, ONE) + /** send ONLY to one client */ + CASE(NOTIF, ONE_ONLY) + /** send only to X team and their spectators */ + CASE(NOTIF, TEAM) + /** send only to X team and their spectators, except for Y person and their spectators */ + CASE(NOTIF, TEAM_EXCEPT) + /** send to everyone */ + CASE(NOTIF, ALL) + /** send to everyone except X person and their spectators */ + CASE(NOTIF, ALL_EXCEPT) +ENUMCLASS_END(NOTIF) + +string Get_Notif_BroadcastName(NOTIF broadcast) +{ + switch (broadcast) + { + case NOTIF_ONE: return "NOTIF_ONE"; + case NOTIF_ONE_ONLY: return "NOTIF_ONE_ONLY"; + case NOTIF_ALL_EXCEPT: return "NOTIF_ALL_EXCEPT"; + case NOTIF_ALL: return "NOTIF_ALL"; + case NOTIF_TEAM: return "NOTIF_TEAM"; + case NOTIF_TEAM_EXCEPT: return "NOTIF_TEAM_EXCEPT"; + } + LOG_WARNINGF("Get_Notif_BroadcastName(%d): Improper broadcast!\n", broadcast); + return ""; +} + +void Kill_Notification( + NOTIF broadcast, entity client, + MSG net_type, CPID net_name); +void Send_Notification( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + ...count); +void Send_Notification_WOVA( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + float stringcount, float floatcount, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4); +void Send_Notification_WOCOVA( + NOTIF broadcast, entity client, + MSG net_type, Notification net_name, + string s1, string s2, string s3, string s4, + float f1, float f2, float f3, float f4); +#endif + +// =========================== +// Special CVAR Declarations +// =========================== + +// MAKE SURE THIS IS ALWAYS SYNCHRONIZED WITH THE DUMP +// NOTIFICATIONS FUNCTION IN THE .QC FILE! + +#define NOTIF_ADD_AUTOCVAR(name,default) float autocvar_notification_##name = default; + +float autocvar_notification_show_location = false; +string autocvar_notification_show_location_string = ""; //_(" at the %s"); +float autocvar_notification_show_sprees = true; +float autocvar_notification_show_sprees_info = 3; // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker +float autocvar_notification_show_sprees_info_newline = true; +float autocvar_notification_show_sprees_info_specialonly = true; +float autocvar_notification_errors_are_fatal = true; +float autocvar_notification_lifetime_runtime = 0.5; +float autocvar_notification_lifetime_mapload = 10; +float autocvar_notification_debug = false; + +#ifdef SVQC +.float FRAG_VERBOSE; +void Notification_GetCvars(); +float autocvar_notification_server_allows_location = 1; // 0 = no, 1 = yes +#else +float autocvar_notification_item_centerprinttime = 1.5; + +// 0 = no, 1 = yes, 2 = forced on for all MSG_INFO notifs +// DISABLED IN CODE, BUT ENABLED IN CONFIG FOR COMPATIBILITY WITH OLD CLIENTS +float autocvar_notification_allow_chatboxprint = 0; + +float autocvar_notification_show_sprees_center = true; +float autocvar_notification_show_sprees_center_specialonly = true; +#endif + + +// ============================ +// Notification Argument List +// ============================ +/* + These arguments get replaced with the Local_Notification_sprintf + and other such functions found in all.qc to supply data + from networked notifications to their usage in sprintf... It + allows for more dynamic data to be inferred by the local + notification parser, so that the server does not have to network + anything too crazy on a per-client/per-situation basis. + + Pay attention to the CSQC/SVQC relations, some of these are redefined + in slightly different ways for different programs, this is because the + server does a more conservative approach to the notifs than the client. + + All arguments are swapped into strings, so be sure that your + sprintf usage matches with proper %s placement. + + Argument descriptions: + s1-s4: string arguments to be literally swapped into sprintf + s2loc: s2 string of locations of deaths or other events + s3loc: s3 string of locations of deaths or other events + f1-f4: float arguments expanded into strings to be swapped into sprintf + f1p2dec: f1 float to string with 2 decimal places + f2p2dec: f2 float to string with 2 decimal places + f2primsec: f2 float primary or secondary selection for weapons + f3primsec: f3 float primary or secondary selection for weapons + f1secs: count_seconds of f1 + f1points: point or points depending on f1 + f1ord: count_ordinal of f1 + f1time: process_time of f1 + f1race_time: mmssss of f1 + f2race_time: mmssss of f2 + race_col: color of race time/position (i.e. good or bad) + race_diff: show time difference between f2 and f3 + missing_teams: show which teams still need players + pass_key: find the keybind for "passing" or "dropping" in CTF game mode + frag_ping: show the ping of a player + frag_stats: show health/armor/ping of a player + frag_pos: show score status and position in the match of a player + spree_cen: centerprint notif for kill spree/how many kills they have + spree_inf: info notif for kill spree/how many kills they have + spree_end: placed at the end of murder messages to show ending of sprees + spree_lost: placed at the end of suicide messages to show losing of sprees + item_wepname: return full name of a weapon from weaponid + item_wepammo: ammo display for weapon from string + item_centime: amount of time to display weapon message in centerprint + item_buffname: return full name of a buff from buffid + death_team: show the full name of the team a player is switching from + minigame1_name: return human readable name of a minigame from its id(s1) + minigame1_d: return descriptor name of a minigame from its id(s1) +*/ + +const float NOTIF_MAX_ARGS = 7; +const float NOTIF_MAX_HUDARGS = 2; +const float NOTIF_MAX_DURCNT = 2; + +string arg_slot[NOTIF_MAX_ARGS]; + +const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs +const float ARG_CS_SV_DC = 2; // enabled on CSQC, SVQC, and durcnt centerprint +const float ARG_CS_SV = 3; // enabled on CSQC and SVQC +const float ARG_CS = 4; // unique result to CSQC +const float ARG_SV = 5; // unique result to SVQC +const float ARG_DC = 6; // unique result to durcnt/centerprint + +// todo possible idea.... declare how many floats/strings each arg needs, and then dynamically increment the input +// this way, we don't need to have duplicates like i.e. s2loc and s3loc? + +string BUFF_NAME(int i); + +#define NOTIF_ARGUMENT_LIST \ + ARG_CASE(ARG_CS_SV_HA, "s1", s1) \ + ARG_CASE(ARG_CS_SV_HA, "s2", s2) \ + ARG_CASE(ARG_CS_SV_HA, "s3", s3) \ + ARG_CASE(ARG_CS_SV_HA, "s4", s4) \ + ARG_CASE(ARG_CS_SV, "s2loc", ((autocvar_notification_show_location && (s2 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s2) : "")) \ + ARG_CASE(ARG_CS_SV, "s3loc", ((autocvar_notification_show_location && (s3 != "")) ? sprintf(( ((tmp_s = autocvar_notification_show_location_string) != "") ? tmp_s : _(" (near %s)") ), s3) : "")) \ + ARG_CASE(ARG_CS_SV_DC, "f1", ftos(f1)) \ + ARG_CASE(ARG_CS_SV_DC, "f2", ftos(f2)) \ + ARG_CASE(ARG_CS_SV, "f3", ftos(f3)) \ + ARG_CASE(ARG_CS_SV, "f4", ftos(f4)) \ + ARG_CASE(ARG_CS_SV, "f1p2dec", ftos_decimals(f1/100, 2)) \ + ARG_CASE(ARG_CS_SV, "f2p2dec", ftos_decimals(f2/100, 2)) \ + ARG_CASE(ARG_CS, "f2primsec", (f2 ? _("secondary") : _("primary"))) \ + ARG_CASE(ARG_CS, "f3primsec", (f3 ? _("secondary") : _("primary"))) \ + ARG_CASE(ARG_CS, "f1secs", count_seconds(f1)) \ + ARG_CASE(ARG_CS, "f1points", (f1 == 1 ? _("point") : _("points"))) \ + ARG_CASE(ARG_CS_SV, "f1ord", count_ordinal(f1)) \ + ARG_CASE(ARG_CS, "f1time", process_time(2, f1)) \ + ARG_CASE(ARG_CS_SV_HA, "f1race_time", mmssss(f1)) \ + ARG_CASE(ARG_CS_SV_HA, "f2race_time", mmssss(f2)) \ + ARG_CASE(ARG_CS_SV_HA, "f3race_time", mmssss(f3)) \ + ARG_CASE(ARG_CS_SV, "race_col", CCR(((f1 == 1) ? "^F1" : "^F2"))) \ + ARG_CASE(ARG_CS_SV, "race_diff", ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2)))) \ + ARG_CASE(ARG_CS, "missing_teams", notif_arg_missing_teams(f1)) \ + ARG_CASE(ARG_CS, "pass_key", ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \ + ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(true, f2)) \ + ARG_CASE(ARG_CS, "frag_stats", notif_arg_frag_stats(f2, f3, f4)) \ + /*ARG_CASE(ARG_CS, "frag_pos", ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \ + ARG_CASE(ARG_CS, "spree_cen", (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \ + ARG_CASE(ARG_CS_SV, "spree_inf", (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \ + ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \ + ARG_CASE(ARG_CS_SV, "spree_lost", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \ + ARG_CASE(ARG_CS_SV, "item_wepname", Weapons_from(f1).m_name) \ + ARG_CASE(ARG_CS_SV, "item_buffname", BUFF_NAME(f1)) \ + ARG_CASE(ARG_CS_SV, "f3buffname", BUFF_NAME(f3)) \ + ARG_CASE(ARG_CS_SV, "item_wepammo", (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \ + ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \ + ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \ + ARG_CASE(ARG_CS, "death_team", Team_ColoredFullName(f1 - 1)) \ + ARG_CASE(ARG_CS_SV_HA, "minigame1_name",find(world,netname,s1).descriptor.message) \ + ARG_CASE(ARG_CS_SV_HA, "minigame1_d", find(world,netname,s1).descriptor.netname) + +#define NOTIF_HIT_MAX(count,funcname) MACRO_BEGIN { \ + if(sel_num == count) { backtrace(sprintf("%s: Hit maximum arguments!\n", funcname)); break; } \ +} MACRO_END +#define NOTIF_HIT_UNKNOWN(token,funcname) { backtrace(sprintf("%s: Hit unknown token in selected string! '%s'\n", funcname, selected)); break; } + +#define KILL_SPREE_LIST \ + SPREE_ITEM(3, 03, _("TRIPLE FRAG! "), _("%s^K1 made a TRIPLE FRAG! %s^BG"), _("%s^K1 made a TRIPLE SCORE! %s^BG")) \ + SPREE_ITEM(5, 05, _("RAGE! "), _("%s^K1 unlocked RAGE! %s^BG"), _("%s^K1 made FIVE SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(10, 10, _("MASSACRE! "), _("%s^K1 started a MASSACRE! %s^BG"), _("%s^K1 made TEN SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(15, 15, _("MAYHEM! "), _("%s^K1 executed MAYHEM! %s^BG"), _("%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(20, 20, _("BERSERKER! "), _("%s^K1 is a BERSERKER! %s^BG"), _("%s^K1 made TWENTY SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(25, 25, _("CARNAGE! "), _("%s^K1 inflicts CARNAGE! %s^BG"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG")) \ + SPREE_ITEM(30, 30, _("ARMAGEDDON! "), _("%s^K1 unleashes ARMAGEDDON! %s^BG"), _("%s^K1 made THIRTY SCORES IN A ROW! %s^BG")) + +#ifdef CSQC +string notif_arg_frag_ping(bool newline, float fping) +{ + string s = newline ? "\n" : " "; + if (fping < 0) + return sprintf(CCR(_("%s(^F1Bot^BG)")), s); + else + return sprintf(CCR(_("%s(Ping ^F1%d^BG)")), s, fping); +} + +string notif_arg_frag_stats(float fhealth, float farmor, float fping) +{ + string s = notif_arg_frag_ping(false, fping); + if (fhealth > 1) + return sprintf(CCR(_("\n(Health ^1%d^BG / Armor ^2%d^BG)%s")), fhealth, farmor, s); + else + return sprintf(CCR(_("\n(^F4Dead^BG)%s")), s); +} + +string notif_arg_missing_teams(float f1) +{ + return sprintf("%s%s%s%s", + ((f1 & BIT(0)) ? sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_1), (f1 & (BIT(1) | BIT(2) | BIT(3)) ? ", " : "")) : ""), + ((f1 & BIT(1)) ? sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_2), (f1 & ( BIT(2) | BIT(3)) ? ", " : "")) : ""), + ((f1 & BIT(2)) ? sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_3), (f1 & ( BIT(3)) ? ", " : "")) : ""), + ((f1 & BIT(3)) ? Team_ColoredFullName(NUM_TEAM_4) : "") + ); +} + +string notif_arg_spree_cen(float spree) +{ + // 0 = off, 1 = target (but only for first victim) and attacker + if(autocvar_notification_show_sprees_center) + { + if(spree > 1) + { + #define SPREE_ITEM(counta,countb,center,normal,gentle) \ + case counta: { return normal_or_gentle(center, sprintf(_("%d score spree! "), spree)); } + + switch(spree) + { + KILL_SPREE_LIST + default: + { + if (!autocvar_notification_show_sprees_center_specialonly) + { + return + sprintf( + normal_or_gentle( + _("%d frag spree! "), + _("%d score spree! ") + ), + spree); + } + else { return ""; } // don't show spree information if it isn't an achievement + } + } + + #undef SPREE_ITEM + } + else if(spree == -1) // first blood + { + return normal_or_gentle(_("First blood! "), _("First score! ")); + } + else if(spree == -2) // first victim + { + return normal_or_gentle(_("First victim! "), _("First casualty! ")); + } + } + return ""; +} +#endif + +string notif_arg_spree_inf(float type, string input, string player, float spree) +{ + switch(type) + { + case 1: // attacker kill spree + { + // 0 = off, 1 = target only, 2 = attacker only, 3 = target and attacker + // this conditional (& 2) is true for 2 and 3 + if(autocvar_notification_show_sprees_info & 2) + { + #ifdef CSQC + string spree_newline = + ( autocvar_notification_show_sprees_info_newline ? + ((substring(input, 0, 1) == "\{3}") ? "\n\{3}" : "\n") : "" ); + #else + string spree_newline = + (autocvar_notification_show_sprees_info_newline ? "\n" : ""); + #endif + + if(spree > 1) + { + #define SPREE_ITEM(counta,countb,center,normal,gentle) \ + case counta: { return sprintf(CCR(normal_or_gentle(normal, gentle)), player, spree_newline); } + + switch(spree) + { + KILL_SPREE_LIST + default: + { + if (!autocvar_notification_show_sprees_info_specialonly) + { + return + sprintf( + CCR(normal_or_gentle( + _("%s^K1 has %d frags in a row! %s^BG"), + _("%s^K1 made %d scores in a row! %s^BG") + )), + player, + spree, + spree_newline + ); + } + else { return ""; } // don't show spree information if it isn't an achievement + } + } + + #undef SPREE_ITEM + } + else if(spree == -1) // firstblood + { + return + sprintf( + CCR(normal_or_gentle( + _("%s^K1 drew first blood! %s^BG"), + _("%s^K1 got the first score! %s^BG") + )), + player, + spree_newline + ); + } + } + break; + } + + case -1: // kill spree ended + { + if((spree > 1) && (autocvar_notification_show_sprees_info & 1)) + { + return + sprintf(normal_or_gentle( + _(", ending their %d frag spree"), + _(", ending their %d score spree") + ), + spree + ); + } + break; + } + + case -2: // kill spree lost + { + if((spree > 1) && (autocvar_notification_show_sprees_info & 1)) + { + return + sprintf(normal_or_gentle( + _(", losing their %d frag spree"), + _(", losing their %d score spree") + ), + spree + ); + } + break; + } + } + return ""; +} + + +// ==================================== +// Initialization/Create Declarations +// ==================================== + +// common notification entity values +.int nent_default; +.bool nent_enabled; +.MSG nent_type; +.string nent_name; +.int nent_stringcount; +.int nent_floatcount; + +// MSG_ANNCE entity values +.int nent_channel; +.string nent_snd; +.float nent_vol; +.float nent_position; + +// MSG_INFO and MSG_CENTER entity values +.string nent_args; // used by both +.string nent_hudargs; // used by info +.string nent_icon; // used by info +.CPID nent_cpid; // used by center +.string nent_durcnt; // used by center +.string nent_string; // used by both + +// MSG_MULTI entity values +.entity nent_msgannce; +.entity nent_msginfo; +.entity nent_msgcenter; + +// MSG_CHOICE entity values +.float nent_challow_def; +.float nent_challow_var; +.entity nent_optiona; +.entity nent_optionb; + +// networked notification entity values +#ifdef SVQC +.NOTIF nent_broadcast; +#endif +.entity nent_client; +.MSG nent_net_type; +.float nent_net_name; +.string nent_strings[4]; +.float nent_floats[4]; + +#define ACVNN(name) autocvar_notification_##name + +REGISTRY(Notifications, BITS(11)) +REGISTER_REGISTRY(Notifications) +REGISTRY_SORT(Notifications); STATIC_INIT(Notifications) { FOREACH(Notifications, true, it.m_id = i); } +REGISTRY_CHECK(Notifications) + +const int NOTIF_CHOICE_MAX = 50; +int nent_choice_count = 0; +.int nent_choice_idx; +.int msg_choice_choices[NOTIF_CHOICE_MAX]; // set on each player containing MSG_CHOICE choices +// initialization error detection +bool notif_error; +bool notif_global_error; + +STATIC_INIT_LATE(Notif_Choices) { + int c = 0; + FOREACH(Notifications, it.nent_type == MSG_CHOICE, { c++; }); + if (c > NOTIF_CHOICE_MAX) { + LOG_FATALF("Too many MSG_CHOICE notifications (%d)", c); + } +} + +Notification Get_Notif_Ent(MSG net_type, int net_name) +{ + Notification it = _Notifications_from(net_name, NULL); + if (it.nent_type != net_type) { + LOG_WARNINGF("Get_Notif_Ent(%s (%d), %s (%d)): Improper net type '%s'!\n", + Get_Notif_TypeName(net_type), net_type, + it.registered_id, net_name, + Get_Notif_TypeName(it.nent_type) + ); + return NULL; + } + return it; +} + +#define MSG_ANNCE_NOTIF(name, default, sound, channel, volume, position) \ + MSG_ANNCE_NOTIF_(ANNCE_##name, default, sound, channel, volume, position) +#define MSG_ANNCE_NOTIF_(name, default, sound, channel, volume, position) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_ANNCE, strtoupper(#name)); \ + Create_Notification_Entity_Annce(this, ACVNN(name), strtoupper(#name), \ + channel, /* channel */ \ + sound, /* snd */ \ + volume, /* vol */ \ + position); /* position */ \ + } + +#define MSG_INFO_NOTIF(name, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + MSG_INFO_NOTIF_(INFO_##name, default, strnum, flnum, args, hudargs, icon, normal, gentle) +#define MSG_INFO_NOTIF_(name, default, strnum, flnum, args, hudargs, icon, normal, gentle) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_INFO, strtoupper(#name)); \ + Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \ + args, /* args */ \ + hudargs, /* hudargs */ \ + icon, /* icon */ \ + CPID_Null,/* cpid */ \ + "", /* durcnt */ \ + normal, /* normal */ \ + gentle); /* gentle */ \ + } + +.string nent_iconargs; +#define MULTIICON_INFO(name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \ + MULTIICON_INFO_(INFO_##name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) +#define MULTIICON_INFO_(name, default, strnum, flnum, args, hudargs, iconargs, icon, normal, gentle) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_info_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_INFO, strtoupper(#name)); \ + Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \ + args, /* args */ \ + hudargs, /* hudargs */ \ + icon, /* icon */ \ + CPID_Null,/* cpid */ \ + "", /* durcnt */ \ + normal, /* normal */ \ + gentle); /* gentle */ \ + this.nent_iconargs = iconargs; \ + } + +#define MSG_CENTER_NOTIF(name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + MSG_CENTER_NOTIF_(CENTER_##name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) +#define MSG_CENTER_NOTIF_(name, default, strnum, flnum, args, cpid, durcnt, normal, gentle) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_center_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_CENTER, strtoupper(#name)); \ + Create_Notification_Entity_InfoCenter(this, ACVNN(name), strtoupper(#name), strnum, flnum, \ + args, /* args */ \ + "", /* hudargs */ \ + "", /* icon */ \ + cpid, /* cpid */ \ + durcnt, /* durcnt */ \ + normal, /* normal */ \ + gentle); /* gentle */ \ + } + +#define MSG_MULTI_NOTIF(name, default, anncename, infoname, centername) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + REGISTER(Notifications, name, m_id, new_pure(msg_multi_notification)) { \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_MULTI, strtoupper(#name)); \ + Create_Notification_Entity_Multi(this, ACVNN(name), strtoupper(#name), \ + anncename, /* anncename */ \ + infoname, /* infoname */ \ + centername); /* centername */ \ + } + +#define MSG_CHOICE_NOTIF(name, default, challow, chtype, optiona, optionb) \ + MSG_CHOICE_NOTIF_(CHOICE_##name, default, challow, chtype, optiona, optionb) +#define MSG_CHOICE_NOTIF_(name, default, challow, chtype, optiona, optionb) \ + NOTIF_ADD_AUTOCVAR(name, default) \ + NOTIF_ADD_AUTOCVAR(name##_ALLOWED, challow) \ + REGISTER(Notifications, name, m_id, new_pure(msg_choice_notification)) { \ + this.nent_choice_idx = nent_choice_count++; \ + Create_Notification_Entity (this, default, ACVNN(name), MSG_CHOICE, strtoupper(#name)); \ + Create_Notification_Entity_Choice(this, ACVNN(name), strtoupper(#name), \ + challow, /* challow_def */ \ + autocvar_notification_##name##_ALLOWED, /* challow_var */ \ + chtype, /* chtype */ \ + optiona, /* optiona */ \ + optionb); /* optionb */ \ + } + +REGISTRY_BEGIN(Notifications) +{ + notif_global_error = false; +} + +REGISTRY_END(Notifications) +{ + if (!notif_global_error) return; + // shit happened... stop the loading of the program now if this is unacceptable + if (autocvar_notification_errors_are_fatal) + LOG_FATAL("Notification initialization failed! Read above and fix the errors!"); + else + LOG_SEVERE("Notification initialization failed! Read above and fix the errors!"); +} + +#include "all.inc" + +#endif diff --git a/qcsrc/common/physics/movetypes/movetypes.qc b/qcsrc/common/physics/movetypes/movetypes.qc index 0d6b98eaa..2c9c5894b 100644 --- a/qcsrc/common/physics/movetypes/movetypes.qc +++ b/qcsrc/common/physics/movetypes/movetypes.qc @@ -343,11 +343,10 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this) // SV_LinkEdict_TouchAreaGr entity oldother = other; - for (entity e = findradius(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin)); e; e = e.chain) - { - if(e.solid == SOLID_TRIGGER && e != this) - if(e.move_nomonsters != MOVE_NOMONSTERS && e.move_nomonsters != MOVE_WORLDONLY) - if(e.move_touch && boxesoverlap(e.absmin, e.absmax, this.absmin, this.absmax)) + 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 (it.move_touch && boxesoverlap(it.absmin, it.absmax, this.absmin, this.absmax)) { other = this; @@ -356,14 +355,14 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this) // SV_LinkEdict_TouchAreaGr trace_fraction = 1; trace_inwater = false; trace_inopen = true; - trace_endpos = e.move_origin; + trace_endpos = it.move_origin; trace_plane_normal = '0 0 1'; trace_plane_dist = 0; trace_ent = this; - WITH(entity, self, e, e.move_touch()); + WITH(entity, self, it, it.move_touch()); } - } + }); other = oldother; } @@ -411,8 +410,10 @@ void _Movetype_LinkEdict(entity this, bool touch_triggers) // SV_LinkEdict _Movetype_LinkEdict_TouchAreaGrid(this); } -bool _Movetype_TestEntityPosition(entity this, vector ofs) // SV_TestEntityPosition +entity _Movetype_TestEntityPosition_ent; +bool _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition { + entity this = _Movetype_TestEntityPosition_ent; // vector org = this.move_origin + ofs; int cont = this.dphitcontentsmask; @@ -430,24 +431,30 @@ bool _Movetype_TestEntityPosition(entity this, vector ofs) // SV_TestEntityPosi bool _Movetype_UnstickEntity(entity this) // SV_UnstickEntity { - if(!_Movetype_TestEntityPosition(this, '0 0 0')) return true; - if(!_Movetype_TestEntityPosition(this, '-1 0 0')) goto success; - if(!_Movetype_TestEntityPosition(this, '1 0 0')) goto success; - if(!_Movetype_TestEntityPosition(this, '0 -1 0')) goto success; - if(!_Movetype_TestEntityPosition(this, '0 1 0')) goto success; - if(!_Movetype_TestEntityPosition(this, '-1 -1 0')) goto success; - if(!_Movetype_TestEntityPosition(this, '1 -1 0')) goto success; - if(!_Movetype_TestEntityPosition(this, '-1 1 0')) goto success; - if(!_Movetype_TestEntityPosition(this, '1 1 0')) goto success; - for (int i = 1; i <= 17; ++i) + _Movetype_TestEntityPosition_ent = this; + if (!_Movetype_TestEntityPosition(' 0 0 0')) { + return true; + } + #define X(v) if (_Movetype_TestEntityPosition(v)) + X('-1 0 0') X(' 1 0 0') + X(' 0 -1 0') X(' 0 1 0') + X('-1 -1 0') X(' 1 -1 0') + X('-1 1 0') X(' 1 1 0') + #undef X { - if(!_Movetype_TestEntityPosition(this, '0 0 -1' * i)) goto success; - if(!_Movetype_TestEntityPosition(this, '0 0 1' * i)) goto success; + #define X(i) \ + if (_Movetype_TestEntityPosition('0 0 -1' * i)) \ + if (_Movetype_TestEntityPosition('0 0 1' * i)) + X(01) X(02) X(03) X(04) X(05) X(06) X(07) X(08) + X(09) X(10) X(11) X(12) X(13) X(14) X(15) X(16) + X(17) + #undef X + { + LOG_DEBUGF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n", + etof(this), this.classname, vtos(this.move_origin)); + return false; + } } - LOG_DEBUGF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n", - etof(this), this.classname, vtos(this.move_origin)); - return false; - : success; LOG_DEBUGF("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)\n", etof(this), this.classname, vtos(this.move_origin)); _Movetype_LinkEdict(this, true); diff --git a/qcsrc/common/physics/movetypes/movetypes.qh b/qcsrc/common/physics/movetypes/movetypes.qh index 9342ecb21..ada026df9 100644 --- a/qcsrc/common/physics/movetypes/movetypes.qh +++ b/qcsrc/common/physics/movetypes/movetypes.qh @@ -42,8 +42,6 @@ void _Movetype_CheckWaterTransition(entity ent); float _Movetype_CheckWater(entity ent); void _Movetype_LinkEdict_TouchAreaGrid(entity this); void _Movetype_LinkEdict(entity this, float touch_triggers); -float _Movetype_TestEntityPosition(entity this, vector ofs); -float _Movetype_UnstickEntity(entity this); vector _Movetype_ClipVelocity(vector vel, vector norm, float f); void _Movetype_PushEntityTrace(entity this, vector push); float _Movetype_PushEntity(entity this, vector push, float failonstartsolid); diff --git a/qcsrc/common/physics/movetypes/push.qc b/qcsrc/common/physics/movetypes/push.qc index dc455944c..dd89a4099 100644 --- a/qcsrc/common/physics/movetypes/push.qc +++ b/qcsrc/common/physics/movetypes/push.qc @@ -53,9 +53,8 @@ void _Movetype_PushMove(entity this, float dt) // SV_PushMove if (this.move_movetype != MOVETYPE_FAKEPUSH) { - for (entity check = findradius(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin)); check; check = check.chain) - { - switch (check.move_movetype) + FOREACH_ENTITY_RADIUS(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true, { + switch (it.move_movetype) { case MOVETYPE_NONE: case MOVETYPE_PUSH: @@ -67,17 +66,17 @@ void _Movetype_PushMove(entity this, float dt) // SV_PushMove break; } - if (check.owner == this) + if (it.owner == this) continue; - if (this.owner == check) + if (this.owner == it) continue; - vector pivot = check.mins + 0.5 * (check.maxs - check.mins); + vector pivot = it.mins + 0.5 * (it.maxs - it.mins); vector move; if (rotated) { - vector org = (check.move_origin - this.move_origin) + pivot; + vector org = (it.move_origin - this.move_origin) + pivot; vector org2; org2.x = org * v_forward; org2.y = org * v_right; @@ -90,34 +89,34 @@ void _Movetype_PushMove(entity this, float dt) // SV_PushMove } // physics objects need better collisions than this code can do - if (check.move_movetype == 32) // MOVETYPE_PHYSICS + if (it.move_movetype == 32) // MOVETYPE_PHYSICS { - check.move_origin = check.move_origin + move; - _Movetype_LinkEdict(check, true); + it.move_origin = it.move_origin + move; + _Movetype_LinkEdict(it, true); continue; } // try moving the contacted entity this.solid = SOLID_NOT; bool flag = false; - flag = _Movetype_PushEntity(check, move, true); + flag = _Movetype_PushEntity(it, move, true); if (!flag) { - // entity "check" got teleported - check.move_angles_y += trace_fraction * moveangle.y; + // entity "it" got teleported + it.move_angles_y += trace_fraction * moveangle.y; this.solid = savesolid; continue; // pushed enough } // FIXME: turn players specially - check.move_angles_y += trace_fraction * moveangle.y; + it.move_angles_y += trace_fraction * moveangle.y; this.solid = savesolid; // this trace.fraction < 1 check causes items to fall off of pushers // if they pass under or through a wall // the groundentity check causes items to fall off of ledges - if (check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != this)) - check.move_flags &= ~FL_ONGROUND; - } + if (it.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || it.move_groundentity != this)) + it.move_flags &= ~FL_ONGROUND; + }); } this.move_angles_x -= 360.0 * floor(this.move_angles.x * (1.0 / 360.0)); diff --git a/qcsrc/common/physics/player.qc b/qcsrc/common/physics/player.qc index 0da3c1df3..af3f87c15 100644 --- a/qcsrc/common/physics/player.qc +++ b/qcsrc/common/physics/player.qc @@ -690,7 +690,7 @@ void PM_check_nickspam(entity this) { // slight annoyance for nick change scripts this.movement = -1 * this.movement; - this.BUTTON_ATCK = this.BUTTON_JUMP = this.BUTTON_ATCK2 = this.BUTTON_ZOOM = this.BUTTON_CROUCH = this.BUTTON_HOOK = this.BUTTON_USE = 0; + PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_JUMP(this) = PHYS_INPUT_BUTTON_ATCK2(this) = PHYS_INPUT_BUTTON_ZOOM(this) = PHYS_INPUT_BUTTON_CROUCH(this) = PHYS_INPUT_BUTTON_HOOK(this) = PHYS_INPUT_BUTTON_USE(this) = false; if (this.nickspamcount >= autocvar_g_nick_flood_penalty_red) // if you are persistent and the slight annoyance above does not stop you, I'll show you! { @@ -992,7 +992,7 @@ void PM_jetpack(entity this, float maxspd_mod) // add the unused velocity as up component wishvel_z = 0; - // if (this.BUTTON_JUMP) + // if (PHYS_INPUT_BUTTON_JUMP(this)) wishvel_z = sqrt(max(0, 1 - wishvel * wishvel)); // it is now normalized, so... @@ -1283,6 +1283,10 @@ bool IsFlying(entity this) return true; } +#ifdef CSQC +float autocvar_slowmo; +#endif + void PM_Main(entity this) { int buttons = PHYS_INPUT_BUTTON_MASK(this); @@ -1321,6 +1325,9 @@ void PM_Main(entity this) if (this.PlayerPhysplug) if (this.PlayerPhysplug()) return; +#elif defined(CSQC) + if(autocvar_slowmo != STAT(MOVEVARS_TIMESCALE)) + cvar_set("slowmo", ftos(STAT(MOVEVARS_TIMESCALE))); #endif #ifdef SVQC diff --git a/qcsrc/common/physics/player.qh b/qcsrc/common/physics/player.qh index ea318c5b0..252b157cd 100644 --- a/qcsrc/common/physics/player.qh +++ b/qcsrc/common/physics/player.qh @@ -99,6 +99,15 @@ bool IsFlying(entity a); #define PHYS_INPUT_BUTTON_ZOOM(s) PHYS_INPUT_BUTTON_BUTTON4(s) #define PHYS_INPUT_BUTTON_CROUCH(s) PHYS_INPUT_BUTTON_BUTTON5(s) #define PHYS_INPUT_BUTTON_HOOK(s) PHYS_INPUT_BUTTON_BUTTON6(s) + +#ifdef CSQC +STATIC_INIT(PHYS_INPUT_BUTTON_HOOK) +{ + localcmd("alias +hook +button6\n"); + localcmd("alias -hook -button6\n"); +} +#endif + #define PHYS_INPUT_BUTTON_INFO(s) PHYS_INPUT_BUTTON_BUTTON7(s) #define PHYS_INPUT_BUTTON_DRAG(s) PHYS_INPUT_BUTTON_BUTTON8(s) #define PHYS_INPUT_BUTTON_USE(s) PHYS_INPUT_BUTTON_BUTTON_USE(s) @@ -107,6 +116,14 @@ bool IsFlying(entity a); #define PHYS_INPUT_BUTTON_ZOOMSCRIPT(s) PHYS_INPUT_BUTTON_BUTTON9(s) #define PHYS_INPUT_BUTTON_JETPACK(s) PHYS_INPUT_BUTTON_BUTTON10(s) +#ifdef CSQC +STATIC_INIT(PHYS_INPUT_BUTTON_JETPACK) +{ + localcmd("alias +jetpack +button10\n"); + localcmd("alias -jetpack -button10\n"); +} +#endif + // if more buttons are needed, start using impulse bits as buttons #define PHYS_INPUT_BUTTON_BACKWARD(s) (PHYS_INPUT_MOVEVALUES(s).x < 0) diff --git a/qcsrc/common/playerstats.qc b/qcsrc/common/playerstats.qc index 3d10ca8b5..233762202 100644 --- a/qcsrc/common/playerstats.qc +++ b/qcsrc/common/playerstats.qc @@ -108,13 +108,13 @@ void PlayerStats_GameReport_Accuracy(entity p) { #define ACCMAC(suffix, field) \ PS_GR_P_ADDVAL(p, sprintf("acc-%s-%s", it.netname, suffix), p.accuracy.(field[i-1])); - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { ACCMAC("hit", accuracy_hit) ACCMAC("fired", accuracy_fired) ACCMAC("cnt-hit", accuracy_cnt_hit) ACCMAC("cnt-fired", accuracy_cnt_fired) ACCMAC("frags", accuracy_frags) - )); + }); #undef ACCMAC } @@ -163,7 +163,7 @@ void PlayerStats_GameReport(float finished) PlayerScore_Sort(scoreboard_pos, 1, 1, 1); if(teamplay) { PlayerScore_TeamStats(); } - FOREACH_CLIENT(true, LAMBDA( + FOREACH_CLIENT(true, { // add personal score rank PS_GR_P_ADDVAL(it, PLAYERSTATS_RANK, it.score_dummyfield); @@ -189,7 +189,7 @@ void PlayerStats_GameReport(float finished) // collect final player information PlayerStats_GameReport_FinalizePlayer(it); - )); + }); if(autocvar_g_playerstats_gamereport_uri != "") { @@ -231,13 +231,13 @@ void PlayerStats_GameReport_Init() // initiated before InitGameplayMode so that PlayerStats_GameReport_AddEvent(PLAYERSTATS_RANK); // accuracy stats - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-hit")); PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-fired")); PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-cnt-hit")); PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-cnt-fired")); PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-frags")); - )); + }); PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3); PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5); @@ -457,7 +457,7 @@ void PlayerStats_PlayerBasic(entity joiningplayer, float newrequest) db_close(PS_B_IN_DB); PS_B_IN_DB = -1; - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA(it.playerstats_basicstatus = PS_B_STATUS_IDLE)); + FOREACH_CLIENT(IS_REAL_CLIENT(it), it.playerstats_basicstatus = PS_B_STATUS_IDLE); } } } diff --git a/qcsrc/common/sounds/all.qc b/qcsrc/common/sounds/all.qc index c5685df3a..751462498 100644 --- a/qcsrc/common/sounds/all.qc +++ b/qcsrc/common/sounds/all.qc @@ -128,7 +128,7 @@ float spamsound(entity e, int chan, string samp, float vol, float _atten) void play2team(float t, string filename) { if (autocvar_bot_sound_monopoly) return; - FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.team == t, LAMBDA(play2(it, filename))); + FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.team == t, play2(it, filename)); } void play2all(string samp) diff --git a/qcsrc/common/sounds/all.qh b/qcsrc/common/sounds/all.qh index 02098e875..a7fe25f17 100644 --- a/qcsrc/common/sounds/all.qh +++ b/qcsrc/common/sounds/all.qh @@ -15,9 +15,7 @@ REGISTER_REGISTRY(Sounds) #define SND(id) Sound_fixpath(SND_##id) PRECACHE(Sounds) { - FOREACH(Sounds, true, LAMBDA({ - it.sound_precache(it); - })); + FOREACH(Sounds, true, it.sound_precache(it)); } SOUND(Null, "misc/null"); diff --git a/qcsrc/common/sounds/sound.qh b/qcsrc/common/sounds/sound.qh index 53185b0fb..5d6c57f21 100644 --- a/qcsrc/common/sounds/sound.qh +++ b/qcsrc/common/sounds/sound.qh @@ -76,7 +76,6 @@ const float VOL_BASEVOICE = 1.0; auto = true; \ __chan = fabs(__chan); \ entity tmp = __e = new(csqc_autochannel); \ - make_pure(tmp); \ tmp.think = SUB_Remove_self; \ tmp.nextthink = time + soundlength(__samp); \ } \ diff --git a/qcsrc/common/state.qc b/qcsrc/common/state.qc new file mode 100644 index 000000000..226ff1ba5 --- /dev/null +++ b/qcsrc/common/state.qc @@ -0,0 +1,83 @@ +#include "state.qh" + +void Inventory_new(entity this); +void Inventory_delete(entity this); + +void PlayerState_attach(entity this) +{ + this._ps = NEW(PlayerState, this); + + Inventory_new(this); +} + +void PlayerState_detach(entity this) +{ + if (!PS(this)) return; // initial connect + FOREACH_CLIENT(PS(it) == PS(this), { PS(it) = NULL; }); + remove(PS(this)); + this._ps = NULL; + + Inventory_delete(self); +} + +void GetCvars(int); +void DecodeLevelParms(entity this); +void PlayerScore_Attach(entity this); +void ClientData_Attach(entity this); +void accuracy_init(entity this); +void entcs_attach(entity this); +void playerdemo_init(entity this); +void anticheat_init(entity this); +void W_HitPlotOpen(entity this); +void bot_clientconnect(entity this); + +void ClientState_attach(entity this) +{ + this._cs = NEW(ClientState, this); + + GetCvars(0); // get other cvars from player + + // TODO: xonstat elo.txt support, until then just 404s + if (false && IS_REAL_CLIENT(this)) { PlayerStats_PlayerBasic_CheckUpdate(this); } + + // TODO: fold all of these into ClientState + + DecodeLevelParms(this); + + PlayerScore_Attach(this); + ClientData_Attach(this); + accuracy_init(this); + entcs_attach(this); + playerdemo_init(this); + anticheat_init(this); + W_HitPlotOpen(this); + + bot_clientconnect(this); +} + +void bot_clientdisconnect(); +void W_HitPlotClose(entity this); +void anticheat_report(); +void playerdemo_shutdown(); +void entcs_detach(entity this); +void accuracy_free(entity this); +void ClientData_Detach(entity this); +void PlayerScore_Detach(entity this); + +void ClientState_detach(entity this) +{ + remove(CS(this)); + this._cs = NULL; + + GetCvars(-1); // free cvars + + bot_clientdisconnect(); + + W_HitPlotClose(this); + anticheat_report(); + playerdemo_shutdown(); + entcs_detach(this); + accuracy_free(self); + ClientData_Detach(this); + PlayerScore_Detach(self); +} diff --git a/qcsrc/common/state.qh b/qcsrc/common/state.qh index e2ba5f385..64ae3e7fe 100644 --- a/qcsrc/common/state.qh +++ b/qcsrc/common/state.qh @@ -30,19 +30,9 @@ ENDCLASS(PlayerState) PlayerState PS(entity this) { assert(IS_CLIENT(this)); return this._ps; } #endif -void PlayerState_attach(entity this) -{ - // TODO: dynamic - // this._ps = NEW(PlayerState, this); -} - -void PlayerState_detach(entity this) -{ - // TODO: dynamic - // if (!PS(this)) return; // initial connect - // remove(PS(this)); - // this._ps = NULL; -} +// TODO: renew on death +void PlayerState_attach(entity this); +void PlayerState_detach(entity this); /** * Purpose: common client state, usable on client and server @@ -66,15 +56,5 @@ ENDCLASS(ClientState) ClientState CS(entity this) { assert(IS_CLIENT(this)); assert(this._cs); return this._cs; } #endif -void ClientState_attach(entity this) -{ - this._cs = NEW(ClientState, this); - this._ps = NEW(PlayerState, this); // TODO: dynamic -} - -void ClientState_detach(entity this) -{ - remove(CS(this)); - this._cs = NULL; - this._ps = NULL; // TODO: dynamic -} +void ClientState_attach(entity this); +void ClientState_detach(entity this); diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index 0bb3ac174..e2bafb82f 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -15,7 +15,7 @@ #include "constants.qh" #include - #include + #include #include "triggers/subs.qh" #include "util.qh" @@ -555,13 +555,13 @@ void Item_RespawnCountdown () if(self.waypointsprite_attached) { setself(self.waypointsprite_attached); - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA( + FOREACH_CLIENT(IS_REAL_CLIENT(it), { if(self.waypointsprite_visible_for_player(it)) { msg_entity = it; soundto(MSG_ONE, this, CH_TRIGGER, SND(ITEMRESPAWNCOUNTDOWN), VOL_BASE, ATTEN_NORM); // play respawn sound } - )); + }); setself(this); WaypointSprite_Ping(self.waypointsprite_attached); @@ -582,7 +582,8 @@ void Item_RespawnThink() void Item_ScheduleRespawnIn(entity e, float t) { - if (Item_ItemsTime_Allow(e.itemdef) || e.weapons & WEPSET_SUPERWEAPONS) + // if the respawn time is longer than 10 seconds, show a waypoint, otherwise, just respawn normally + if ((Item_ItemsTime_Allow(e.itemdef) || e.weapons & WEPSET_SUPERWEAPONS) && (t - ITEM_RESPAWN_TICKS) > 0) { e.think = Item_RespawnCountdown; e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS); @@ -615,7 +616,7 @@ void Item_ScheduleRespawn(entity e) void Item_ScheduleInitialRespawn(entity e) { Item_Show(e, 0); - Item_ScheduleRespawnIn(e, game_starttime - time + ITEM_RESPAWNTIME_INITIAL(e)); + Item_ScheduleRespawnIn(e, game_starttime - time + ((e.respawntimestart) ? e.respawntimestart : ITEM_RESPAWNTIME_INITIAL(e))); } float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax, float mode) @@ -697,16 +698,24 @@ float Item_GiveTo(entity item, entity player) if (w || (item.spawnshieldtime && item.pickup_anyway > 0)) { pickedup = true; - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { if(w & (it.m_wepset)) { W_DropEvent(wr_pickup, player, it.m_id, item); W_GiveWeapon(player, it.m_id); } - )); + }); } } + if (item.itemdef.instanceOfPowerup) + { + if ((item.itemdef == ITEM_JetpackRegen) && !(player.items & IT_FUEL_REGEN)) + Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_FUELREGEN_GOT); + else if ((item.itemdef == ITEM_Jetpack) && !(player.items & IT_JETPACK)) + Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_JETPACK_GOT); + } + int its; if((its = (item.items - (item.items & player.items)) & IT_PICKUPMASK)) { @@ -894,7 +903,6 @@ void Item_FindTeam() } // Savage: used for item garbage-collection -// TODO: perhaps nice special effect? void RemoveItem() {SELFPARAM(); if(wasfreed(self) || !self) { return; } @@ -964,7 +972,7 @@ float commodity_pickupevalfunc(entity player, entity item) c = 0; // Detect needed ammo - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { if(!(player.weapons & (it.m_wepset))) continue; @@ -980,7 +988,7 @@ float commodity_pickupevalfunc(entity player, entity item) need_plasma = true; else if(it.items & ITEM_JetpackFuel.m_itemid) need_fuel = true; - )); + }); // TODO: figure out if the player even has the weapon this ammo is for? // may not affect strategy much though... @@ -1147,16 +1155,12 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if(autocvar_spawn_debug >= 2) { - for(entity otheritem = findradius(this.origin, 3); otheritem; otheritem = otheritem.chain) - { - // why not flags & fl_item? - if(otheritem.is_item) - { - LOG_TRACE("XXX Found duplicated item: ", itemname, vtos(this.origin)); - LOG_TRACE(" vs ", otheritem.netname, vtos(otheritem.origin), "\n"); - error("Mapper sucks."); - } - } + // why not flags & fl_item? + FOREACH_ENTITY_RADIUS(this.origin, 3, it.is_item, { + LOG_TRACE("XXX Found duplicated item: ", itemname, vtos(this.origin)); + LOG_TRACE(" vs ", it.netname, vtos(it.origin), "\n"); + error("Mapper sucks."); + }); this.is_item = true; } @@ -1474,7 +1478,7 @@ spawnfunc(target_items) else if(argv(i) == "fuel_regen") self.items |= ITEM_JetpackRegen.m_itemid; else { - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { s = W_UndeprecateName(argv(i)); if(s == it.netname) { @@ -1483,7 +1487,7 @@ spawnfunc(target_items) it.wr_init(it); break; } - )); + }); } } @@ -1529,8 +1533,8 @@ spawnfunc(target_items) if(self.ammo_plasma != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_plasma), "plasma"); if(self.ammo_fuel != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_fuel), "fuel"); if(self.health != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.health), "health"); - if(self.armorvalue != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.health), "armor"); - FOREACH(Weapons, it != WEP_Null, LAMBDA(self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.weapons & (it.m_wepset)), it.netname))); + if(self.armorvalue != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.armorvalue), "armor"); + FOREACH(Weapons, it != WEP_Null, self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.weapons & (it.m_wepset)), it.netname)); } self.netname = strzone(self.netname); //print(self.netname, "\n"); @@ -1538,13 +1542,10 @@ spawnfunc(target_items) n = tokenize_console(self.netname); for(i = 0; i < n; ++i) { - FOREACH(Weapons, it != WEP_Null, LAMBDA( - if(argv(i) == it.netname) - { - it.wr_init(it); - break; - } - )); + FOREACH(Weapons, it != WEP_Null && argv(i) == it.netname, { + it.wr_init(it); + break; + }); } } @@ -1705,10 +1706,7 @@ float GiveItems(entity e, float beginarg, float endarg) got += GiveValue(e, health, op, val); got += GiveValue(e, armorvalue, op, val); case "allweapons": - FOREACH(Weapons, it != WEP_Null, LAMBDA( - if(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED)) - got += GiveWeapon(e, it.m_id, op, val); - )); + FOREACH(Weapons, it != WEP_Null && !(it.spawnflags & WEP_FLAG_MUTATORBLOCKED), got += GiveWeapon(e, it.m_id, op, val)); case "allammo": got += GiveValue(e, ammo_cells, op, val); got += GiveValue(e, ammo_plasma, op, val); @@ -1767,13 +1765,10 @@ float GiveItems(entity e, float beginarg, float endarg) got += GiveValue(e, ammo_fuel, op, val); break; default: - FOREACH(Weapons, it != WEP_Null, LAMBDA( - if(cmd == it.netname) - { - got += GiveWeapon(e, it.m_id, op, val); - break; - } - )); + FOREACH(Weapons, it != WEP_Null && cmd == it.netname, { + got += GiveWeapon(e, it.m_id, op, val); + break; + }); break; } val = 999; @@ -1784,12 +1779,12 @@ float GiveItems(entity e, float beginarg, float endarg) POSTGIVE_BIT(e, items, IT_UNLIMITED_SUPERWEAPONS, SND_POWERUP, SND_POWEROFF); POSTGIVE_BIT(e, items, IT_UNLIMITED_WEAPON_AMMO, SND_POWERUP, SND_POWEROFF); POSTGIVE_BIT(e, items, ITEM_Jetpack.m_itemid, SND_ITEMPICKUP, SND_Null); - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { POSTGIVE_WEAPON(e, it, SND_WEAPONPICKUP, SND_Null); if(!(save_weapons & (it.m_wepset))) if(e.weapons & (it.m_wepset)) it.wr_init(it); - )); + }); POSTGIVE_VALUE(e, strength_finished, 1, SND_POWERUP, SND_POWEROFF); POSTGIVE_VALUE(e, invincible_finished, 1, SND_Shield, SND_POWEROFF); POSTGIVE_VALUE(e, ammo_nails, 0, SND_ITEMPICKUP, SND_Null); diff --git a/qcsrc/common/t_items.qh b/qcsrc/common/t_items.qh index 86e5c7c8e..d6c97445f 100644 --- a/qcsrc/common/t_items.qh +++ b/qcsrc/common/t_items.qh @@ -94,7 +94,6 @@ void Item_Reset(entity this); void Item_FindTeam(); // Savage: used for item garbage-collection -// TODO: perhaps nice special effect? bool ItemSend(entity this, entity to, int sf); void ItemUpdate(entity this); diff --git a/qcsrc/common/teams.qh b/qcsrc/common/teams.qh index 8e09a58eb..3dd50ee88 100644 --- a/qcsrc/common/teams.qh +++ b/qcsrc/common/teams.qh @@ -164,9 +164,4 @@ float Team_TeamToNumber(float teamid) #define SAME_TEAM(a,b) (teamplay ? (a.team == b.team) : (a == b)) #define DIFF_TEAM(a,b) (teamplay ? (a.team != b.team) : (a != b)) -// used for notification system multi-team identifiers -#define APP_TEAM_NUM_2(num,prefix) ((num == NUM_TEAM_1) ? prefix##RED : prefix##BLUE) -#define APP_TEAM_NUM_4(num,prefix) ((num == NUM_TEAM_1) ? prefix##RED : ((num == NUM_TEAM_2) ? prefix##BLUE : ((num == NUM_TEAM_3) ? prefix##YELLOW : prefix##PINK))) -#define APP_TEAM_ENT_2(ent,prefix) ((ent.team == NUM_TEAM_1) ? prefix##RED : prefix##BLUE) -#define APP_TEAM_ENT_4(ent,prefix) ((ent.team == NUM_TEAM_1) ? prefix##RED : ((ent.team == NUM_TEAM_2) ? prefix##BLUE : ((ent.team == NUM_TEAM_3) ? prefix##YELLOW : prefix##PINK))) #endif diff --git a/qcsrc/common/triggers/misc/teleport_dest.qc b/qcsrc/common/triggers/misc/teleport_dest.qc index 161e6796b..f6919006d 100644 --- a/qcsrc/common/triggers/misc/teleport_dest.qc +++ b/qcsrc/common/triggers/misc/teleport_dest.qc @@ -26,7 +26,7 @@ bool teleport_dest_send(entity this, entity to, int sf) void teleport_dest_link() {SELFPARAM(); - Net_LinkEntity(self, false, 0, teleport_dest_send); + //Net_LinkEntity(self, false, 0, teleport_dest_send); //self.SendFlags |= 1; // update } diff --git a/qcsrc/common/triggers/target/changelevel.qc b/qcsrc/common/triggers/target/changelevel.qc index dc227f176..69f444073 100644 --- a/qcsrc/common/triggers/target/changelevel.qc +++ b/qcsrc/common/triggers/target/changelevel.qc @@ -16,11 +16,11 @@ void target_changelevel_use() int plnum = 0; int realplnum = 0; // let's not count bots - FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA( + FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { ++realplnum; if(it.chlevel_targ == self) ++plnum; - )); + }); if(plnum < ceil(realplnum * min(1, self.count))) // 70% of players return; } diff --git a/qcsrc/common/triggers/target/music.qc b/qcsrc/common/triggers/target/music.qc index 015ad9138..52f1fca0e 100644 --- a/qcsrc/common/triggers/target/music.qc +++ b/qcsrc/common/triggers/target/music.qc @@ -54,10 +54,10 @@ void target_music_use() msg_entity = activator; target_music_sendto(MSG_ONE, 1); } - FOREACH_CLIENT(IS_SPEC(it) && it.enemy == activator, LAMBDA( + FOREACH_CLIENT(IS_SPEC(it) && it.enemy == activator, { msg_entity = it; target_music_sendto(MSG_ONE, 1); - )); + }); } spawnfunc(target_music) { @@ -168,7 +168,7 @@ void TargetMusic_Advance() entity best = music_default; if (music_target && time < music_target.lifetime) best = music_target; if (music_trigger) best = music_trigger; - LL_EACH(TargetMusic_list, it.noise, LAMBDA( + LL_EACH(TargetMusic_list, it.noise, { const float vol0 = (getsoundtime(it, CH_BGM_SINGLE) >= 0) ? it.lastvol : -1; if (it == best) { @@ -189,7 +189,7 @@ void TargetMusic_Advance() _sound(it, CH_BGM_SINGLE, "", vol, ATTEN_NONE); it.lastvol = vol; } - )); + }); music_trigger = world; bgmtime = (best) ? getsoundtime(best, CH_BGM_SINGLE) : gettime(GETTIME_CDTRACK); } @@ -210,11 +210,10 @@ void Net_TargetMusic() const string noi = ReadString(); entity e = NULL; - LL_EACH(TargetMusic_list, it.count == id, LAMBDA(e = it; break)); + LL_EACH(TargetMusic_list, it.count == id, { e = it; break; }); if (!e) { - LL_PUSH(TargetMusic_list, e = new(TargetMusic)); - make_pure(e); + LL_PUSH(TargetMusic_list, e = new_pure(TargetMusic)); e.count = id; } if(e.noise != noi) diff --git a/qcsrc/common/triggers/teleporters.qc b/qcsrc/common/triggers/teleporters.qc index eae31ead0..40ba61f65 100644 --- a/qcsrc/common/triggers/teleporters.qc +++ b/qcsrc/common/triggers/teleporters.qc @@ -160,7 +160,7 @@ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angle { player.pusher = teleporter.owner; player.pushltime = time + autocvar_g_maxpushtime; - player.istypefrag = player.BUTTON_CHAT; + player.istypefrag = PHYS_INPUT_BUTTON_CHAT(player); } else { @@ -304,9 +304,7 @@ void WarpZone_PostTeleportPlayer_Callback(entity pl) Reset_ArcBeam(pl, v_forward); UpdateCSQCProjectileAfterTeleport(pl); UpdateItemAfterTeleport(pl); - { - WITH(entity, self, pl, anticheat_fixangle()); - } + if (IS_PLAYER(pl)) anticheat_fixangle(pl); #endif // "disown" projectiles after teleport if(pl.owner) diff --git a/qcsrc/common/triggers/trigger/jumppads.qc b/qcsrc/common/triggers/trigger/jumppads.qc index 3c1534c97..141fd458f 100644 --- a/qcsrc/common/triggers/trigger/jumppads.qc +++ b/qcsrc/common/triggers/trigger/jumppads.qc @@ -417,16 +417,23 @@ bool target_push_send(entity this, entity to, float sf) return true; } -void target_push_link() -{SELFPARAM(); - BITSET_ASSIGN(self.effects, EF_NODEPTHTEST); - Net_LinkEntity(self, false, 0, target_push_send); - //self.SendFlags |= 1; // update +void target_push_link(entity this) +{ + BITSET_ASSIGN(this.effects, EF_NODEPTHTEST); + Net_LinkEntity(this, false, 0, target_push_send); + //this.SendFlags |= 1; // update +} + +void target_push_init(entity this) +{ + this.mangle = this.angles; + setorigin(this, this.origin); + target_push_link(this); } -spawnfunc(target_push) { target_push_link(); } -spawnfunc(info_notnull) { target_push_link(); } -spawnfunc(target_position) { make_pure(this); target_push_link(); } +spawnfunc(target_push) { target_push_init(this); } +spawnfunc(info_notnull) { target_push_init(this); } +spawnfunc(target_position) { target_push_init(this); } #elif defined(CSQC) @@ -466,7 +473,6 @@ void target_push_remove(entity this) NET_HANDLE(ENT_CLIENT_TARGET_PUSH, bool isnew) { - make_pure(this); self.classname = "push_target"; self.cnt = ReadByte(); self.targetname = strzone(ReadString()); diff --git a/qcsrc/common/triggers/trigger/teleport.qc b/qcsrc/common/triggers/trigger/teleport.qc index e289064c8..be8040079 100644 --- a/qcsrc/common/triggers/trigger/teleport.qc +++ b/qcsrc/common/triggers/trigger/teleport.qc @@ -75,7 +75,7 @@ float trigger_teleport_send(entity this, entity to, float sf) void trigger_teleport_link(entity this) { - trigger_link(this, trigger_teleport_send); + //trigger_link(this, trigger_teleport_send); } spawnfunc(trigger_teleport) @@ -83,11 +83,12 @@ spawnfunc(trigger_teleport) self.angles = '0 0 0'; self.active = ACTIVE_ACTIVE; - trigger_init(self); + //trigger_init(self); // only for predicted triggers? + EXACTTRIGGER_INIT; self.use = trigger_teleport_use; if(self.noise != "") - FOREACH_WORD(self.noise, true, LAMBDA(precache_sound(it))); + FOREACH_WORD(self.noise, true, precache_sound(it)); // this must be called to spawn the teleport waypoints for bots InitializeEntity(self, teleport_findtarget, INITPRIO_FINDTARGET); diff --git a/qcsrc/common/triggers/triggers.qc b/qcsrc/common/triggers/triggers.qc index 563364523..29cb70a7d 100644 --- a/qcsrc/common/triggers/triggers.qc +++ b/qcsrc/common/triggers/triggers.qc @@ -296,7 +296,7 @@ void trigger_touch_generic(entity this, void() touchfunc) { entity e; for(e = findradius((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1); e; e = e.chain) - if(e.isplayermodel || e.classname == "csqcprojectile") + if(e.classname == "csqcprojectile") { vector emin = e.absmin, emax = e.absmax; if(this.solid == SOLID_BSP) diff --git a/qcsrc/common/turrets/config.qc b/qcsrc/common/turrets/config.qc index 34cf50eac..022e73c5e 100644 --- a/qcsrc/common/turrets/config.qc +++ b/qcsrc/common/turrets/config.qc @@ -28,7 +28,7 @@ float T_Config_Queue_Compare(float root, float child, entity pass) void Dump_Turret_Settings() { float x, totalsettings = 0; - FOREACH(Turrets, it != TUR_Null, LAMBDA({ + FOREACH(Turrets, it != TUR_Null, { // step 1: clear the queue TUR_CONFIG_COUNT = 0; for(x = 0; x <= MAX_TUR_CONFIG; ++x) @@ -49,7 +49,7 @@ void Dump_Turret_Settings() // step 5: debug info LOG_INFO(sprintf("#%d: %s: %d settings...\n", i, it.turret_name, TUR_CONFIG_COUNT)); totalsettings += TUR_CONFIG_COUNT; - })); + }); // clear queue now that we're finished TUR_CONFIG_COUNT = 0; diff --git a/qcsrc/common/turrets/sv_turrets.qc b/qcsrc/common/turrets/sv_turrets.qc index a06fbcbb9..fec1e885f 100644 --- a/qcsrc/common/turrets/sv_turrets.qc +++ b/qcsrc/common/turrets/sv_turrets.qc @@ -1206,11 +1206,11 @@ void turrets_manager_think() if (autocvar_g_turrets_reloadcvars == 1) { - FOREACH_ENTITY(IS_TURRET(it), LAMBDA( + FOREACH_ENTITY(IS_TURRET(it), { load_unit_settings(it, true); Turret tur = get_turretinfo(it.m_id); tur.tr_think(tur, it); - )); + }); cvar_set("g_turrets_reloadcvars", "0"); } } diff --git a/qcsrc/common/turrets/turret/ewheel.qc b/qcsrc/common/turrets/turret/ewheel.qc index dc3b460e9..2a537d4e9 100644 --- a/qcsrc/common/turrets/turret/ewheel.qc +++ b/qcsrc/common/turrets/turret/ewheel.qc @@ -137,102 +137,104 @@ void ewheel_move_idle() spawnfunc(turret_ewheel) { if(!turret_initialize(TUR_EWHEEL)) remove(self); } - METHOD(EWheel, tr_think, void(EWheel thistur, entity it)) - { - SELFPARAM(); - float vz; - vector wish_angle, real_angle; +METHOD(EWheel, tr_think, void(EWheel thistur, entity it)) +{ + SELFPARAM(); + float vz; + vector wish_angle, real_angle; - vz = self.velocity_z; + vz = self.velocity_z; - self.angles_x = anglemods(self.angles_x); - self.angles_y = anglemods(self.angles_y); + self.angles_x = anglemods(self.angles_x); + self.angles_y = anglemods(self.angles_y); - fixedmakevectors(self.angles); + fixedmakevectors(self.angles); - wish_angle = normalize(self.steerto); - wish_angle = vectoangles(wish_angle); - real_angle = wish_angle - self.angles; - real_angle = shortangle_vxy(real_angle, self.tur_head.angles); + wish_angle = normalize(self.steerto); + wish_angle = vectoangles(wish_angle); + real_angle = wish_angle - self.angles; + real_angle = shortangle_vxy(real_angle, self.tur_head.angles); - self.tur_head.spawnshieldtime = fabs(real_angle_y); - real_angle_y = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed); - self.angles_y = (self.angles_y + real_angle_y); + self.tur_head.spawnshieldtime = fabs(real_angle_y); + real_angle_y = bound(-self.tur_head.aim_speed, real_angle_y, self.tur_head.aim_speed); + self.angles_y = (self.angles_y + real_angle_y); - if(self.enemy) - ewheel_move_enemy(); - else if(self.pathcurrent) - ewheel_move_path(); - else - ewheel_move_idle(); + if(self.enemy) + ewheel_move_enemy(); + else if(self.pathcurrent) + ewheel_move_path(); + else + ewheel_move_idle(); - self.velocity_z = vz; + self.velocity_z = vz; - if(self.velocity) - self.SendFlags |= TNSF_MOVE; - } - METHOD(EWheel, tr_death, void(EWheel this, entity it)) - { - it.velocity = '0 0 0'; + if(self.velocity) + self.SendFlags |= TNSF_MOVE; +} + +METHOD(EWheel, tr_death, void(EWheel this, entity it)) +{ + it.velocity = '0 0 0'; #ifdef EWHEEL_FANCYPATH - if (self.pathcurrent) - pathlib_deletepath(it.pathcurrent.owner); + if (self.pathcurrent) + pathlib_deletepath(it.pathcurrent.owner); #endif - it.pathcurrent = NULL; - } - METHOD(EWheel, tr_setup, void(EWheel this, entity it)) - { - entity e; + it.pathcurrent = NULL; +} - if(it.movetype == MOVETYPE_WALK) - { - it.velocity = '0 0 0'; - it.enemy = world; +METHOD(EWheel, tr_setup, void(EWheel this, entity it)) +{ + entity e; + + if(it.movetype == MOVETYPE_WALK) + { + it.velocity = '0 0 0'; + it.enemy = world; - setorigin(it, it.pos1); + setorigin(it, it.pos1); - if (it.target != "") - { - e = find(world, targetname, it.target); - if (!e) - { - LOG_TRACE("Initital waypoint for ewheel does NOT exsist, fix your map!\n"); - it.target = ""; - } - - if (e.classname != "turret_checkpoint") - LOG_TRACE("Warning: not a turrret path\n"); - else - { + if (it.target != "") + { + e = find(world, targetname, it.target); + if (!e) + { + LOG_TRACE("Initital waypoint for ewheel does NOT exsist, fix your map!\n"); + it.target = ""; + } + + if (e.classname != "turret_checkpoint") + LOG_TRACE("Warning: not a turrret path\n"); + else + { #ifdef EWHEEL_FANCYPATH - it.pathcurrent = WALKER_PATH(it.origin,e.origin); - it.pathgoal = e; + it.pathcurrent = WALKER_PATH(it.origin,e.origin); + it.pathgoal = e; #else - it.pathcurrent = e; + it.pathcurrent = e; #endif - } - } } - - it.iscreature = true; - it.teleportable = TELEPORT_NORMAL; - it.damagedbycontents = true; - it.movetype = MOVETYPE_WALK; - it.solid = SOLID_SLIDEBOX; - it.takedamage = DAMAGE_AIM; - it.idle_aim = '0 0 0'; - it.pos1 = it.origin; - it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; - it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; - it.frame = it.tur_head.frame = 1; - it.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; - - // Convert from dgr / sec to dgr / tic - it.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate); - it.tur_head.aim_speed = it.tur_head.aim_speed / (1 / it.ticrate); } + } + + it.iscreature = true; + it.teleportable = TELEPORT_NORMAL; + it.damagedbycontents = true; + it.movetype = MOVETYPE_WALK; + it.solid = SOLID_SLIDEBOX; + it.takedamage = DAMAGE_AIM; + it.idle_aim = '0 0 0'; + it.pos1 = it.origin; + it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + it.frame = it.tur_head.frame = 1; + it.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; + + // Convert from dgr / sec to dgr / tic + it.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate); + it.tur_head.aim_speed = it.tur_head.aim_speed / (1 / it.ticrate); +} #endif // SVQC #ifdef CSQC diff --git a/qcsrc/common/turrets/turret/walker.qc b/qcsrc/common/turrets/turret/walker.qc index 599e00c29..bf68e85fd 100644 --- a/qcsrc/common/turrets/turret/walker.qc +++ b/qcsrc/common/turrets/turret/walker.qc @@ -348,284 +348,284 @@ void walker_move_path() spawnfunc(turret_walker) { if(!turret_initialize(TUR_WALKER)) remove(self); } - METHOD(WalkerTurret, tr_think, void(WalkerTurret thistur, entity it)) - { - fixedmakevectors(self.angles); +METHOD(WalkerTurret, tr_think, void(WalkerTurret thistur, entity it)) +{ + fixedmakevectors(self.angles); - if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent) - walker_move_path(); - else if (self.enemy == world) + if (self.spawnflags & TSF_NO_PATHBREAK && self.pathcurrent) + walker_move_path(); + else if (self.enemy == world) + { + if(self.pathcurrent) + walker_move_path(); + else + { + if(self.enemy_last_time != 0) { - if(self.pathcurrent) - walker_move_path(); + if(vdist(self.origin - self.enemy_last_loc, <, 128) || time - self.enemy_last_time > 10) + self.enemy_last_time = 0; else - { - if(self.enemy_last_time != 0) - { - if(vdist(self.origin - self.enemy_last_loc, <, 128) || time - self.enemy_last_time > 10) - self.enemy_last_time = 0; - else - walker_move_to(self.enemy_last_loc, 0); - } - else - { - if(self.animflag != ANIM_NO) - { - traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self); - - if(trace_fraction != 1.0) - self.tur_head.idletime = -1337; - else - { - traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self); - if(trace_fraction == 1.0) - self.tur_head.idletime = -1337; - } - - if(self.tur_head.idletime == -1337) - { - self.moveto = self.origin + randomvec() * 256; - self.tur_head.idletime = 0; - } - - self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1; - self.moveto_z = self.origin_z + 64; - walker_move_to(self.moveto, 0); - } - - if(self.idletime < time) - { - if(random() < 0.5 || !(self.spawnflags & TSL_ROAM)) - { - self.idletime = time + 1 + random() * 5; - self.moveto = self.origin; - self.animflag = ANIM_NO; - } - else - { - self.animflag = ANIM_WALK; - self.idletime = time + 4 + random() * 2; - self.moveto = self.origin + randomvec() * 256; - self.tur_head.moveto = self.moveto; - self.tur_head.idletime = 0; - } - } - } - } + walker_move_to(self.enemy_last_loc, 0); } else { - if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE) + if(self.animflag != ANIM_NO) { - vector wish_angle; + traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self); + + if(trace_fraction != 1.0) + self.tur_head.idletime = -1337; + else + { + traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self); + if(trace_fraction == 1.0) + self.tur_head.idletime = -1337; + } - wish_angle = angleofs(self, self.enemy); - if (self.animflag != ANIM_SWIM) - if (fabs(wish_angle_y) < 15) + if(self.tur_head.idletime == -1337) { - self.moveto = self.enemy.origin; - self.steerto = steerlib_attract2(self, self.moveto, 0.5, 500, 0.95); - self.animflag = ANIM_MELEE; + self.moveto = self.origin + randomvec() * 256; + self.tur_head.idletime = 0; } + + self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1; + self.moveto_z = self.origin_z + 64; + walker_move_to(self.moveto, 0); } - else if (self.tur_head.attack_finished_single[0] < time) + + if(self.idletime < time) { - if(self.tur_head.shot_volly) + if(random() < 0.5 || !(self.spawnflags & TSL_ROAM)) { + self.idletime = time + 1 + random() * 5; + self.moveto = self.origin; self.animflag = ANIM_NO; - - self.tur_head.shot_volly = self.tur_head.shot_volly -1; - if(self.tur_head.shot_volly == 0) - self.tur_head.attack_finished_single[0] = time + (autocvar_g_turrets_unit_walker_rocket_refire); - else - self.tur_head.attack_finished_single[0] = time + 0.2; - - if(self.tur_head.shot_volly > 1) - walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01"))); - else - walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02"))); } else { - if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min)) - if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range)) - self.tur_head.shot_volly = 4; + self.animflag = ANIM_WALK; + self.idletime = time + 4 + random() * 2; + self.moveto = self.origin + randomvec() * 256; + self.tur_head.moveto = self.moveto; + self.tur_head.idletime = 0; } } - else - { - if (self.animflag != ANIM_MELEE) - walker_move_to(self.enemy.origin, self.tur_dist_enemy); - } } + } + } + else + { + if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_melee_range) && self.animflag != ANIM_MELEE) + { + vector wish_angle; + wish_angle = angleofs(self, self.enemy); + if (self.animflag != ANIM_SWIM) + if (fabs(wish_angle_y) < 15) { - vector real_angle; - float turny = 0, turnx = 0; - float vz; + self.moveto = self.enemy.origin; + self.steerto = steerlib_attract2(self, self.moveto, 0.5, 500, 0.95); + self.animflag = ANIM_MELEE; + } + } + else if (self.tur_head.attack_finished_single[0] < time) + { + if(self.tur_head.shot_volly) + { + self.animflag = ANIM_NO; - real_angle = vectoangles(self.steerto) - self.angles; - vz = self.velocity_z; + self.tur_head.shot_volly = self.tur_head.shot_volly -1; + if(self.tur_head.shot_volly == 0) + self.tur_head.attack_finished_single[0] = time + (autocvar_g_turrets_unit_walker_rocket_refire); + else + self.tur_head.attack_finished_single[0] = time + 0.2; - switch (self.animflag) - { - case ANIM_NO: - movelib_brake_simple(self, (autocvar_g_turrets_unit_walker_speed_stop)); - break; - - case ANIM_TURN: - turny = (autocvar_g_turrets_unit_walker_turn); - movelib_brake_simple(self, (autocvar_g_turrets_unit_walker_speed_stop)); - break; - - case ANIM_WALK: - turny = (autocvar_g_turrets_unit_walker_turn_walk); - movelib_move_simple(self, v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6); - break; - - case ANIM_RUN: - turny = (autocvar_g_turrets_unit_walker_turn_run); - movelib_move_simple(self, v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6); - break; - - case ANIM_STRAFE_L: - turny = (autocvar_g_turrets_unit_walker_turn_strafe); - movelib_move_simple(self, v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8); - break; - - case ANIM_STRAFE_R: - turny = (autocvar_g_turrets_unit_walker_turn_strafe); - movelib_move_simple(self, v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8); - break; - - case ANIM_JUMP: - self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump); - break; - - case ANIM_LAND: - break; - - case ANIM_PAIN: - if(self.frame != ANIM_PAIN) - defer(self, 0.25, walker_setnoanim); - - break; - - case ANIM_MELEE: - if(self.frame != ANIM_MELEE) - { - defer(self, 0.41, walker_setnoanim); - defer(self, 0.21, walker_melee_do_dmg); - } - - movelib_brake_simple(self, (autocvar_g_turrets_unit_walker_speed_stop)); - break; - - case ANIM_SWIM: - turny = (autocvar_g_turrets_unit_walker_turn_swim); - turnx = (autocvar_g_turrets_unit_walker_turn_swim); - - self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10); - movelib_move_simple(self, v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3); - vz = self.velocity_z + sin(time * 4) * 8; - break; - - case ANIM_ROAM: - turny = (autocvar_g_turrets_unit_walker_turn_walk); - movelib_move_simple(self, v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5); - break; - } + if(self.tur_head.shot_volly > 1) + walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01"))); + else + walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket02"))); + } + else + { + if (self.tur_dist_enemy > (autocvar_g_turrets_unit_walker_rocket_range_min)) + if (self.tur_dist_enemy < (autocvar_g_turrets_unit_walker_rocket_range)) + self.tur_head.shot_volly = 4; + } + } + else + { + if (self.animflag != ANIM_MELEE) + walker_move_to(self.enemy.origin, self.tur_dist_enemy); + } + } - if(turny) - { - turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny ); - self.angles_y += turny; - } + { + vector real_angle; + float turny = 0, turnx = 0; + float vz; - if(turnx) + real_angle = vectoangles(self.steerto) - self.angles; + vz = self.velocity_z; + + switch (self.animflag) + { + case ANIM_NO: + movelib_brake_simple(self, (autocvar_g_turrets_unit_walker_speed_stop)); + break; + + case ANIM_TURN: + turny = (autocvar_g_turrets_unit_walker_turn); + movelib_brake_simple(self, (autocvar_g_turrets_unit_walker_speed_stop)); + break; + + case ANIM_WALK: + turny = (autocvar_g_turrets_unit_walker_turn_walk); + movelib_move_simple(self, v_forward, (autocvar_g_turrets_unit_walker_speed_walk), 0.6); + break; + + case ANIM_RUN: + turny = (autocvar_g_turrets_unit_walker_turn_run); + movelib_move_simple(self, v_forward, (autocvar_g_turrets_unit_walker_speed_run), 0.6); + break; + + case ANIM_STRAFE_L: + turny = (autocvar_g_turrets_unit_walker_turn_strafe); + movelib_move_simple(self, v_right * -1, (autocvar_g_turrets_unit_walker_speed_walk), 0.8); + break; + + case ANIM_STRAFE_R: + turny = (autocvar_g_turrets_unit_walker_turn_strafe); + movelib_move_simple(self, v_right, (autocvar_g_turrets_unit_walker_speed_walk), 0.8); + break; + + case ANIM_JUMP: + self.velocity += '0 0 1' * (autocvar_g_turrets_unit_walker_speed_jump); + break; + + case ANIM_LAND: + break; + + case ANIM_PAIN: + if(self.frame != ANIM_PAIN) + defer(self, 0.25, walker_setnoanim); + + break; + + case ANIM_MELEE: + if(self.frame != ANIM_MELEE) { - turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx ); - self.angles_x += turnx; + defer(self, 0.41, walker_setnoanim); + defer(self, 0.21, walker_melee_do_dmg); } - self.velocity_z = vz; - } + movelib_brake_simple(self, (autocvar_g_turrets_unit_walker_speed_stop)); + break; + case ANIM_SWIM: + turny = (autocvar_g_turrets_unit_walker_turn_swim); + turnx = (autocvar_g_turrets_unit_walker_turn_swim); - if(self.origin != self.oldorigin) - self.SendFlags |= TNSF_MOVE; + self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10); + movelib_move_simple(self, v_forward, (autocvar_g_turrets_unit_walker_speed_swim), 0.3); + vz = self.velocity_z + sin(time * 4) * 8; + break; - self.oldorigin = self.origin; - turrets_setframe(self.animflag, false); + case ANIM_ROAM: + turny = (autocvar_g_turrets_unit_walker_turn_walk); + movelib_move_simple(self, v_forward ,(autocvar_g_turrets_unit_walker_speed_roam), 0.5); + break; } - METHOD(WalkerTurret, tr_death, void(WalkerTurret this, entity it)) + + if(turny) { -#ifdef WALKER_FANCYPATHING - if (it.pathcurrent) - pathlib_deletepath(it.pathcurrent.owner); -#endif - it.pathcurrent = NULL; + turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny ); + self.angles_y += turny; } - METHOD(WalkerTurret, tr_setup, void(WalkerTurret this, entity it)) + + if(turnx) { - it.ticrate = 0.05; + turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx ); + self.angles_x += turnx; + } - entity e; + self.velocity_z = vz; + } - // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn. - if(it.movetype == MOVETYPE_WALK) - { - if(it.pos1) - setorigin(it, it.pos1); - if(it.pos2) - it.angles = it.pos2; - } - it.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; - it.aim_flags = TFL_AIM_LEAD; - it.turret_flags |= TUR_FLAG_HITSCAN; - - it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; - it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; - it.iscreature = true; - it.teleportable = TELEPORT_NORMAL; - it.damagedbycontents = true; - it.solid = SOLID_SLIDEBOX; - it.takedamage = DAMAGE_AIM; - if(it.movetype != MOVETYPE_WALK) - { - setorigin(it, it.origin); - tracebox(it.origin + '0 0 128', it.mins, it.maxs, it.origin - '0 0 10000', MOVE_NORMAL, it); - setorigin(it, trace_endpos + '0 0 4'); - it.pos1 = it.origin; - it.pos2 = it.angles; - } - it.movetype = MOVETYPE_WALK; - it.idle_aim = '0 0 0'; - it.turret_firecheckfunc = walker_firecheck; + if(self.origin != self.oldorigin) + self.SendFlags |= TNSF_MOVE; - if (it.target != "") - { - e = find(world, targetname, it.target); - if (!e) - { - LOG_TRACE("Initital waypoint for walker does NOT exsist, fix your map!\n"); - it.target = ""; - } + self.oldorigin = self.origin; + turrets_setframe(self.animflag, false); +} +METHOD(WalkerTurret, tr_death, void(WalkerTurret this, entity it)) +{ +#ifdef WALKER_FANCYPATHING + if (it.pathcurrent) + pathlib_deletepath(it.pathcurrent.owner); +#endif + it.pathcurrent = NULL; +} +METHOD(WalkerTurret, tr_setup, void(WalkerTurret this, entity it)) +{ + it.ticrate = 0.05; - if (e.classname != "turret_checkpoint") - LOG_TRACE("Warning: not a turrret path\n"); - else - { + entity e; + + // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn. + if(it.movetype == MOVETYPE_WALK) + { + if(it.pos1) + setorigin(it, it.pos1); + if(it.pos2) + it.angles = it.pos2; + } + + it.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE; + it.aim_flags = TFL_AIM_LEAD; + it.turret_flags |= TUR_FLAG_HITSCAN; + + it.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + it.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS; + it.iscreature = true; + it.teleportable = TELEPORT_NORMAL; + it.damagedbycontents = true; + it.solid = SOLID_SLIDEBOX; + it.takedamage = DAMAGE_AIM; + if(it.movetype != MOVETYPE_WALK) + { + setorigin(it, it.origin); + tracebox(it.origin + '0 0 128', it.mins, it.maxs, it.origin - '0 0 10000', MOVE_NORMAL, it); + setorigin(it, trace_endpos + '0 0 4'); + it.pos1 = it.origin; + it.pos2 = it.angles; + } + it.movetype = MOVETYPE_WALK; + it.idle_aim = '0 0 0'; + it.turret_firecheckfunc = walker_firecheck; + + if (it.target != "") + { + e = find(world, targetname, it.target); + if (!e) + { + LOG_TRACE("Initital waypoint for walker does NOT exsist, fix your map!\n"); + it.target = ""; + } + + if (e.classname != "turret_checkpoint") + LOG_TRACE("Warning: not a turrret path\n"); + else + { #ifdef WALKER_FANCYPATHING - it.pathcurrent = WALKER_PATH(it.origin, e.origin); - it.pathgoal = e; + it.pathcurrent = WALKER_PATH(it.origin, e.origin); + it.pathgoal = e; #else - it.pathcurrent = e; + it.pathcurrent = e; #endif - } - } } + } +} #endif // SVQC #ifdef CSQC diff --git a/qcsrc/common/util.qc b/qcsrc/common/util.qc index a087c9faa..0e6b6d6ba 100644 --- a/qcsrc/common/util.qc +++ b/qcsrc/common/util.qc @@ -5,7 +5,7 @@ #include "constants.qh" #include "../client/mutators/events.qh" #include "mapinfo.qh" - #include "notifications.qh" + #include "notifications/all.qh" #include #elif defined(MENUQC) #elif defined(SVQC) @@ -13,7 +13,7 @@ #include "../server/autocvars.qh" #include "../server/defs.qh" #include "../server/mutators/events.qh" - #include "notifications.qh" + #include "notifications/all.qh" #include #include "mapinfo.qh" #endif @@ -608,8 +608,7 @@ float cvar_settemp(string tmp_cvar, string tmp_value) if(created_saved_value != -1) { // creating a new entity to keep track of this cvar - entity e = new(saved_cvar_value); - make_pure(e); + entity e = new_pure(saved_cvar_value); e.netname = strzone(tmp_cvar); e.message = strzone(cvar_string(tmp_cvar)); created_saved_value = 1; @@ -1489,9 +1488,10 @@ void dedicated_print(string input) // print(), but only print if the server is n #endif #ifndef MENUQC -float Announcer_PickNumber(float type, float num) +Notification Announcer_PickNumber(int type, int num) { - switch(type) + return = NULL; + switch (type) { case CNT_GAMESTART: { @@ -1596,7 +1596,6 @@ float Announcer_PickNumber(float type, float num) break; } } - return NOTIF_ABORT; // abort sending if none of these numbers were right } #endif diff --git a/qcsrc/common/util.qh b/qcsrc/common/util.qh index fd5c88889..2a6d28e8e 100644 --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@ -159,8 +159,6 @@ string getcurrentmod(); #ifndef MENUQC #ifdef CSQC int ReadInt24_t(); -vector ReadInt48_t(); -vector ReadInt72_t(); #else void WriteInt24_t(float dest, float val); void WriteInt48_t(float dest, vector val); @@ -286,7 +284,7 @@ const float CNT_IDLE = 3; const float CNT_KILL = 4; const float CNT_RESPAWN = 5; const float CNT_ROUNDSTART = 6; -float Announcer_PickNumber(float type, float num); +entity Announcer_PickNumber(float type, float num); #endif #ifndef MENUQC diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc index 6224eca65..3e75ae530 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qc +++ b/qcsrc/common/vehicles/sv_vehicles.qc @@ -884,8 +884,8 @@ void vehicles_exit(bool eject) if(!teamplay) _vehicle.team = 0; - Kill_Notification(NOTIF_ONE, _player, MSG_CENTER_CPID, CPID_VEHICLES); - Kill_Notification(NOTIF_ONE, _player, MSG_CENTER_CPID, CPID_VEHICLES_OTHER); // kill all vehicle notifications when exiting a vehicle? + Kill_Notification(NOTIF_ONE, _player, MSG_CENTER, CPID_VEHICLES); + Kill_Notification(NOTIF_ONE, _player, MSG_CENTER, CPID_VEHICLES_OTHER); // kill all vehicle notifications when exiting a vehicle? WaypointSprite_Kill(_vehicle.wps_intruder); @@ -1007,7 +1007,7 @@ void vehicles_enter(entity pl, entity veh) if(DIFF_TEAM(pl, veh)) if(autocvar_g_vehicles_steal) { - FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(it, veh), LAMBDA(Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_VEHICLE_STEAL))); + FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(it, veh), Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_VEHICLE_STEAL)); Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_VEHICLE_STEAL_SELF); @@ -1164,7 +1164,7 @@ void vehicles_spawn() if(self.vehicle_controller) self.team = self.vehicle_controller.team; - FOREACH_CLIENT(IS_PLAYER(it) && it.hook.aiment == self, LAMBDA(RemoveGrapplingHook(it))); + FOREACH_CLIENT(IS_PLAYER(it) && it.hook.aiment == self, RemoveGrapplingHook(it)); vehicles_reset_colors(); diff --git a/qcsrc/common/vehicles/vehicle/bumblebee.qc b/qcsrc/common/vehicles/vehicle/bumblebee.qc index f65bb0cd5..323e485dc 100644 --- a/qcsrc/common/vehicles/vehicle/bumblebee.qc +++ b/qcsrc/common/vehicles/vehicle/bumblebee.qc @@ -178,7 +178,7 @@ float bumblebee_gunner_frame() _out * -1, _in, autocvar_g_vehicle_bumblebee_cannon_turnspeed); if(!forbidWeaponUse(gunner)) - if(gunner.BUTTON_ATCK) + if(PHYS_INPUT_BUTTON_ATCK(gunner)) if(time > gun.attack_finished_single[0]) if(gun.vehicle_energy >= autocvar_g_vehicle_bumblebee_cannon_cost) { @@ -202,7 +202,7 @@ float bumblebee_gunner_frame() UpdateAuxiliaryXhair(vehic.owner, trace_endpos, ('1 0 0' * gunner.vehicle_reload1) + ('0 1 0' *(1 - gunner.vehicle_reload1)), ((gunner == vehic.gunner1) ? 1 : 2)); vehic.solid = SOLID_BBOX; - gunner.BUTTON_ATCK = gunner.BUTTON_ATCK2 = gunner.BUTTON_CROUCH = 0; + PHYS_INPUT_BUTTON_ATCK(gunner) = PHYS_INPUT_BUTTON_ATCK2(gunner) = PHYS_INPUT_BUTTON_CROUCH(gunner) = false; gunner.vehicle_energy = (gun.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo) * 100; setself(gunner); @@ -436,7 +436,7 @@ float bumblebee_pilot_frame() if(IS_DEAD(vehic)) { setself(pilot); - pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = 0; + PHYS_INPUT_BUTTON_ATCK(pilot) = PHYS_INPUT_BUTTON_ATCK2(pilot) = false; return 1; } @@ -504,9 +504,9 @@ float bumblebee_pilot_frame() vehic.angles_z = 0; } - if(pilot.BUTTON_CROUCH) + if(PHYS_INPUT_BUTTON_CROUCH(pilot)) newvel -= v_up * autocvar_g_vehicle_bumblebee_speed_down; - else if(pilot.BUTTON_JUMP) + else if(PHYS_INPUT_BUTTON_JUMP(pilot)) newvel += v_up * autocvar_g_vehicle_bumblebee_speed_up; vehic.velocity += newvel * frametime; @@ -550,7 +550,7 @@ float bumblebee_pilot_frame() autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides * -1, autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides, autocvar_g_vehicle_bumblebee_raygun_turnspeed); if(!forbidWeaponUse(pilot)) - if((pilot.BUTTON_ATCK || pilot.BUTTON_ATCK2) && (vehic.vehicle_energy > autocvar_g_vehicle_bumblebee_raygun_dps * sys_frametime || autocvar_g_vehicle_bumblebee_raygun == 0)) + if((PHYS_INPUT_BUTTON_ATCK(pilot) || PHYS_INPUT_BUTTON_ATCK2(pilot)) && (vehic.vehicle_energy > autocvar_g_vehicle_bumblebee_raygun_dps * sys_frametime || autocvar_g_vehicle_bumblebee_raygun == 0)) { vehic.gun3.enemy.realowner = pilot; vehic.gun3.enemy.effects &= ~EF_NODRAW; @@ -633,7 +633,7 @@ float bumblebee_pilot_frame() vehic.angles_x *= -1; setorigin(pilot, vehic.origin + v_up * 48 + v_forward * 160); - pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = pilot.BUTTON_CROUCH = 0; + PHYS_INPUT_BUTTON_ATCK(pilot) = PHYS_INPUT_BUTTON_ATCK2(pilot) = PHYS_INPUT_BUTTON_CROUCH(pilot) = false; setself(pilot); return 1; @@ -736,222 +736,222 @@ spawnfunc(vehicle_bumblebee) if(!vehicle_initialize(VEH_BUMBLEBEE, false)) { remove(self); return; } } - METHOD(Bumblebee, vr_impact, void(Bumblebee thisveh, entity instance)) - { - if(autocvar_g_vehicle_bumblebee_bouncepain) - vehicles_impact(autocvar_g_vehicle_bumblebee_bouncepain_x, autocvar_g_vehicle_bumblebee_bouncepain_y, autocvar_g_vehicle_bumblebee_bouncepain_z); - } - METHOD(Bumblebee, vr_enter, void(Bumblebee thisveh, entity instance)) - { - SELFPARAM(); - self.touch = bumblebee_touch; - self.nextthink = 0; - self.movetype = MOVETYPE_BOUNCEMISSILE; - } - METHOD(Bumblebee, vr_think, void(Bumblebee thisveh, entity instance)) - { - SELFPARAM(); - self.angles_z *= 0.8; - self.angles_x *= 0.8; - - self.nextthink = time; - - if(!self.owner) - { - entity oldself = self; - if(self.gunner1) - { - setself(self.gunner1); - oldself.gun1.vehicle_exit(VHEF_EJECT); - entity oldother = other; - other = self; - setself(oldself); - self.phase = 0; - self.touch(); - other = oldother; - return; - } - - if(self.gunner2) - { - setself(self.gunner2); - oldself.gun2.vehicle_exit(VHEF_EJECT); - entity oldother = other; - other = self; - setself(oldself); - self.phase = 0; - self.touch(); - other = oldother; - return; - } - } - } - METHOD(Bumblebee, vr_death, void(Bumblebee thisveh, entity instance)) - { - entity oldself = self; - setself(instance); - - CSQCModel_UnlinkEntity(self); - - // Hide beam - if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) - self.gun3.enemy.effects |= EF_NODRAW; - - if(self.gunner1) - { - setself(self.gunner1); - oldself.gun1.vehicle_exit(VHEF_EJECT); - setself(oldself); - } - - if(self.gunner2) - { - setself(self.gunner2); - oldself.gun2.vehicle_exit(VHEF_EJECT); - setself(oldself); - } - - self.vehicle_exit(VHEF_EJECT); - - fixedmakevectors(self.angles); - vehicle_tossgib(self.gun1, self.velocity + v_right * 300 + v_up * 100 + randomvec() * 200, "cannon_right", rint(random()), rint(random()), 6, randomvec() * 200); - vehicle_tossgib(self.gun2, self.velocity + v_right * -300 + v_up * 100 + randomvec() * 200, "cannon_left", rint(random()), rint(random()), 6, randomvec() * 200); - vehicle_tossgib(self.gun3, self.velocity + v_forward * 300 + v_up * -100 + randomvec() * 200, "raygun", rint(random()), rint(random()), 6, randomvec() * 300); - - entity _body = vehicle_tossgib(self, self.velocity + randomvec() * 200, "", rint(random()), rint(random()), 6, randomvec() * 100); - - if(random() > 0.5) - _body.touch = bumblebee_blowup; - else - _body.touch = func_null; - - _body.think = bumblebee_diethink; - _body.nextthink = time; - _body.wait = time + 2 + (random() * 8); - _body.owner = self; - _body.enemy = self.enemy; - _body.scale = 1.5; - _body.angles = self.angles; - - Send_Effect(EFFECT_EXPLOSION_MEDIUM, findbetterlocation(self.origin, 16), '0 0 0', 1); - - self.health = 0; - self.event_damage = func_null; - self.solid = SOLID_NOT; - self.takedamage = DAMAGE_NO; - self.deadflag = DEAD_DYING; - self.movetype = MOVETYPE_NONE; - self.effects = EF_NODRAW; - self.colormod = '0 0 0'; - self.avelocity = '0 0 0'; - self.velocity = '0 0 0'; - self.touch = func_null; - self.nextthink = 0; - - setorigin(self, self.pos1); - - setself(oldself); - } - METHOD(Bumblebee, vr_spawn, void(Bumblebee thisveh, entity instance)) - { - SELFPARAM(); - if(!self.gun1) - { - // for some reason, autosizing of the shield entity refuses to work for this one so set it up in advance. - self.vehicle_shieldent = spawn(); - self.vehicle_shieldent.effects = EF_LOWPRECISION; - setmodel(self.vehicle_shieldent, MDL_VEH_BUMBLEBEE_SHIELD); - setattachment(self.vehicle_shieldent, self, ""); - setorigin(self.vehicle_shieldent, real_origin(self) - self.origin); - self.vehicle_shieldent.scale = 512 / vlen(self.maxs - self.mins); - self.vehicle_shieldent.think = shieldhit_think; - self.vehicle_shieldent.alpha = -1; - self.vehicle_shieldent.effects = EF_LOWPRECISION | EF_NODRAW; - - self.gun1 = new(vehicle_playerslot); - self.gun2 = new(vehicle_playerslot); - self.gun3 = new(bumblebee_raygun); - - self.vehicle_flags |= VHF_MULTISLOT; - - self.gun1.owner = self; - self.gun2.owner = self; - self.gun3.owner = self; - - setmodel(self.gun1, MDL_VEH_BUMBLEBEE_CANNON_RIGHT); - setmodel(self.gun2, MDL_VEH_BUMBLEBEE_CANNON_LEFT); - setmodel(self.gun3, MDL_VEH_BUMBLEBEE_CANNON_CENTER); - - setattachment(self.gun1, self, "cannon_right"); - setattachment(self.gun2, self, "cannon_left"); - - // Angled bones are no fun, messes up gun-aim; so work arround it. - self.gun3.pos1 = self.angles; - self.angles = '0 0 0'; - vector ofs = gettaginfo(self, gettagindex(self, "raygun")); - ofs -= self.origin; - setattachment(self.gun3, self, ""); - setorigin(self.gun3, ofs); - self.angles = self.gun3.pos1; - - vehicle_addplayerslot(self, self.gun1, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumblebee_gunner_frame, bumblebee_gunner_exit, bumblebee_gunner_enter); - vehicle_addplayerslot(self, self.gun2, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumblebee_gunner_frame, bumblebee_gunner_exit, bumblebee_gunner_enter); - - setorigin(self.vehicle_hudmodel, '50 0 -5'); // Move cockpit forward - down. - setorigin(self.vehicle_viewport, '5 0 2'); // Move camera forward up - - //fixme-model-bones - setorigin(self.gun1.vehicle_hudmodel, '90 -27 -23'); - setorigin(self.gun1.vehicle_viewport, '-85 0 50'); - //fixme-model-bones - setorigin(self.gun2.vehicle_hudmodel, '90 27 -23'); - setorigin(self.gun2.vehicle_viewport, '-85 0 50'); - - self.scale = 1.5; - - // Raygun beam - if(self.gun3.enemy == world) - { - self.gun3.enemy = spawn(); - Net_LinkEntity(self.gun3.enemy, true, 0, bumble_raygun_send); - self.gun3.enemy.SendFlags = BRG_SETUP; - self.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun; - self.gun3.enemy.effects = EF_NODRAW | EF_LOWPRECISION; - } - } - - self.vehicle_health = autocvar_g_vehicle_bumblebee_health; - self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield; - self.solid = SOLID_BBOX; - self.movetype = MOVETYPE_TOSS; - self.damageforcescale = 0.025; - - self.PlayerPhysplug = bumblebee_pilot_frame; - - setorigin(self, self.origin + '0 0 25'); - } - METHOD(Bumblebee, vr_setup, void(Bumblebee thisveh, entity instance)) - { - SELFPARAM(); - if(autocvar_g_vehicle_bumblebee_energy) - if(autocvar_g_vehicle_bumblebee_energy_regen) - self.vehicle_flags |= VHF_ENERGYREGEN; +METHOD(Bumblebee, vr_impact, void(Bumblebee thisveh, entity instance)) +{ + if(autocvar_g_vehicle_bumblebee_bouncepain) + vehicles_impact(autocvar_g_vehicle_bumblebee_bouncepain_x, autocvar_g_vehicle_bumblebee_bouncepain_y, autocvar_g_vehicle_bumblebee_bouncepain_z); +} +METHOD(Bumblebee, vr_enter, void(Bumblebee thisveh, entity instance)) +{ + SELFPARAM(); + self.touch = bumblebee_touch; + self.nextthink = 0; + self.movetype = MOVETYPE_BOUNCEMISSILE; +} +METHOD(Bumblebee, vr_think, void(Bumblebee thisveh, entity instance)) +{ + SELFPARAM(); + self.angles_z *= 0.8; + self.angles_x *= 0.8; + + self.nextthink = time; + + if(!self.owner) + { + entity oldself = self; + if(self.gunner1) + { + setself(self.gunner1); + oldself.gun1.vehicle_exit(VHEF_EJECT); + entity oldother = other; + other = self; + setself(oldself); + self.phase = 0; + self.touch(); + other = oldother; + return; + } + + if(self.gunner2) + { + setself(self.gunner2); + oldself.gun2.vehicle_exit(VHEF_EJECT); + entity oldother = other; + other = self; + setself(oldself); + self.phase = 0; + self.touch(); + other = oldother; + return; + } + } +} +METHOD(Bumblebee, vr_death, void(Bumblebee thisveh, entity instance)) +{ + entity oldself = self; + setself(instance); + + CSQCModel_UnlinkEntity(self); + + // Hide beam + if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) + self.gun3.enemy.effects |= EF_NODRAW; + + if(self.gunner1) + { + setself(self.gunner1); + oldself.gun1.vehicle_exit(VHEF_EJECT); + setself(oldself); + } + + if(self.gunner2) + { + setself(self.gunner2); + oldself.gun2.vehicle_exit(VHEF_EJECT); + setself(oldself); + } + + self.vehicle_exit(VHEF_EJECT); + + fixedmakevectors(self.angles); + vehicle_tossgib(self.gun1, self.velocity + v_right * 300 + v_up * 100 + randomvec() * 200, "cannon_right", rint(random()), rint(random()), 6, randomvec() * 200); + vehicle_tossgib(self.gun2, self.velocity + v_right * -300 + v_up * 100 + randomvec() * 200, "cannon_left", rint(random()), rint(random()), 6, randomvec() * 200); + vehicle_tossgib(self.gun3, self.velocity + v_forward * 300 + v_up * -100 + randomvec() * 200, "raygun", rint(random()), rint(random()), 6, randomvec() * 300); + + entity _body = vehicle_tossgib(self, self.velocity + randomvec() * 200, "", rint(random()), rint(random()), 6, randomvec() * 100); + + if(random() > 0.5) + _body.touch = bumblebee_blowup; + else + _body.touch = func_null; + + _body.think = bumblebee_diethink; + _body.nextthink = time; + _body.wait = time + 2 + (random() * 8); + _body.owner = self; + _body.enemy = self.enemy; + _body.scale = 1.5; + _body.angles = self.angles; + + Send_Effect(EFFECT_EXPLOSION_MEDIUM, findbetterlocation(self.origin, 16), '0 0 0', 1); + + self.health = 0; + self.event_damage = func_null; + self.solid = SOLID_NOT; + self.takedamage = DAMAGE_NO; + self.deadflag = DEAD_DYING; + self.movetype = MOVETYPE_NONE; + self.effects = EF_NODRAW; + self.colormod = '0 0 0'; + self.avelocity = '0 0 0'; + self.velocity = '0 0 0'; + self.touch = func_null; + self.nextthink = 0; + + setorigin(self, self.pos1); + + setself(oldself); +} +METHOD(Bumblebee, vr_spawn, void(Bumblebee thisveh, entity instance)) +{ + SELFPARAM(); + if(!self.gun1) + { + // for some reason, autosizing of the shield entity refuses to work for this one so set it up in advance. + self.vehicle_shieldent = spawn(); + self.vehicle_shieldent.effects = EF_LOWPRECISION; + setmodel(self.vehicle_shieldent, MDL_VEH_BUMBLEBEE_SHIELD); + setattachment(self.vehicle_shieldent, self, ""); + setorigin(self.vehicle_shieldent, real_origin(self) - self.origin); + self.vehicle_shieldent.scale = 512 / vlen(self.maxs - self.mins); + self.vehicle_shieldent.think = shieldhit_think; + self.vehicle_shieldent.alpha = -1; + self.vehicle_shieldent.effects = EF_LOWPRECISION | EF_NODRAW; + + self.gun1 = new(vehicle_playerslot); + self.gun2 = new(vehicle_playerslot); + self.gun3 = new(bumblebee_raygun); + + self.vehicle_flags |= VHF_MULTISLOT; + + self.gun1.owner = self; + self.gun2.owner = self; + self.gun3.owner = self; + + setmodel(self.gun1, MDL_VEH_BUMBLEBEE_CANNON_RIGHT); + setmodel(self.gun2, MDL_VEH_BUMBLEBEE_CANNON_LEFT); + setmodel(self.gun3, MDL_VEH_BUMBLEBEE_CANNON_CENTER); + + setattachment(self.gun1, self, "cannon_right"); + setattachment(self.gun2, self, "cannon_left"); + + // Angled bones are no fun, messes up gun-aim; so work arround it. + self.gun3.pos1 = self.angles; + self.angles = '0 0 0'; + vector ofs = gettaginfo(self, gettagindex(self, "raygun")); + ofs -= self.origin; + setattachment(self.gun3, self, ""); + setorigin(self.gun3, ofs); + self.angles = self.gun3.pos1; + + vehicle_addplayerslot(self, self.gun1, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumblebee_gunner_frame, bumblebee_gunner_exit, bumblebee_gunner_enter); + vehicle_addplayerslot(self, self.gun2, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumblebee_gunner_frame, bumblebee_gunner_exit, bumblebee_gunner_enter); + + setorigin(self.vehicle_hudmodel, '50 0 -5'); // Move cockpit forward - down. + setorigin(self.vehicle_viewport, '5 0 2'); // Move camera forward up + + //fixme-model-bones + setorigin(self.gun1.vehicle_hudmodel, '90 -27 -23'); + setorigin(self.gun1.vehicle_viewport, '-85 0 50'); + //fixme-model-bones + setorigin(self.gun2.vehicle_hudmodel, '90 27 -23'); + setorigin(self.gun2.vehicle_viewport, '-85 0 50'); + + self.scale = 1.5; + + // Raygun beam + if(self.gun3.enemy == world) + { + self.gun3.enemy = spawn(); + Net_LinkEntity(self.gun3.enemy, true, 0, bumble_raygun_send); + self.gun3.enemy.SendFlags = BRG_SETUP; + self.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun; + self.gun3.enemy.effects = EF_NODRAW | EF_LOWPRECISION; + } + } + + self.vehicle_health = autocvar_g_vehicle_bumblebee_health; + self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield; + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_TOSS; + self.damageforcescale = 0.025; + + self.PlayerPhysplug = bumblebee_pilot_frame; + + setorigin(self, self.origin + '0 0 25'); +} +METHOD(Bumblebee, vr_setup, void(Bumblebee thisveh, entity instance)) +{ + SELFPARAM(); + if(autocvar_g_vehicle_bumblebee_energy) + if(autocvar_g_vehicle_bumblebee_energy_regen) + self.vehicle_flags |= VHF_ENERGYREGEN; - if(autocvar_g_vehicle_bumblebee_shield) - self.vehicle_flags |= VHF_HASSHIELD; + if(autocvar_g_vehicle_bumblebee_shield) + self.vehicle_flags |= VHF_HASSHIELD; - if(autocvar_g_vehicle_bumblebee_shield_regen) - self.vehicle_flags |= VHF_SHIELDREGEN; + if(autocvar_g_vehicle_bumblebee_shield_regen) + self.vehicle_flags |= VHF_SHIELDREGEN; - if(autocvar_g_vehicle_bumblebee_health_regen) - self.vehicle_flags |= VHF_HEALTHREGEN; + if(autocvar_g_vehicle_bumblebee_health_regen) + self.vehicle_flags |= VHF_HEALTHREGEN; - self.vehicle_exit = bumblebee_exit; - self.respawntime = autocvar_g_vehicle_bumblebee_respawntime; - self.vehicle_health = autocvar_g_vehicle_bumblebee_health; - self.max_health = self.vehicle_health; - self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield; - } + self.vehicle_exit = bumblebee_exit; + self.respawntime = autocvar_g_vehicle_bumblebee_respawntime; + self.vehicle_health = autocvar_g_vehicle_bumblebee_health; + self.max_health = self.vehicle_health; + self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield; +} #endif // SVQC #ifdef CSQC @@ -963,40 +963,40 @@ void CSQC_BUMBLE_GUN_HUD() string_null, '0 0 0'); } - METHOD(Bumblebee, vr_hud, void(Bumblebee thisveh)) - { - Vehicles_drawHUD(VEH_BUMBLEBEE.m_icon, "vehicle_bumble_weapon1", "vehicle_bumble_weapon2", - "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, - "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color); - - float hudAlpha = autocvar_hud_panel_fg_alpha; - float blinkValue = 0.55 + sin(time * 7) * 0.45; - vector tmpPos = '0 0 0'; - vector tmpSize = '1 1 1' * hud_fontsize; - tmpPos.x = vehicleHud_Pos.x + vehicleHud_Size.x * (520/768); - - if(!AuxiliaryXhair[1].draw2d) - { - tmpPos.y = vehicleHud_Pos.y + vehicleHud_Size.y * (96/256) - tmpSize.y; - drawstring(tmpPos, _("No right gunner!"), tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL); - } - - if(!AuxiliaryXhair[2].draw2d) - { - tmpPos.y = vehicleHud_Pos.y + vehicleHud_Size.y * (160/256); - drawstring(tmpPos, _("No left gunner!"), tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL); - } - } - METHOD(Bumblebee, vr_crosshair, void(Bumblebee thisveh)) - { - Vehicles_drawCrosshair(vCROSS_HEAL); - } - METHOD(Bumblebee, vr_setup, void(Bumblebee thisveh, entity instance)) - { - AuxiliaryXhair[0].axh_image = vCROSS_LOCK; // Raygun-locked - AuxiliaryXhair[1].axh_image = vCROSS_BURST; // Gunner1 - AuxiliaryXhair[2].axh_image = vCROSS_BURST; // Gunner2 - } +METHOD(Bumblebee, vr_hud, void(Bumblebee thisveh)) +{ + Vehicles_drawHUD(VEH_BUMBLEBEE.m_icon, "vehicle_bumble_weapon1", "vehicle_bumble_weapon2", + "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, + "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color); + + float hudAlpha = autocvar_hud_panel_fg_alpha; + float blinkValue = 0.55 + sin(time * 7) * 0.45; + vector tmpPos = '0 0 0'; + vector tmpSize = '1 1 1' * hud_fontsize; + tmpPos.x = vehicleHud_Pos.x + vehicleHud_Size.x * (520/768); + + if(!AuxiliaryXhair[1].draw2d) + { + tmpPos.y = vehicleHud_Pos.y + vehicleHud_Size.y * (96/256) - tmpSize.y; + drawstring(tmpPos, _("No right gunner!"), tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL); + } + + if(!AuxiliaryXhair[2].draw2d) + { + tmpPos.y = vehicleHud_Pos.y + vehicleHud_Size.y * (160/256); + drawstring(tmpPos, _("No left gunner!"), tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL); + } +} +METHOD(Bumblebee, vr_crosshair, void(Bumblebee thisveh)) +{ + Vehicles_drawCrosshair(vCROSS_HEAL); +} +METHOD(Bumblebee, vr_setup, void(Bumblebee thisveh, entity instance)) +{ + AuxiliaryXhair[0].axh_image = vCROSS_LOCK; // Raygun-locked + AuxiliaryXhair[1].axh_image = vCROSS_BURST; // Gunner1 + AuxiliaryXhair[2].axh_image = vCROSS_BURST; // Gunner2 +} #endif #endif diff --git a/qcsrc/common/vehicles/vehicle/racer.qc b/qcsrc/common/vehicles/vehicle/racer.qc index 7e9632d96..b9a1a7174 100644 --- a/qcsrc/common/vehicles/vehicle/racer.qc +++ b/qcsrc/common/vehicles/vehicle/racer.qc @@ -127,7 +127,7 @@ void racer_align4point(entity this, float _delta) { uforce = autocvar_g_vehicle_racer_water_upforcedamper; - if(this.owner.BUTTON_CROUCH && time < this.air_finished) + if(PHYS_INPUT_BUTTON_CROUCH(this.owner) && time < this.air_finished) this.velocity_z += 30; else this.velocity_z += 200; @@ -187,13 +187,13 @@ float racer_frame() if(IS_DEAD(racer)) { setself(player); - player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; + PHYS_INPUT_BUTTON_ATCK(player) = PHYS_INPUT_BUTTON_ATCK2(player) = false; return 1; } racer_align4point(self, PHYS_INPUT_TIMELENGTH); - player.BUTTON_ZOOM = player.BUTTON_CROUCH = 0; + PHYS_INPUT_BUTTON_ZOOM(player) = PHYS_INPUT_BUTTON_CROUCH(player) = false; crosshair_trace(player); @@ -311,7 +311,7 @@ float racer_frame() #ifdef SVQC Weapon wep1 = WEP_RACER; if (!forbidWeaponUse(player)) - if (player.BUTTON_ATCK) + if (PHYS_INPUT_BUTTON_ATCK(player)) if (wep1.wr_checkammo1(wep1)) { string tagname = (racer.cnt) @@ -346,7 +346,7 @@ float racer_frame() if(!forbidWeaponUse(player)) if(time > racer.delay) - if(player.BUTTON_ATCK2) + if(PHYS_INPUT_BUTTON_ATCK2(player)) { racer.misc_bulletcounter += 1; racer.delay = time + 0.3; @@ -388,7 +388,7 @@ float racer_frame() if(racer.vehicle_flags & VHF_HASSHIELD) VEHICLE_UPDATE_PLAYER(player, shield, racer); - player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; + PHYS_INPUT_BUTTON_ATCK(player) = PHYS_INPUT_BUTTON_ATCK2(player) = false; #endif setorigin(player,racer.origin + '0 0 32'); @@ -560,140 +560,140 @@ void racer_draw() #endif #endif - METHOD(Racer, vr_impact, void(Racer thisveh, entity instance)) - { - #ifdef SVQC - if(autocvar_g_vehicle_racer_bouncepain) - vehicles_impact(autocvar_g_vehicle_racer_bouncepain_x, autocvar_g_vehicle_racer_bouncepain_y, autocvar_g_vehicle_racer_bouncepain_z); - #endif - } +METHOD(Racer, vr_impact, void(Racer thisveh, entity instance)) +{ +#ifdef SVQC + if(autocvar_g_vehicle_racer_bouncepain) + vehicles_impact(autocvar_g_vehicle_racer_bouncepain_x, autocvar_g_vehicle_racer_bouncepain_y, autocvar_g_vehicle_racer_bouncepain_z); +#endif +} - METHOD(Racer, vr_enter, void(Racer thisveh, entity instance)) - { - #ifdef SVQC - self.movetype = MOVETYPE_BOUNCE; - self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health) * 100; - self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield) * 100; +METHOD(Racer, vr_enter, void(Racer thisveh, entity instance)) +{ +#ifdef SVQC + self.movetype = MOVETYPE_BOUNCE; + self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health) * 100; + self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield) * 100; - if(self.owner.flagcarried) - setorigin(self.owner.flagcarried, '-190 0 96'); - #elif defined(CSQC) + if(self.owner.flagcarried) + setorigin(self.owner.flagcarried, '-190 0 96'); +#elif defined(CSQC) - self.move_movetype = MOVETYPE_BOUNCE; - #endif - } + self.move_movetype = MOVETYPE_BOUNCE; +#endif +} - METHOD(Racer, vr_spawn, void(Racer thisveh, entity instance)) - { - #ifdef SVQC - if(self.scale != 0.5) - { - if(autocvar_g_vehicle_racer_hovertype != 0) - racer_force_from_tag = vehicles_force_fromtag_maglev; - else - racer_force_from_tag = vehicles_force_fromtag_hover; - - // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel). - self.scale = 0.5; - setattachment(self.vehicle_hudmodel, self, ""); - setattachment(self.vehicle_viewport, self, "tag_viewport"); - - self.mass = 900; - } - - self.think = racer_think; - self.nextthink = time; - self.vehicle_health = autocvar_g_vehicle_racer_health; - self.vehicle_shield = autocvar_g_vehicle_racer_shield; - - self.movetype = MOVETYPE_TOSS; - self.solid = SOLID_SLIDEBOX; - self.delay = time; - self.scale = 0.5; - - self.PlayerPhysplug = racer_frame; - - self.bouncefactor = autocvar_g_vehicle_racer_bouncefactor; - self.bouncestop = autocvar_g_vehicle_racer_bouncestop; - self.damageforcescale = 0.5; - self.vehicle_health = autocvar_g_vehicle_racer_health; - self.vehicle_shield = autocvar_g_vehicle_racer_shield; - #endif - } +METHOD(Racer, vr_spawn, void(Racer thisveh, entity instance)) +{ +#ifdef SVQC + if(self.scale != 0.5) + { + if(autocvar_g_vehicle_racer_hovertype != 0) + racer_force_from_tag = vehicles_force_fromtag_maglev; + else + racer_force_from_tag = vehicles_force_fromtag_hover; + + // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel). + self.scale = 0.5; + setattachment(self.vehicle_hudmodel, self, ""); + setattachment(self.vehicle_viewport, self, "tag_viewport"); + + self.mass = 900; + } + + self.think = racer_think; + self.nextthink = time; + self.vehicle_health = autocvar_g_vehicle_racer_health; + self.vehicle_shield = autocvar_g_vehicle_racer_shield; + + self.movetype = MOVETYPE_TOSS; + self.solid = SOLID_SLIDEBOX; + self.delay = time; + self.scale = 0.5; + + self.PlayerPhysplug = racer_frame; + + self.bouncefactor = autocvar_g_vehicle_racer_bouncefactor; + self.bouncestop = autocvar_g_vehicle_racer_bouncestop; + self.damageforcescale = 0.5; + self.vehicle_health = autocvar_g_vehicle_racer_health; + self.vehicle_shield = autocvar_g_vehicle_racer_shield; +#endif +} - METHOD(Racer, vr_death, void(Racer thisveh, entity instance)) - { - #ifdef SVQC - instance.SendEntity = func_null; // stop networking this racer (for now) - instance.health = 0; - instance.event_damage = func_null; - instance.solid = SOLID_CORPSE; - instance.takedamage = DAMAGE_NO; - instance.deadflag = DEAD_DYING; - instance.movetype = MOVETYPE_BOUNCE; - instance.wait = time; - instance.delay = 2 + time + random() * 3; - instance.cnt = 1 + random() * 2; - instance.touch = racer_deadtouch; - - Send_Effect(EFFECT_EXPLOSION_MEDIUM, instance.origin, '0 0 0', 1); - - if(random() < 0.5) - instance.avelocity_z = 32; - else - instance.avelocity_z = -32; - - instance.avelocity_x = -vlen(instance.velocity) * 0.2; - instance.velocity += '0 0 700'; - instance.colormod = '-0.5 -0.5 -0.5'; - - instance.think = racer_blowup_think; - instance.nextthink = time; - #endif - } +METHOD(Racer, vr_death, void(Racer thisveh, entity instance)) +{ +#ifdef SVQC + instance.SendEntity = func_null; // stop networking this racer (for now) + instance.health = 0; + instance.event_damage = func_null; + instance.solid = SOLID_CORPSE; + instance.takedamage = DAMAGE_NO; + instance.deadflag = DEAD_DYING; + instance.movetype = MOVETYPE_BOUNCE; + instance.wait = time; + instance.delay = 2 + time + random() * 3; + instance.cnt = 1 + random() * 2; + instance.touch = racer_deadtouch; + + Send_Effect(EFFECT_EXPLOSION_MEDIUM, instance.origin, '0 0 0', 1); + + if(random() < 0.5) + instance.avelocity_z = 32; + else + instance.avelocity_z = -32; + + instance.avelocity_x = -vlen(instance.velocity) * 0.2; + instance.velocity += '0 0 700'; + instance.colormod = '-0.5 -0.5 -0.5'; + + instance.think = racer_blowup_think; + instance.nextthink = time; +#endif +} #ifdef CSQC - METHOD(Racer, vr_hud, void(Racer thisveh)) - { - Vehicles_drawHUD(VEH_RACER.m_icon, "vehicle_racer_weapon1", "vehicle_racer_weapon2", - "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, - "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color); - } - METHOD(Racer, vr_crosshair, void(Racer thisveh)) - { - Vehicles_drawCrosshair(vCROSS_GUIDE); - } +METHOD(Racer, vr_hud, void(Racer thisveh)) +{ + Vehicles_drawHUD(VEH_RACER.m_icon, "vehicle_racer_weapon1", "vehicle_racer_weapon2", + "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, + "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color); +} +METHOD(Racer, vr_crosshair, void(Racer thisveh)) +{ + Vehicles_drawCrosshair(vCROSS_GUIDE); +} #endif - METHOD(Racer, vr_setup, void(Racer thisveh, entity instance)) - { - #ifdef SVQC - self.vehicle_exit = racer_exit; - #endif - - #ifdef SVQC - // we have no need to network energy - if(autocvar_g_vehicle_racer_energy) - if(autocvar_g_vehicle_racer_energy_regen) - self.vehicle_flags |= VHF_ENERGYREGEN; - - if(autocvar_g_vehicle_racer_shield) - self.vehicle_flags |= VHF_HASSHIELD; - - if(autocvar_g_vehicle_racer_shield_regen) - self.vehicle_flags |= VHF_SHIELDREGEN; - - if(autocvar_g_vehicle_racer_health_regen) - self.vehicle_flags |= VHF_HEALTHREGEN; - - self.respawntime = autocvar_g_vehicle_racer_respawntime; - self.vehicle_health = autocvar_g_vehicle_racer_health; - self.vehicle_shield = autocvar_g_vehicle_racer_shield; - self.max_health = self.vehicle_health; - #endif - - #ifdef CSQC - AuxiliaryXhair[0].axh_image = vCROSS_LOCK; // Rocket - #endif - } +METHOD(Racer, vr_setup, void(Racer thisveh, entity instance)) +{ +#ifdef SVQC + self.vehicle_exit = racer_exit; +#endif + +#ifdef SVQC + // we have no need to network energy + if(autocvar_g_vehicle_racer_energy) + if(autocvar_g_vehicle_racer_energy_regen) + self.vehicle_flags |= VHF_ENERGYREGEN; + + if(autocvar_g_vehicle_racer_shield) + self.vehicle_flags |= VHF_HASSHIELD; + + if(autocvar_g_vehicle_racer_shield_regen) + self.vehicle_flags |= VHF_SHIELDREGEN; + + if(autocvar_g_vehicle_racer_health_regen) + self.vehicle_flags |= VHF_HEALTHREGEN; + + self.respawntime = autocvar_g_vehicle_racer_respawntime; + self.vehicle_health = autocvar_g_vehicle_racer_health; + self.vehicle_shield = autocvar_g_vehicle_racer_shield; + self.max_health = self.vehicle_health; +#endif + +#ifdef CSQC + AuxiliaryXhair[0].axh_image = vCROSS_LOCK; // Rocket +#endif +} #endif diff --git a/qcsrc/common/vehicles/vehicle/raptor.qc b/qcsrc/common/vehicles/vehicle/raptor.qc index 67c67d948..8f8f3cf72 100644 --- a/qcsrc/common/vehicles/vehicle/raptor.qc +++ b/qcsrc/common/vehicles/vehicle/raptor.qc @@ -204,7 +204,7 @@ float raptor_frame() if(IS_DEAD(raptor)) { setself(player); - player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; + PHYS_INPUT_BUTTON_ATCK(player) = PHYS_INPUT_BUTTON_ATCK2(player) = false; return 1; } crosshair_trace(player); @@ -213,10 +213,10 @@ float raptor_frame() //{ if(raptor.angles_z > 50 || raptor.angles_z < -50) { - if(player.BUTTON_JUMP) + if(PHYS_INPUT_BUTTON_JUMP(player)) { - player.BUTTON_CROUCH = true; - player.BUTTON_JUMP = false; + PHYS_INPUT_BUTTON_CROUCH(player) = true; + PHYS_INPUT_BUTTON_JUMP(player) = false; } } //} @@ -279,9 +279,9 @@ float raptor_frame() raptor.angles_z = 0; } - if(player.BUTTON_CROUCH) + if(PHYS_INPUT_BUTTON_CROUCH(player)) df -= v_up * autocvar_g_vehicle_raptor_speed_down; - else if (player.BUTTON_JUMP) + else if (PHYS_INPUT_BUTTON_JUMP(player)) df += v_up * autocvar_g_vehicle_raptor_speed_up; raptor.velocity += df * frametime; @@ -392,7 +392,7 @@ float raptor_frame() Weapon wep1 = WEP_RAPTOR; if(!forbidWeaponUse(player)) - if(player.BUTTON_ATCK) + if(PHYS_INPUT_BUTTON_ATCK(player)) if (wep1.wr_checkammo1(wep1)) { .entity weaponentity = weaponentities[0]; @@ -413,7 +413,7 @@ float raptor_frame() if(raptor.vehicle_weapon2mode == RSM_BOMB) { if(time > raptor.lip + autocvar_g_vehicle_raptor_bombs_refire) - if(player.BUTTON_ATCK2) + if(PHYS_INPUT_BUTTON_ATCK2(player)) { .entity weaponentity = weaponentities[1]; wep2a.wr_think(wep2a, self, weaponentity, 2); @@ -425,7 +425,7 @@ float raptor_frame() { Weapon wep2b = WEP_RAPTOR_FLARE; if(time > raptor.lip + autocvar_g_vehicle_raptor_flare_refire) - if(player.BUTTON_ATCK2) + if(PHYS_INPUT_BUTTON_ATCK2(player)) { .entity weaponentity = weaponentities[1]; wep2b.wr_think(wep2b, self, weaponentity, 2); @@ -464,7 +464,7 @@ float raptor_frame() if(self.vehicle_flags & VHF_HASSHIELD) VEHICLE_UPDATE_PLAYER(player, shield, raptor); - player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0; + PHYS_INPUT_BUTTON_ATCK(player) = PHYS_INPUT_BUTTON_ATCK2(player) = PHYS_INPUT_BUTTON_CROUCH(player) = false; setself(player); return 1; @@ -495,7 +495,7 @@ float raptor_takeoff() raptor.velocity_z = min(raptor.velocity_z * 1.5, 256); self.bomb1.gun1.avelocity_y = 90 + ((raptor.frame / 25) * 25000); self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y; - player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0; + PHYS_INPUT_BUTTON_ATCK(player) = PHYS_INPUT_BUTTON_ATCK2(player) = PHYS_INPUT_BUTTON_CROUCH(player) = false; setorigin(player, raptor.origin + '0 0 32'); } @@ -521,7 +521,7 @@ float raptor_takeoff() if(self.vehicle_flags & VHF_HASSHIELD) VEHICLE_UPDATE_PLAYER(player, shield, raptor); - player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0; + PHYS_INPUT_BUTTON_ATCK(player) = PHYS_INPUT_BUTTON_ATCK2(player) = PHYS_INPUT_BUTTON_CROUCH(player) = false; setself(player); return 1; } @@ -617,243 +617,243 @@ spawnfunc(vehicle_raptor) if(!vehicle_initialize(VEH_RAPTOR, false)) { remove(self); return; } } - METHOD(Raptor, vr_impact, void(Raptor thisveh, entity instance)) - { - if(autocvar_g_vehicle_raptor_bouncepain) - vehicles_impact(autocvar_g_vehicle_raptor_bouncepain_x, autocvar_g_vehicle_raptor_bouncepain_y, autocvar_g_vehicle_raptor_bouncepain_z); - } - METHOD(Raptor, vr_enter, void(Raptor thisveh, entity instance)) - { - self.vehicle_weapon2mode = RSM_BOMB; - self.owner.PlayerPhysplug = raptor_takeoff; - self.movetype = MOVETYPE_BOUNCEMISSILE; - self.solid = SOLID_SLIDEBOX; - self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_raptor_health) * 100; - self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_raptor_shield) * 100; - self.velocity_z = 1; // Nudge upwards to takeoff sequense can work. - self.tur_head.exteriormodeltoclient = self.owner; - - self.delay = time + autocvar_g_vehicle_raptor_bombs_refire; - self.lip = time; - - if(self.owner.flagcarried) - setorigin(self.owner.flagcarried, '-20 0 96'); - - CSQCVehicleSetup(self.owner, 0); - } - METHOD(Raptor, vr_death, void(Raptor thisveh, entity instance)) - { - instance.health = 0; - instance.event_damage = func_null; - instance.solid = SOLID_CORPSE; - instance.takedamage = DAMAGE_NO; - instance.deadflag = DEAD_DYING; - instance.movetype = MOVETYPE_BOUNCE; - instance.think = raptor_diethink; - instance.nextthink = time; - instance.wait = time + 5 + (random() * 5); - - Send_Effect(EFFECT_EXPLOSION_MEDIUM, findbetterlocation (instance.origin, 16), '0 0 0', 1); - - instance.velocity_z += 600; - - instance.avelocity = '0 0.5 1' * (random() * 400); - instance.avelocity -= '0 0.5 1' * (random() * 400); - - instance.colormod = '-0.5 -0.5 -0.5'; - instance.touch = raptor_blowup; - } - METHOD(Raptor, vr_spawn, void(Raptor thisveh, entity instance)) - { - if(!self.gun1) - { - entity spinner; - vector ofs; - - //FIXME: Camera is in a bad place in HUD model. - //setorigin(self.vehicle_viewport, '25 0 5'); - - self.vehicles_impulse = raptor_impulse; - - self.frame = 0; - - self.bomb1 = new(raptor_bomb); - self.bomb2 = new(raptor_bomb); - self.gun1 = new(raptor_gun); - self.gun2 = new(raptor_gun); - - setmodel(self.bomb1, MDL_VEH_RAPTOR_CB_FOLDED); - setmodel(self.bomb2, MDL_VEH_RAPTOR_CB_FOLDED); - setmodel(self.gun1, MDL_VEH_RAPTOR_GUN); - setmodel(self.gun2, MDL_VEH_RAPTOR_GUN); - setmodel(self.tur_head, MDL_VEH_RAPTOR_TAIL); - - setattachment(self.bomb1, self, "bombmount_left"); - setattachment(self.bomb2, self, "bombmount_right"); - setattachment(self.tur_head, self,"root"); - - // FIXMODEL Guns mounts to angled bones - self.bomb1.angles = self.angles; - self.angles = '0 0 0'; - // This messes up gun-aim, so work arround it. - //setattachment(self.gun1, self, "gunmount_left"); - ofs = gettaginfo(self, gettagindex(self, "gunmount_left")); - ofs -= self.origin; - setattachment(self.gun1, self, ""); - setorigin(self.gun1, ofs); - - //setattachment(self.gun2, self, "gunmount_right"); - ofs = gettaginfo(self, gettagindex(self, "gunmount_right")); - ofs -= self.origin; - setattachment(self.gun2, self, ""); - setorigin(self.gun2, ofs); - - self.angles = self.bomb1.angles; - self.bomb1.angles = '0 0 0'; - - spinner = new(raptor_spinner); - spinner.owner = self; - setmodel(spinner, MDL_VEH_RAPTOR_PROP); - setattachment(spinner, self, "engine_left"); - spinner.movetype = MOVETYPE_NOCLIP; - spinner.avelocity = '0 90 0'; - self.bomb1.gun1 = spinner; - - spinner = new(raptor_spinner); - spinner.owner = self; - setmodel(spinner, MDL_VEH_RAPTOR_PROP); - setattachment(spinner, self, "engine_right"); - spinner.movetype = MOVETYPE_NOCLIP; - spinner.avelocity = '0 -90 0'; - self.bomb1.gun2 = spinner; - - // Sigh. - self.bomb1.think = raptor_rotor_anglefix; - self.bomb1.nextthink = time; - - self.mass = 1 ; - } - - self.frame = 0; - self.vehicle_health = autocvar_g_vehicle_raptor_health; - self.vehicle_shield = autocvar_g_vehicle_raptor_shield; - self.movetype = MOVETYPE_TOSS; - self.solid = SOLID_SLIDEBOX; - self.vehicle_energy = 1; +METHOD(Raptor, vr_impact, void(Raptor thisveh, entity instance)) +{ + if(autocvar_g_vehicle_raptor_bouncepain) + vehicles_impact(autocvar_g_vehicle_raptor_bouncepain_x, autocvar_g_vehicle_raptor_bouncepain_y, autocvar_g_vehicle_raptor_bouncepain_z); +} +METHOD(Raptor, vr_enter, void(Raptor thisveh, entity instance)) +{ + self.vehicle_weapon2mode = RSM_BOMB; + self.owner.PlayerPhysplug = raptor_takeoff; + self.movetype = MOVETYPE_BOUNCEMISSILE; + self.solid = SOLID_SLIDEBOX; + self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_raptor_health) * 100; + self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_raptor_shield) * 100; + self.velocity_z = 1; // Nudge upwards to takeoff sequense can work. + self.tur_head.exteriormodeltoclient = self.owner; + + self.delay = time + autocvar_g_vehicle_raptor_bombs_refire; + self.lip = time; + + if(self.owner.flagcarried) + setorigin(self.owner.flagcarried, '-20 0 96'); + + CSQCVehicleSetup(self.owner, 0); +} +METHOD(Raptor, vr_death, void(Raptor thisveh, entity instance)) +{ + instance.health = 0; + instance.event_damage = func_null; + instance.solid = SOLID_CORPSE; + instance.takedamage = DAMAGE_NO; + instance.deadflag = DEAD_DYING; + instance.movetype = MOVETYPE_BOUNCE; + instance.think = raptor_diethink; + instance.nextthink = time; + instance.wait = time + 5 + (random() * 5); - self.PlayerPhysplug = raptor_frame; + Send_Effect(EFFECT_EXPLOSION_MEDIUM, findbetterlocation (instance.origin, 16), '0 0 0', 1); - self.bomb1.gun1.avelocity_y = 90; - self.bomb1.gun2.avelocity_y = -90; + instance.velocity_z += 600; - self.delay = time; + instance.avelocity = '0 0.5 1' * (random() * 400); + instance.avelocity -= '0 0.5 1' * (random() * 400); - self.bouncefactor = autocvar_g_vehicle_raptor_bouncefactor; - self.bouncestop = autocvar_g_vehicle_raptor_bouncestop; - self.damageforcescale = 0.25; - self.vehicle_health = autocvar_g_vehicle_raptor_health; - self.vehicle_shield = autocvar_g_vehicle_raptor_shield; - } - METHOD(Raptor, vr_setup, void(Raptor thisveh, entity instance)) - { - if(autocvar_g_vehicle_raptor_shield) - self.vehicle_flags |= VHF_HASSHIELD; + instance.colormod = '-0.5 -0.5 -0.5'; + instance.touch = raptor_blowup; +} +METHOD(Raptor, vr_spawn, void(Raptor thisveh, entity instance)) +{ + if(!self.gun1) + { + entity spinner; + vector ofs; + + //FIXME: Camera is in a bad place in HUD model. + //setorigin(self.vehicle_viewport, '25 0 5'); + + self.vehicles_impulse = raptor_impulse; + + self.frame = 0; + + self.bomb1 = new(raptor_bomb); + self.bomb2 = new(raptor_bomb); + self.gun1 = new(raptor_gun); + self.gun2 = new(raptor_gun); + + setmodel(self.bomb1, MDL_VEH_RAPTOR_CB_FOLDED); + setmodel(self.bomb2, MDL_VEH_RAPTOR_CB_FOLDED); + setmodel(self.gun1, MDL_VEH_RAPTOR_GUN); + setmodel(self.gun2, MDL_VEH_RAPTOR_GUN); + setmodel(self.tur_head, MDL_VEH_RAPTOR_TAIL); + + setattachment(self.bomb1, self, "bombmount_left"); + setattachment(self.bomb2, self, "bombmount_right"); + setattachment(self.tur_head, self,"root"); + + // FIXMODEL Guns mounts to angled bones + self.bomb1.angles = self.angles; + self.angles = '0 0 0'; + // This messes up gun-aim, so work arround it. + //setattachment(self.gun1, self, "gunmount_left"); + ofs = gettaginfo(self, gettagindex(self, "gunmount_left")); + ofs -= self.origin; + setattachment(self.gun1, self, ""); + setorigin(self.gun1, ofs); + + //setattachment(self.gun2, self, "gunmount_right"); + ofs = gettaginfo(self, gettagindex(self, "gunmount_right")); + ofs -= self.origin; + setattachment(self.gun2, self, ""); + setorigin(self.gun2, ofs); + + self.angles = self.bomb1.angles; + self.bomb1.angles = '0 0 0'; + + spinner = new(raptor_spinner); + spinner.owner = self; + setmodel(spinner, MDL_VEH_RAPTOR_PROP); + setattachment(spinner, self, "engine_left"); + spinner.movetype = MOVETYPE_NOCLIP; + spinner.avelocity = '0 90 0'; + self.bomb1.gun1 = spinner; + + spinner = new(raptor_spinner); + spinner.owner = self; + setmodel(spinner, MDL_VEH_RAPTOR_PROP); + setattachment(spinner, self, "engine_right"); + spinner.movetype = MOVETYPE_NOCLIP; + spinner.avelocity = '0 -90 0'; + self.bomb1.gun2 = spinner; + + // Sigh. + self.bomb1.think = raptor_rotor_anglefix; + self.bomb1.nextthink = time; + + self.mass = 1 ; + } + + self.frame = 0; + self.vehicle_health = autocvar_g_vehicle_raptor_health; + self.vehicle_shield = autocvar_g_vehicle_raptor_shield; + self.movetype = MOVETYPE_TOSS; + self.solid = SOLID_SLIDEBOX; + self.vehicle_energy = 1; + + self.PlayerPhysplug = raptor_frame; + + self.bomb1.gun1.avelocity_y = 90; + self.bomb1.gun2.avelocity_y = -90; + + self.delay = time; + + self.bouncefactor = autocvar_g_vehicle_raptor_bouncefactor; + self.bouncestop = autocvar_g_vehicle_raptor_bouncestop; + self.damageforcescale = 0.25; + self.vehicle_health = autocvar_g_vehicle_raptor_health; + self.vehicle_shield = autocvar_g_vehicle_raptor_shield; +} +METHOD(Raptor, vr_setup, void(Raptor thisveh, entity instance)) +{ + if(autocvar_g_vehicle_raptor_shield) + self.vehicle_flags |= VHF_HASSHIELD; - if(autocvar_g_vehicle_raptor_shield_regen) - self.vehicle_flags |= VHF_SHIELDREGEN; + if(autocvar_g_vehicle_raptor_shield_regen) + self.vehicle_flags |= VHF_SHIELDREGEN; - if(autocvar_g_vehicle_raptor_health_regen) - self.vehicle_flags |= VHF_HEALTHREGEN; + if(autocvar_g_vehicle_raptor_health_regen) + self.vehicle_flags |= VHF_HEALTHREGEN; - if(autocvar_g_vehicle_raptor_energy_regen) - self.vehicle_flags |= VHF_ENERGYREGEN; + if(autocvar_g_vehicle_raptor_energy_regen) + self.vehicle_flags |= VHF_ENERGYREGEN; - self.vehicle_exit = raptor_exit; - self.respawntime = autocvar_g_vehicle_raptor_respawntime; - self.vehicle_health = autocvar_g_vehicle_raptor_health; - self.vehicle_shield = autocvar_g_vehicle_raptor_shield; - self.max_health = self.vehicle_health; - } + self.vehicle_exit = raptor_exit; + self.respawntime = autocvar_g_vehicle_raptor_respawntime; + self.vehicle_health = autocvar_g_vehicle_raptor_health; + self.vehicle_shield = autocvar_g_vehicle_raptor_shield; + self.max_health = self.vehicle_health; +} #endif #ifdef CSQC - METHOD(Raptor, vr_hud, void(Raptor thisveh)) - { - Vehicles_drawHUD(VEH_RAPTOR.m_icon, "vehicle_raptor_weapon1", "vehicle_raptor_weapon2", - "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, - "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color); - } - METHOD(Raptor, vr_crosshair, void(Raptor thisveh)) - { - string crosshair; - - switch(weapon2mode) - { - case RSM_FLARE: crosshair = vCROSS_RAIN; break; - case RSM_BOMB: crosshair = vCROSS_BURST; break; - default: crosshair = vCROSS_BURST; - } - - vector tmpSize = '0 0 0'; - if(weapon2mode != RSM_FLARE) - { - vector where; - - if(!dropmark) - { - dropmark = spawn(); - dropmark.owner = self; - dropmark.gravity = 1; - } - - float reload2 = STAT(VEHICLESTAT_RELOAD2) * 0.01; - if(reload2 == 1) - { - setorigin(dropmark, pmove_org); - dropmark.velocity = pmove_vel; - tracetoss(dropmark, self); - - where = project_3d_to_2d(trace_endpos); - - setorigin(dropmark, trace_endpos); - tmpSize = draw_getimagesize(vCROSS_DROP) * autocvar_cl_vehicles_crosshair_size; - - if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight)) - { - where.x -= tmpSize.x * 0.5; - where.y -= tmpSize.y * 0.5; - where.z = 0; - drawpic(where, vCROSS_DROP, tmpSize, '0 1 0', autocvar_crosshair_alpha * 0.9, DRAWFLAG_ADDITIVE); - drawpic(where, vCROSS_DROP, tmpSize, '0 1 0', autocvar_crosshair_alpha * 0.6, DRAWFLAG_NORMAL); // Ensure visibility against bright bg - } - dropmark.cnt = time + 5; - } - else - { - if(dropmark.cnt > time) - { - where = project_3d_to_2d(dropmark.origin); - tmpSize = draw_getimagesize(vCROSS_DROP) * autocvar_cl_vehicles_crosshair_size * 1.25; - - if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight)) - { - where.x -= tmpSize.x * 0.5; - where.y -= tmpSize.y * 0.5; - where.z = 0; - drawpic(where, vCROSS_DROP, tmpSize, '1 0 0', autocvar_crosshair_alpha * 0.9, DRAWFLAG_ADDITIVE); - drawpic(where, vCROSS_DROP, tmpSize, '1 0 0', autocvar_crosshair_alpha * 0.6, DRAWFLAG_NORMAL); // Ensure visibility against bright bg - } - } - } - } - - Vehicles_drawCrosshair(crosshair); - } - METHOD(Raptor, vr_setup, void(Raptor thisveh, entity instance)) - { - AuxiliaryXhair[1].axh_image = vCROSS_LOCK; - } +METHOD(Raptor, vr_hud, void(Raptor thisveh)) +{ + Vehicles_drawHUD(VEH_RAPTOR.m_icon, "vehicle_raptor_weapon1", "vehicle_raptor_weapon2", + "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, + "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color); +} +METHOD(Raptor, vr_crosshair, void(Raptor thisveh)) +{ + string crosshair; + + switch(weapon2mode) + { + case RSM_FLARE: crosshair = vCROSS_RAIN; break; + case RSM_BOMB: crosshair = vCROSS_BURST; break; + default: crosshair = vCROSS_BURST; + } + + vector tmpSize = '0 0 0'; + if(weapon2mode != RSM_FLARE) + { + vector where; + + if(!dropmark) + { + dropmark = spawn(); + dropmark.owner = self; + dropmark.gravity = 1; + } + + float reload2 = STAT(VEHICLESTAT_RELOAD2) * 0.01; + if(reload2 == 1) + { + setorigin(dropmark, pmove_org); + dropmark.velocity = pmove_vel; + tracetoss(dropmark, self); + + where = project_3d_to_2d(trace_endpos); + + setorigin(dropmark, trace_endpos); + tmpSize = draw_getimagesize(vCROSS_DROP) * autocvar_cl_vehicles_crosshair_size; + + if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight)) + { + where.x -= tmpSize.x * 0.5; + where.y -= tmpSize.y * 0.5; + where.z = 0; + drawpic(where, vCROSS_DROP, tmpSize, '0 1 0', autocvar_crosshair_alpha * 0.9, DRAWFLAG_ADDITIVE); + drawpic(where, vCROSS_DROP, tmpSize, '0 1 0', autocvar_crosshair_alpha * 0.6, DRAWFLAG_NORMAL); // Ensure visibility against bright bg + } + dropmark.cnt = time + 5; + } + else + { + if(dropmark.cnt > time) + { + where = project_3d_to_2d(dropmark.origin); + tmpSize = draw_getimagesize(vCROSS_DROP) * autocvar_cl_vehicles_crosshair_size * 1.25; + + if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight)) + { + where.x -= tmpSize.x * 0.5; + where.y -= tmpSize.y * 0.5; + where.z = 0; + drawpic(where, vCROSS_DROP, tmpSize, '1 0 0', autocvar_crosshair_alpha * 0.9, DRAWFLAG_ADDITIVE); + drawpic(where, vCROSS_DROP, tmpSize, '1 0 0', autocvar_crosshair_alpha * 0.6, DRAWFLAG_NORMAL); // Ensure visibility against bright bg + } + } + } + } + + Vehicles_drawCrosshair(crosshair); +} +METHOD(Raptor, vr_setup, void(Raptor thisveh, entity instance)) +{ + AuxiliaryXhair[1].axh_image = vCROSS_LOCK; +} #endif #endif diff --git a/qcsrc/common/vehicles/vehicle/spiderbot.qc b/qcsrc/common/vehicles/vehicle/spiderbot.qc index 5bb26070d..589f6ff9e 100644 --- a/qcsrc/common/vehicles/vehicle/spiderbot.qc +++ b/qcsrc/common/vehicles/vehicle/spiderbot.qc @@ -89,8 +89,8 @@ float spiderbot_frame() setself(spider); - player.BUTTON_ZOOM = 0; - player.BUTTON_CROUCH = 0; + PHYS_INPUT_BUTTON_ZOOM(player) = false; + PHYS_INPUT_BUTTON_CROUCH(player) = false; PS(player).m_switchweapon = WEP_Null; player.vehicle_weapon2mode = spider.vehicle_weapon2mode; @@ -149,10 +149,10 @@ float spiderbot_frame() spider.frame = 5; } - if(!player.BUTTON_JUMP) - spider.BUTTON_JUMP = 0; + if (!PHYS_INPUT_BUTTON_JUMP(player)) + PHYS_INPUT_BUTTON_JUMP(spider) = false; - if((IS_ONGROUND(spider)) && player.BUTTON_JUMP && !spider.BUTTON_JUMP && self.tur_head.wait < time) + if((IS_ONGROUND(spider)) && PHYS_INPUT_BUTTON_JUMP(player) && !PHYS_INPUT_BUTTON_JUMP(spider) && self.tur_head.wait < time) { sound (self, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_JUMP, VOL_VEHICLEENGINE, ATTEN_NORM); //dprint("spiderbot_jump:", ftos(soundlength("vehicles/spiderbot_jump.wav")), "\n"); @@ -160,8 +160,8 @@ float spiderbot_frame() self.tur_head.wait = time + 2; spider.jump_delay = time + 2; - spider.BUTTON_JUMP = 1; // set spider's jump - //player.BUTTON_JUMP = 0; + PHYS_INPUT_BUTTON_JUMP(spider) = true; // set spider's jump + //PHYS_INPUT_BUTTON_JUMP(player) = false; vector movefix = '0 0 0'; if(player.movement_x > 0) movefix_x = 1; @@ -224,7 +224,7 @@ float spiderbot_frame() } player.movement_y = 0; float oldvelz = spider.velocity_z; - movelib_move_simple(self, normalize(v_forward * player.movement_x),((player.BUTTON_JUMP) ? autocvar_g_vehicle_spiderbot_speed_run : autocvar_g_vehicle_spiderbot_speed_walk),autocvar_g_vehicle_spiderbot_movement_inertia); + movelib_move_simple(self, normalize(v_forward * player.movement_x),((PHYS_INPUT_BUTTON_JUMP(player)) ? autocvar_g_vehicle_spiderbot_speed_run : autocvar_g_vehicle_spiderbot_speed_walk),autocvar_g_vehicle_spiderbot_movement_inertia); spider.velocity_z = oldvelz; float g = ((autocvar_sv_gameplayfix_gravityunaffectedbyticrate) ? 0.5 : 1); if(spider.velocity_z <= 20) // not while jumping @@ -276,7 +276,7 @@ float spiderbot_frame() self.angles_z = bound(-autocvar_g_vehicle_spiderbot_tiltlimit, self.angles_z, autocvar_g_vehicle_spiderbot_tiltlimit); if(!forbidWeaponUse(player)) - if(player.BUTTON_ATCK) + if(PHYS_INPUT_BUTTON_ATCK(player)) { spider.cnt = time; if(spider.vehicle_ammo1 >= autocvar_g_vehicle_spiderbot_minigun_ammo_cost && spider.tur_head.attack_finished_single[0] <= time) @@ -328,7 +328,7 @@ float spiderbot_frame() if(self.vehicle_flags & VHF_HEALTHREGEN) vehicles_regen(spider.dmg_time, vehicle_health, autocvar_g_vehicle_spiderbot_health, autocvar_g_vehicle_spiderbot_health_regen_pause, autocvar_g_vehicle_spiderbot_health_regen, frametime, false); - player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; + PHYS_INPUT_BUTTON_ATCK(player) = PHYS_INPUT_BUTTON_ATCK2(player) = false; //player.vehicle_ammo2 = spider.tur_head.frame; player.vehicle_ammo2 = (9 - spider.tur_head.frame) / 8 * 100; // Percentage, like ammo1 @@ -554,127 +554,127 @@ spawnfunc(vehicle_spiderbot) if(!vehicle_initialize(VEH_SPIDERBOT, false)) { remove(self); return; } } - METHOD(Spiderbot, vr_impact, void(Spiderbot thisveh, entity instance)) - { - if(autocvar_g_vehicle_spiderbot_bouncepain) - vehicles_impact(autocvar_g_vehicle_spiderbot_bouncepain_x, autocvar_g_vehicle_spiderbot_bouncepain_y, autocvar_g_vehicle_spiderbot_bouncepain_z); - } - METHOD(Spiderbot, vr_enter, void(Spiderbot thisveh, entity instance)) - { - self.vehicle_weapon2mode = SBRM_GUIDE; - self.movetype = MOVETYPE_WALK; - CSQCVehicleSetup(self.owner, 0); - self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_spiderbot_health) * 100; - self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_spiderbot_shield) * 100; - - if(self.owner.flagcarried) - { - setattachment(self.owner.flagcarried, self.tur_head, ""); - setorigin(self.owner.flagcarried, '-20 0 120'); - } - } - METHOD(Spiderbot, vr_think, void(Spiderbot thisveh, entity instance)) - { - if(IS_ONGROUND(self)) - movelib_brake_simple(self, autocvar_g_vehicle_spiderbot_speed_stop); - } - METHOD(Spiderbot, vr_death, void(Spiderbot thisveh, entity instance)) - { - instance.health = 0; - instance.event_damage = func_null; - instance.takedamage = DAMAGE_NO; - instance.touch = func_null; - instance.cnt = 3.4 + time + random() * 2; - instance.think = spiderbot_blowup; - instance.nextthink = time; - instance.deadflag = DEAD_DYING; - instance.frame = 5; - instance.tur_head.effects |= EF_FLAME; - instance.colormod = instance.tur_head.colormod = '-1 -1 -1'; - instance.frame = 10; - instance.movetype = MOVETYPE_TOSS; - - CSQCModel_UnlinkEntity(instance); // networking the death scene would be a nightmare - } - METHOD(Spiderbot, vr_spawn, void(Spiderbot thisveh, entity instance)) - { - if(!self.gun1) - { - self.vehicles_impulse = spiderbot_impulse; - self.gun1 = spawn(); - self.gun2 = spawn(); - setmodel(self.gun1, MDL_VEH_SPIDERBOT_GUN); - setmodel(self.gun2, MDL_VEH_SPIDERBOT_GUN); - setattachment(self.gun1, self.tur_head, "tag_hardpoint01"); - setattachment(self.gun2, self.tur_head, "tag_hardpoint02"); - self.gravity = 2; - self.mass = 5000; - } - - self.frame = 5; - self.tur_head.frame = 1; - self.movetype = MOVETYPE_WALK; - self.solid = SOLID_SLIDEBOX; - self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = 1; - self.tur_head.angles = '0 0 0'; - self.vehicle_exit = spiderbot_exit; - - setorigin(self, self.pos1 + '0 0 128'); - self.angles = self.pos2; - self.damageforcescale = 0.03; - self.vehicle_health = autocvar_g_vehicle_spiderbot_health; - self.vehicle_shield = autocvar_g_vehicle_spiderbot_shield; - - self.PlayerPhysplug = spiderbot_frame; - } - METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance)) - { - if(autocvar_g_vehicle_spiderbot_shield) - self.vehicle_flags |= VHF_HASSHIELD; +METHOD(Spiderbot, vr_impact, void(Spiderbot thisveh, entity instance)) +{ + if(autocvar_g_vehicle_spiderbot_bouncepain) + vehicles_impact(autocvar_g_vehicle_spiderbot_bouncepain_x, autocvar_g_vehicle_spiderbot_bouncepain_y, autocvar_g_vehicle_spiderbot_bouncepain_z); +} +METHOD(Spiderbot, vr_enter, void(Spiderbot thisveh, entity instance)) +{ + self.vehicle_weapon2mode = SBRM_GUIDE; + self.movetype = MOVETYPE_WALK; + CSQCVehicleSetup(self.owner, 0); + self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_spiderbot_health) * 100; + self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_spiderbot_shield) * 100; + + if(self.owner.flagcarried) + { + setattachment(self.owner.flagcarried, self.tur_head, ""); + setorigin(self.owner.flagcarried, '-20 0 120'); + } +} +METHOD(Spiderbot, vr_think, void(Spiderbot thisveh, entity instance)) +{ + if(IS_ONGROUND(self)) + movelib_brake_simple(self, autocvar_g_vehicle_spiderbot_speed_stop); +} +METHOD(Spiderbot, vr_death, void(Spiderbot thisveh, entity instance)) +{ + instance.health = 0; + instance.event_damage = func_null; + instance.takedamage = DAMAGE_NO; + instance.touch = func_null; + instance.cnt = 3.4 + time + random() * 2; + instance.think = spiderbot_blowup; + instance.nextthink = time; + instance.deadflag = DEAD_DYING; + instance.frame = 5; + instance.tur_head.effects |= EF_FLAME; + instance.colormod = instance.tur_head.colormod = '-1 -1 -1'; + instance.frame = 10; + instance.movetype = MOVETYPE_TOSS; + + CSQCModel_UnlinkEntity(instance); // networking the death scene would be a nightmare +} +METHOD(Spiderbot, vr_spawn, void(Spiderbot thisveh, entity instance)) +{ + if(!self.gun1) + { + self.vehicles_impulse = spiderbot_impulse; + self.gun1 = spawn(); + self.gun2 = spawn(); + setmodel(self.gun1, MDL_VEH_SPIDERBOT_GUN); + setmodel(self.gun2, MDL_VEH_SPIDERBOT_GUN); + setattachment(self.gun1, self.tur_head, "tag_hardpoint01"); + setattachment(self.gun2, self.tur_head, "tag_hardpoint02"); + self.gravity = 2; + self.mass = 5000; + } + + self.frame = 5; + self.tur_head.frame = 1; + self.movetype = MOVETYPE_WALK; + self.solid = SOLID_SLIDEBOX; + self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = 1; + self.tur_head.angles = '0 0 0'; + self.vehicle_exit = spiderbot_exit; + + setorigin(self, self.pos1 + '0 0 128'); + self.angles = self.pos2; + self.damageforcescale = 0.03; + self.vehicle_health = autocvar_g_vehicle_spiderbot_health; + self.vehicle_shield = autocvar_g_vehicle_spiderbot_shield; + + self.PlayerPhysplug = spiderbot_frame; +} +METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance)) +{ + if(autocvar_g_vehicle_spiderbot_shield) + self.vehicle_flags |= VHF_HASSHIELD; - if(autocvar_g_vehicle_spiderbot_shield_regen) - self.vehicle_flags |= VHF_SHIELDREGEN; + if(autocvar_g_vehicle_spiderbot_shield_regen) + self.vehicle_flags |= VHF_SHIELDREGEN; - if(autocvar_g_vehicle_spiderbot_health_regen) - self.vehicle_flags |= VHF_HEALTHREGEN; + if(autocvar_g_vehicle_spiderbot_health_regen) + self.vehicle_flags |= VHF_HEALTHREGEN; - self.respawntime = autocvar_g_vehicle_spiderbot_respawntime; - self.vehicle_health = autocvar_g_vehicle_spiderbot_health; - self.vehicle_shield = autocvar_g_vehicle_spiderbot_shield; - self.max_health = self.vehicle_health; - self.pushable = true; // spiderbot can use jumppads - } + self.respawntime = autocvar_g_vehicle_spiderbot_respawntime; + self.vehicle_health = autocvar_g_vehicle_spiderbot_health; + self.vehicle_shield = autocvar_g_vehicle_spiderbot_shield; + self.max_health = self.vehicle_health; + self.pushable = true; // spiderbot can use jumppads +} #endif // SVQC #ifdef CSQC float autocvar_cl_vehicle_spiderbot_cross_alpha = 0.6; float autocvar_cl_vehicle_spiderbot_cross_size = 1; - METHOD(Spiderbot, vr_hud, void(Spiderbot thisveh)) - { - Vehicles_drawHUD(VEH_SPIDERBOT.m_icon, "vehicle_spider_weapon1", "vehicle_spider_weapon2", - "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, - "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color); - } - METHOD(Spiderbot, vr_crosshair, void(Spiderbot thisveh)) - { - string crosshair; +METHOD(Spiderbot, vr_hud, void(Spiderbot thisveh)) +{ + Vehicles_drawHUD(VEH_SPIDERBOT.m_icon, "vehicle_spider_weapon1", "vehicle_spider_weapon2", + "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color, + "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color); +} +METHOD(Spiderbot, vr_crosshair, void(Spiderbot thisveh)) +{ + string crosshair; - switch(weapon2mode) - { - case SBRM_VOLLY: crosshair = vCROSS_BURST; break; - case SBRM_GUIDE: crosshair = vCROSS_GUIDE; break; - case SBRM_ARTILLERY: crosshair = vCROSS_RAIN; break; - default: crosshair = vCROSS_BURST; - } + switch(weapon2mode) + { + case SBRM_VOLLY: crosshair = vCROSS_BURST; break; + case SBRM_GUIDE: crosshair = vCROSS_GUIDE; break; + case SBRM_ARTILLERY: crosshair = vCROSS_RAIN; break; + default: crosshair = vCROSS_BURST; + } - Vehicles_drawCrosshair(crosshair); - } - METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance)) - { - AuxiliaryXhair[0].axh_image = vCROSS_HINT; // Minigun1 - AuxiliaryXhair[1].axh_image = vCROSS_HINT; // Minigun2 - } + Vehicles_drawCrosshair(crosshair); +} +METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance)) +{ + AuxiliaryXhair[0].axh_image = vCROSS_HINT; // Minigun1 + AuxiliaryXhair[1].axh_image = vCROSS_HINT; // Minigun2 +} #endif #endif diff --git a/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc b/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc index 257eac801..9dfc72c13 100644 --- a/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc +++ b/qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc @@ -174,7 +174,7 @@ void spiderbot_rocket_do() if (self.wait != -10) { - if (self.owner.BUTTON_ATCK2 && self.vehicle_weapon2mode == SBRM_GUIDE) + if (PHYS_INPUT_BUTTON_ATCK2(self.owner) && self.vehicle_weapon2mode == SBRM_GUIDE) { if (self.wait == 1) if (self.tur_head.frame == 9 || self.tur_head.frame == 1) @@ -205,7 +205,7 @@ void spiderbot_rocket_do() } if(self.wait != -10) - if(!self.owner.BUTTON_ATCK2) + if(!PHYS_INPUT_BUTTON_ATCK2(self.owner)) return; if(forbidWeaponUse(self.owner)) @@ -226,7 +226,7 @@ void spiderbot_rocket_do() rocket.nextthink = time + (_dist / autocvar_g_vehicle_spiderbot_rocket_speed); rocket.think = vehicles_projectile_explode; - if(self.owner.BUTTON_ATCK2 && self.tur_head.frame == 1) + if(PHYS_INPUT_BUTTON_ATCK2(self.owner) && self.tur_head.frame == 1) self.wait = -10; break; case SBRM_GUIDE: diff --git a/qcsrc/common/viewloc.qc b/qcsrc/common/viewloc.qc index f67bbc887..fb510f856 100644 --- a/qcsrc/common/viewloc.qc +++ b/qcsrc/common/viewloc.qc @@ -45,9 +45,9 @@ void viewloc_PlayerPhysics(entity this) //if(!PHYS_INPUT_BUTTON_CROUCH(this) && !IS_DUCKED(this)) #ifdef SVQC - //this.BUTTON_CROUCH = (old_movement_x < 0); + //PHYS_INPUT_BUTTON_CROUCH(this) = (old_movement_x < 0); if (old_movement.x < 0) - this.BUTTON_CROUCH = true; + PHYS_INPUT_BUTTON_CROUCH(this) = true; #elif defined(CSQC) if (old_movement.x < 0) { diff --git a/qcsrc/common/weapons/all.qc b/qcsrc/common/weapons/all.qc index d531b8c3f..b126005eb 100644 --- a/qcsrc/common/weapons/all.qc +++ b/qcsrc/common/weapons/all.qc @@ -35,7 +35,7 @@ #include #include #include - #include "../notifications.qh" + #include "../notifications/all.qh" #include "../deathtypes/all.qh" #include #include "../mapinfo.qh" @@ -134,7 +134,7 @@ string W_NumberWeaponOrder_MapFunc(string s) { if (s == "0" || stof(s)) return s; s = W_UndeprecateName(s); - FOREACH(Weapons, it != WEP_Null && it.netname == s, LAMBDA(return ftos(i))); + FOREACH(Weapons, it != WEP_Null && it.netname == s, return ftos(i)); return s; } string W_NumberWeaponOrder(string order) @@ -202,10 +202,10 @@ void W_RandomWeapons(entity e, float n) for (i = 0; i < n; ++i) { RandomSelection_Init(); - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { if (remaining & (it.m_wepset)) RandomSelection_Add(it, 0, string_null, 1, 1); - )); + }); Weapon w = RandomSelection_chosen_ent; result |= WepSet_FromWeapon(w); remaining &= ~WepSet_FromWeapon(w); @@ -425,13 +425,13 @@ void CL_WeaponEntity_SetModel(entity this, string name) if (!this.weaponchild) { this.weaponchild = new(weaponchild); - make_pure(this.weaponchild); #ifdef CSQC this.weaponchild.drawmask = MASK_NORMAL; this.weaponchild.renderflags |= RF_VIEWMODEL; #endif } _setmodel(this.weaponchild, W_Model(strcat("v_", name, ".md3"))); + setsize(this.weaponchild, '0 0 0', '0 0 0'); setattachment(this.weaponchild, this, t); } else @@ -440,6 +440,7 @@ void CL_WeaponEntity_SetModel(entity this, string name) this.weaponchild = NULL; } + setsize(this, '0 0 0', '0 0 0'); setorigin(this, '0 0 0'); this.angles = '0 0 0'; this.frame = 0; diff --git a/qcsrc/common/weapons/all.qh b/qcsrc/common/weapons/all.qh index 6429ff899..5e87a3c3a 100644 --- a/qcsrc/common/weapons/all.qh +++ b/qcsrc/common/weapons/all.qh @@ -33,7 +33,7 @@ WepSet ReadWepSet(); REGISTRY(Weapons, 72) // Increase as needed. Can be up to 72. #define Weapons_from(i) _Weapons_from(i, WEP_Null) REGISTER_REGISTRY(Weapons) -STATIC_INIT(WeaponPickup) { FOREACH(Weapons, true, LAMBDA(it.m_pickup = NEW(WeaponPickup, it))); } +STATIC_INIT(WeaponPickup) { FOREACH(Weapons, true, it.m_pickup = NEW(WeaponPickup, it)); } .WepSet m_wepset; #define WEPSET(id) (WEP_##id.m_wepset) @@ -95,7 +95,7 @@ GENERIC_COMMAND(dumpweapons, "Dump all weapons into weapons_dump.txt") // WEAPON #ifdef SVQC entity W_PROP_reloader; -float autocvar_w_prop_interval = 0; +float autocvar_w_prop_interval = 5; .void(Weapon this, int) wr_net; void W_PROP_reload(int chan, entity to) { @@ -113,8 +113,7 @@ void W_PROP_think() } STATIC_INIT_LATE(W_PROP_reloader) { - entity e = W_PROP_reloader = new(W_PROP_reloader); - make_pure(e); + entity e = W_PROP_reloader = new_pure(W_PROP_reloader); WITH(entity, self, e, (e.think = W_PROP_think)()); } #endif @@ -299,7 +298,7 @@ REGISTRY_CHECK(Weapons) STATIC_INIT(register_weapons_done) { - FOREACH(Weapons, true, LAMBDA( + FOREACH(Weapons, true, { WepSet set = it.m_wepset = _WepSet_FromWeapon(it.m_id = i); WEPSET_ALL |= set; if ((it.spawnflags) & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= set; @@ -310,9 +309,9 @@ STATIC_INIT(register_weapons_done) localcmd(sprintf("alias weapon_%s \"impulse %d\"\n", it.netname, imp)); else LOG_TRACEF("Impulse limit exceeded, weapon will not be directly accessible: %s\n", it.netname); - )); + }); #ifdef CSQC - FOREACH(Weapons, true, LAMBDA(it.wr_init(it))); + FOREACH(Weapons, true, it.wr_init(it)); #endif weaponorder_byid = ""; for (int i = Weapons_MAX - 1; i >= 1; --i) diff --git a/qcsrc/common/weapons/config.qc b/qcsrc/common/weapons/config.qc index ad90baa6f..34031a208 100644 --- a/qcsrc/common/weapons/config.qc +++ b/qcsrc/common/weapons/config.qc @@ -25,7 +25,7 @@ float W_Config_Queue_Compare(int root, int child, entity pass) void Dump_Weapon_Settings() { int totalweapons = 0, totalsettings = 0; - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { // step 1: clear the queue WEP_CONFIG_COUNT = 0; for (int x = 0; x <= MAX_WEP_CONFIG; ++x) @@ -51,7 +51,7 @@ void Dump_Weapon_Settings() LOG_INFO(sprintf("#%d: %s: %d settings...\n", i, it.m_name, WEP_CONFIG_COUNT)); totalweapons += 1; totalsettings += WEP_CONFIG_COUNT; - )); + }); // clear queue now that we're finished WEP_CONFIG_COUNT = 0; diff --git a/qcsrc/common/weapons/weapon.qh b/qcsrc/common/weapons/weapon.qh index b529d109d..4a12dee27 100644 --- a/qcsrc/common/weapons/weapon.qh +++ b/qcsrc/common/weapons/weapon.qh @@ -93,9 +93,9 @@ CLASS(Weapon, Object) /** (BOTH) precaches models/sounds used by this weapon, also sets up weapon properties */ METHOD(Weapon, wr_init, void(Weapon this)) {} /** (SERVER) notification number for suicide message (may inspect w_deathtype for details) */ - METHOD(Weapon, wr_suicidemessage, int(Weapon this)) {return 0;} + METHOD(Weapon, wr_suicidemessage, entity(Weapon this)) {return NULL;} /** (SERVER) notification number for kill message (may inspect w_deathtype for details) */ - METHOD(Weapon, wr_killmessage, int(Weapon this)) {return 0;} + METHOD(Weapon, wr_killmessage, entity(Weapon this)) {return NULL;} /** (SERVER) handles reloading for weapon */ METHOD(Weapon, wr_reload, void(Weapon this, entity actor, .entity weaponentity)) {} /** (SERVER) clears fields that the weapon may use */ diff --git a/qcsrc/common/weapons/weapon/arc.qc b/qcsrc/common/weapons/weapon/arc.qc index 1d3ea78a5..6ac3e9274 100644 --- a/qcsrc/common/weapons/weapon/arc.qc +++ b/qcsrc/common/weapons/weapon/arc.qc @@ -312,7 +312,7 @@ void W_Arc_Beam_Think() float burst = 0; - if( (self.owner.BUTTON_ATCK2 && !WEP_CVAR(arc, bolt)) || self.beam_bursting) + if( (PHYS_INPUT_BUTTON_ATCK2(self.owner) && !WEP_CVAR(arc, bolt)) || self.beam_bursting) { if(!self.beam_bursting) self.beam_bursting = true; @@ -330,7 +330,7 @@ void W_Arc_Beam_Think() || gameover || - (!self.owner.BUTTON_ATCK && !burst ) + (!PHYS_INPUT_BUTTON_ATCK(self.owner) && !burst ) || STAT(FROZEN, self.owner) || @@ -700,7 +700,7 @@ void Arc_Smoke() { if ( random() < self.arc_heat_percent ) Send_Effect(EFFECT_ARC_SMOKE, smoke_origin, '0 0 0', 1 ); - if ( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) + if ( PHYS_INPUT_BUTTON_ATCK(self) || PHYS_INPUT_BUTTON_ATCK2(self) ) { Send_Effect(EFFECT_ARC_OVERHEAT_FIRE, smoke_origin, w_shotdir, 1 ); if ( !self.arc_smoke_sound ) @@ -719,166 +719,166 @@ void Arc_Smoke() } if ( self.arc_smoke_sound && ( self.arc_overheat <= time || - !( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) ) || PS(self).m_switchweapon != WEP_ARC ) + !( PHYS_INPUT_BUTTON_ATCK(self) || PHYS_INPUT_BUTTON_ATCK2(self) ) ) || PS(self).m_switchweapon != WEP_ARC ) { self.arc_smoke_sound = 0; sound(self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM); } } - METHOD(Arc, wr_aim, void(entity thiswep)) - { - SELFPARAM(); - if(WEP_CVAR(arc, beam_botaimspeed)) - { - self.BUTTON_ATCK = bot_aim( - WEP_CVAR(arc, beam_botaimspeed), - 0, - WEP_CVAR(arc, beam_botaimlifetime), - false - ); - } - else - { - self.BUTTON_ATCK = bot_aim( - 1000000, - 0, - 0.001, - false - ); - } - } - METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - Arc_Player_SetHeat(actor); - Arc_Smoke(); - - bool beam_fire2 = ((fire & 2) && !WEP_CVAR(arc, bolt)); - - if (time >= actor.arc_overheat) - if ((fire & 1) || beam_fire2 || actor.arc_beam.beam_bursting) - { - - if(actor.arc_BUTTON_ATCK_prev) - { - #if 0 - if(actor.animstate_startframe == actor.anim_shoot.x && actor.animstate_numframes == actor.anim_shoot.y) - weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready); - else - #endif - weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(arc, beam_animtime), w_ready); - } - - if((!actor.arc_beam) || wasfreed(actor.arc_beam)) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, boolean(beam_fire2), 0)) - { - W_Arc_Beam(boolean(beam_fire2)); - - if(!actor.arc_BUTTON_ATCK_prev) - { - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); - actor.arc_BUTTON_ATCK_prev = true; - } - } - } - - return; - } - else if(fire & 2) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(arc, bolt_refire))) - { - W_Arc_Attack_Bolt(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, bolt_refire), w_ready); - } - } - - if(actor.arc_BUTTON_ATCK_prev) - { - sound(actor, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); - int slot = weaponslot(weaponentity); - ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor(); - } - actor.arc_BUTTON_ATCK_prev = false; - - #if 0 - if(fire & 2) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_arc_secondary_refire)) - { - W_Arc_Attack2(); - actor.arc_count = autocvar_g_balance_arc_secondary_count; - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack); - actor.arc_secondarytime = time + autocvar_g_balance_arc_secondary_refire2 * W_WeaponRateFactor(); - } - #endif - } - METHOD(Arc, wr_init, void(entity thiswep)) - { - if(!arc_shotorigin[0]) - { - arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 1); - arc_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 2); - arc_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 3); - arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 4); - } - } - METHOD(Arc, wr_checkammo1, bool(entity thiswep)) - { - SELFPARAM(); - return ((!WEP_CVAR(arc, beam_ammo)) || (self.(thiswep.ammo_field) > 0)); - } - METHOD(Arc, wr_checkammo2, bool(entity thiswep)) - { - SELFPARAM(); - if(WEP_CVAR(arc, bolt)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(arc, bolt_ammo); - ammo_amount += self.(weapon_load[WEP_ARC.m_id]) >= WEP_CVAR(arc, bolt_ammo); - return ammo_amount; - } - else - return WEP_CVAR(arc, overheat_max) > 0 && - ((!WEP_CVAR(arc, burst_ammo)) || (self.(thiswep.ammo_field) > 0)); - } - METHOD(Arc, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_ARC_MURDER_SPRAY; - else - return WEAPON_ARC_MURDER; - } - METHOD(Arc, wr_drop, void(entity thiswep)) - { - weapon_dropevent_item.arc_overheat = self.arc_overheat; - weapon_dropevent_item.arc_cooldown = self.arc_cooldown; - self.arc_overheat = 0; - self.arc_cooldown = 0; - } - METHOD(Arc, wr_pickup, void(entity thiswep)) - { - if ( !client_hasweapon(self, thiswep, false, false) && - weapon_dropevent_item.arc_overheat > time ) - { - self.arc_overheat = weapon_dropevent_item.arc_overheat; - self.arc_cooldown = weapon_dropevent_item.arc_cooldown; - } - } +METHOD(Arc, wr_aim, void(entity thiswep)) +{ + SELFPARAM(); + if(WEP_CVAR(arc, beam_botaimspeed)) + { + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim( + WEP_CVAR(arc, beam_botaimspeed), + 0, + WEP_CVAR(arc, beam_botaimlifetime), + false + ); + } + else + { + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim( + 1000000, + 0, + 0.001, + false + ); + } +} +METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + Arc_Player_SetHeat(actor); + Arc_Smoke(); + + bool beam_fire2 = ((fire & 2) && !WEP_CVAR(arc, bolt)); + + if (time >= actor.arc_overheat) + if ((fire & 1) || beam_fire2 || actor.arc_beam.beam_bursting) + { + + if(actor.arc_BUTTON_ATCK_prev) + { + #if 0 + if(actor.animstate_startframe == actor.anim_shoot.x && actor.animstate_numframes == actor.anim_shoot.y) + weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready); + else + #endif + weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(arc, beam_animtime), w_ready); + } + + if((!actor.arc_beam) || wasfreed(actor.arc_beam)) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, boolean(beam_fire2), 0)) + { + W_Arc_Beam(boolean(beam_fire2)); + + if(!actor.arc_BUTTON_ATCK_prev) + { + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); + actor.arc_BUTTON_ATCK_prev = true; + } + } + } + + return; + } + else if(fire & 2) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(arc, bolt_refire))) + { + W_Arc_Attack_Bolt(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, bolt_refire), w_ready); + } + } + + if(actor.arc_BUTTON_ATCK_prev) + { + sound(actor, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready); + int slot = weaponslot(weaponentity); + ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor(); + } + actor.arc_BUTTON_ATCK_prev = false; + + #if 0 + if(fire & 2) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, autocvar_g_balance_arc_secondary_refire)) + { + W_Arc_Attack2(); + actor.arc_count = autocvar_g_balance_arc_secondary_count; + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, autocvar_g_balance_arc_secondary_animtime, w_arc_checkattack); + actor.arc_secondarytime = time + autocvar_g_balance_arc_secondary_refire2 * W_WeaponRateFactor(); + } + #endif +} +METHOD(Arc, wr_init, void(entity thiswep)) +{ + if(!arc_shotorigin[0]) + { + arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 1); + arc_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 2); + arc_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 3); + arc_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 4); + } +} +METHOD(Arc, wr_checkammo1, bool(entity thiswep)) +{ + SELFPARAM(); + return ((!WEP_CVAR(arc, beam_ammo)) || (self.(thiswep.ammo_field) > 0)); +} +METHOD(Arc, wr_checkammo2, bool(entity thiswep)) +{ + SELFPARAM(); + if(WEP_CVAR(arc, bolt)) + { + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(arc, bolt_ammo); + ammo_amount += self.(weapon_load[WEP_ARC.m_id]) >= WEP_CVAR(arc, bolt_ammo); + return ammo_amount; + } + else + return WEP_CVAR(arc, overheat_max) > 0 && + ((!WEP_CVAR(arc, burst_ammo)) || (self.(thiswep.ammo_field) > 0)); +} +METHOD(Arc, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_ARC_MURDER_SPRAY; + else + return WEAPON_ARC_MURDER; +} +METHOD(Arc, wr_drop, void(entity thiswep)) +{ + weapon_dropevent_item.arc_overheat = self.arc_overheat; + weapon_dropevent_item.arc_cooldown = self.arc_cooldown; + self.arc_overheat = 0; + self.arc_cooldown = 0; +} +METHOD(Arc, wr_pickup, void(entity thiswep)) +{ + if ( !client_hasweapon(self, thiswep, false, false) && + weapon_dropevent_item.arc_overheat > time ) + { + self.arc_overheat = weapon_dropevent_item.arc_overheat; + self.arc_cooldown = weapon_dropevent_item.arc_cooldown; + } +} #endif #ifdef CSQC bool autocvar_cl_arcbeam_teamcolor = true; - METHOD(Arc, wr_impacteffect, void(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - { - vector org2; - org2 = w_org + w_backoff * 6; - pointparticles(EFFECT_ARC_BOLT_EXPLODE, org2, w_backoff * 1000, 1); - if(!w_issilent) { sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); } - } - } +METHOD(Arc, wr_impacteffect, void(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + { + vector org2; + org2 = w_org + w_backoff * 6; + pointparticles(EFFECT_ARC_BOLT_EXPLODE, org2, w_backoff * 1000, 1); + if(!w_issilent) { sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); } + } +} void Draw_ArcBeam_callback(vector start, vector hit, vector end) { diff --git a/qcsrc/common/weapons/weapon/blaster.qc b/qcsrc/common/weapons/weapon/blaster.qc index 1d76279f3..362666d27 100644 --- a/qcsrc/common/weapons/weapon/blaster.qc +++ b/qcsrc/common/weapons/weapon/blaster.qc @@ -150,113 +150,113 @@ void W_Blaster_Attack( } } - METHOD(Blaster, wr_aim, void(entity thiswep)) - { - if(WEP_CVAR(blaster, secondary)) - { - if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage)) - { self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); } - else - { self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); } - } - else - { self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); } - } +METHOD(Blaster, wr_aim, void(entity thiswep)) +{ + if(WEP_CVAR(blaster, secondary)) + { + if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage)) + { PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); } + else + { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); } + } + else + { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); } +} - METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponentity, int fire)) - { - if(fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(blaster, refire))) - { - W_Blaster_Attack( - actor, - WEP_BLASTER.m_id, - WEP_CVAR_PRI(blaster, shotangle), - WEP_CVAR_PRI(blaster, damage), - WEP_CVAR_PRI(blaster, edgedamage), - WEP_CVAR_PRI(blaster, radius), - WEP_CVAR_PRI(blaster, force), - WEP_CVAR_PRI(blaster, speed), - WEP_CVAR_PRI(blaster, spread), - WEP_CVAR_PRI(blaster, delay), - WEP_CVAR_PRI(blaster, lifetime) - ); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready); - } - } - else if(fire & 2) - { - switch(WEP_CVAR(blaster, secondary)) - { - case 0: // switch to last used weapon - { - if(PS(actor).m_switchweapon == WEP_BLASTER) // don't do this if already switching - W_LastWeapon(actor); - break; - } +METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(blaster, refire))) + { + W_Blaster_Attack( + actor, + WEP_BLASTER.m_id, + WEP_CVAR_PRI(blaster, shotangle), + WEP_CVAR_PRI(blaster, damage), + WEP_CVAR_PRI(blaster, edgedamage), + WEP_CVAR_PRI(blaster, radius), + WEP_CVAR_PRI(blaster, force), + WEP_CVAR_PRI(blaster, speed), + WEP_CVAR_PRI(blaster, spread), + WEP_CVAR_PRI(blaster, delay), + WEP_CVAR_PRI(blaster, lifetime) + ); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready); + } + } + else if(fire & 2) + { + switch(WEP_CVAR(blaster, secondary)) + { + case 0: // switch to last used weapon + { + if(PS(actor).m_switchweapon == WEP_BLASTER) // don't do this if already switching + W_LastWeapon(actor); + break; + } - case 1: // normal projectile secondary - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(blaster, refire))) - { - W_Blaster_Attack( - actor, - WEP_BLASTER.m_id | HITTYPE_SECONDARY, - WEP_CVAR_SEC(blaster, shotangle), - WEP_CVAR_SEC(blaster, damage), - WEP_CVAR_SEC(blaster, edgedamage), - WEP_CVAR_SEC(blaster, radius), - WEP_CVAR_SEC(blaster, force), - WEP_CVAR_SEC(blaster, speed), - WEP_CVAR_SEC(blaster, spread), - WEP_CVAR_SEC(blaster, delay), - WEP_CVAR_SEC(blaster, lifetime) - ); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready); - } + case 1: // normal projectile secondary + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(blaster, refire))) + { + W_Blaster_Attack( + actor, + WEP_BLASTER.m_id | HITTYPE_SECONDARY, + WEP_CVAR_SEC(blaster, shotangle), + WEP_CVAR_SEC(blaster, damage), + WEP_CVAR_SEC(blaster, edgedamage), + WEP_CVAR_SEC(blaster, radius), + WEP_CVAR_SEC(blaster, force), + WEP_CVAR_SEC(blaster, speed), + WEP_CVAR_SEC(blaster, spread), + WEP_CVAR_SEC(blaster, delay), + WEP_CVAR_SEC(blaster, lifetime) + ); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready); + } - break; - } - } - } - } + break; + } + } + } +} - METHOD(Blaster, wr_setup, void(entity thiswep)) - { - self.ammo_field = ammo_none; - } +METHOD(Blaster, wr_setup, void(entity thiswep)) +{ + self.ammo_field = ammo_none; +} - METHOD(Blaster, wr_checkammo1, bool(entity thiswep)) - { - return true; // infinite ammo - } +METHOD(Blaster, wr_checkammo1, bool(entity thiswep)) +{ + return true; // infinite ammo +} - METHOD(Blaster, wr_checkammo2, bool(entity thiswep)) - { - return true; // blaster has infinite ammo - } +METHOD(Blaster, wr_checkammo2, bool(entity thiswep)) +{ + return true; // blaster has infinite ammo +} - METHOD(Blaster, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_BLASTER_SUICIDE; - } +METHOD(Blaster, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_BLASTER_SUICIDE; +} - METHOD(Blaster, wr_killmessage, int(entity thiswep)) - { - return WEAPON_BLASTER_MURDER; - } +METHOD(Blaster, wr_killmessage, Notification(entity thiswep)) +{ + return WEAPON_BLASTER_MURDER; +} #endif #ifdef CSQC - METHOD(Blaster, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 6; - pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) { sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); } - } +METHOD(Blaster, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 6; + pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) { sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); } +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/crylink.qc b/qcsrc/common/weapons/weapon/crylink.qc index 455567a2f..6ad5f957a 100644 --- a/qcsrc/common/weapons/weapon/crylink.qc +++ b/qcsrc/common/weapons/weapon/crylink.qc @@ -567,123 +567,123 @@ void W_Crylink_Attack2(Weapon thiswep) } } - METHOD(Crylink, wr_aim, void(entity thiswep)) - { - SELFPARAM(); - if(random() < 0.10) - self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false); - else - self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false); - } - METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(autocvar_g_balance_crylink_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } - - if(fire & 1) - { - if(actor.crylink_waitrelease != 1) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(crylink, refire))) - { - W_Crylink_Attack(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(crylink, animtime), w_ready); - } - } - - if((fire & 2) && autocvar_g_balance_crylink_secondary) - { - if(actor.crylink_waitrelease != 2) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(crylink, refire))) - { - W_Crylink_Attack2(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(crylink, animtime), w_ready); - } - } - - if((actor.crylink_waitrelease == 1 && !(fire & 1)) || (actor.crylink_waitrelease == 2 && !(fire & 2))) - { - if(!actor.crylink_lastgroup || time > actor.crylink_lastgroup.teleport_time) - { - // fired and released now! - if(actor.crylink_lastgroup) - { - vector pos; - entity linkjoineffect; - float isprimary = (actor.crylink_waitrelease == 1); - - pos = W_Crylink_LinkJoin(actor.crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed)); - - linkjoineffect = new(linkjoineffect); - linkjoineffect.think = W_Crylink_LinkJoinEffect_Think; - linkjoineffect.nextthink = time + w_crylink_linkjoin_time; - linkjoineffect.owner = actor; - setorigin(linkjoineffect, pos); - } - actor.crylink_waitrelease = 0; - if(!thiswep.wr_checkammo1(thiswep) && !thiswep.wr_checkammo2(thiswep)) - if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) - { - // ran out of ammo! - actor.cnt = WEP_CRYLINK.m_id; - PS(actor).m_switchweapon = w_getbestweapon(actor); - } - } - } - } - METHOD(Crylink, wr_checkammo1, bool(entity thiswep)) - { - SELFPARAM(); - // don't "run out of ammo" and switch weapons while waiting for release - if(self.crylink_lastgroup && self.crylink_waitrelease) - return true; - - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(crylink, ammo); - ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo); - return ammo_amount; - } - METHOD(Crylink, wr_checkammo2, bool(entity thiswep)) - { - SELFPARAM(); - // don't "run out of ammo" and switch weapons while waiting for release - if(self.crylink_lastgroup && self.crylink_waitrelease) - return true; - - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(crylink, ammo); - ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo); - return ammo_amount; - } - METHOD(Crylink, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo)), SND(RELOAD)); - } - METHOD(Crylink, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_CRYLINK_SUICIDE; - } - METHOD(Crylink, wr_killmessage, int(entity thiswep)) - { - return WEAPON_CRYLINK_MURDER; - } +METHOD(Crylink, wr_aim, void(entity thiswep)) +{ + SELFPARAM(); + if(random() < 0.10) + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(crylink, speed), 0, WEP_CVAR_PRI(crylink, middle_lifetime), false); + else + PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_SEC(crylink, speed), 0, WEP_CVAR_SEC(crylink, middle_lifetime), false); +} +METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(autocvar_g_balance_crylink_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } + + if(fire & 1) + { + if(actor.crylink_waitrelease != 1) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(crylink, refire))) + { + W_Crylink_Attack(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(crylink, animtime), w_ready); + } + } + + if((fire & 2) && autocvar_g_balance_crylink_secondary) + { + if(actor.crylink_waitrelease != 2) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(crylink, refire))) + { + W_Crylink_Attack2(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(crylink, animtime), w_ready); + } + } + + if((actor.crylink_waitrelease == 1 && !(fire & 1)) || (actor.crylink_waitrelease == 2 && !(fire & 2))) + { + if(!actor.crylink_lastgroup || time > actor.crylink_lastgroup.teleport_time) + { + // fired and released now! + if(actor.crylink_lastgroup) + { + vector pos; + entity linkjoineffect; + float isprimary = (actor.crylink_waitrelease == 1); + + pos = W_Crylink_LinkJoin(actor.crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed)); + + linkjoineffect = new(linkjoineffect); + linkjoineffect.think = W_Crylink_LinkJoinEffect_Think; + linkjoineffect.nextthink = time + w_crylink_linkjoin_time; + linkjoineffect.owner = actor; + setorigin(linkjoineffect, pos); + } + actor.crylink_waitrelease = 0; + if(!thiswep.wr_checkammo1(thiswep) && !thiswep.wr_checkammo2(thiswep)) + if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) + { + // ran out of ammo! + actor.cnt = WEP_CRYLINK.m_id; + PS(actor).m_switchweapon = w_getbestweapon(actor); + } + } + } +} +METHOD(Crylink, wr_checkammo1, bool(entity thiswep)) +{ + SELFPARAM(); + // don't "run out of ammo" and switch weapons while waiting for release + if(self.crylink_lastgroup && self.crylink_waitrelease) + return true; + + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(crylink, ammo); + ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_PRI(crylink, ammo); + return ammo_amount; +} +METHOD(Crylink, wr_checkammo2, bool(entity thiswep)) +{ + SELFPARAM(); + // don't "run out of ammo" and switch weapons while waiting for release + if(self.crylink_lastgroup && self.crylink_waitrelease) + return true; + + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(crylink, ammo); + ammo_amount += self.(weapon_load[WEP_CRYLINK.m_id]) >= WEP_CVAR_SEC(crylink, ammo); + return ammo_amount; +} +METHOD(Crylink, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo)), SND(RELOAD)); +} +METHOD(Crylink, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_CRYLINK_SUICIDE; +} +METHOD(Crylink, wr_killmessage, Notification(entity thiswep)) +{ + return WEAPON_CRYLINK_MURDER; +} #endif #ifdef CSQC - METHOD(Crylink, wr_impacteffect, void(entity thiswep)) - { - SELFPARAM(); - vector org2; - org2 = w_org + w_backoff * 2; - if(w_deathtype & HITTYPE_SECONDARY) - { - pointparticles(EFFECT_CRYLINK_IMPACT2, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_CRYLINK_IMPACT2, VOL_BASE, ATTN_NORM); - } - else - { - pointparticles(EFFECT_CRYLINK_IMPACT, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_CRYLINK_IMPACT, VOL_BASE, ATTN_NORM); - } - } +METHOD(Crylink, wr_impacteffect, void(entity thiswep)) +{ + SELFPARAM(); + vector org2; + org2 = w_org + w_backoff * 2; + if(w_deathtype & HITTYPE_SECONDARY) + { + pointparticles(EFFECT_CRYLINK_IMPACT2, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_CRYLINK_IMPACT2, VOL_BASE, ATTN_NORM); + } + else + { + pointparticles(EFFECT_CRYLINK_IMPACT, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_CRYLINK_IMPACT, VOL_BASE, ATTN_NORM); + } +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/devastator.qc b/qcsrc/common/weapons/weapon/devastator.qc index 0272e424c..53d4b8e94 100644 --- a/qcsrc/common/weapons/weapon/devastator.qc +++ b/qcsrc/common/weapons/weapon/devastator.qc @@ -276,7 +276,7 @@ void W_Devastator_Think() { if(self == self.realowner.lastrocket) if(!self.realowner.rl_release) - if(!self.BUTTON_ATCK2) + if(!PHYS_INPUT_BUTTON_ATCK2(self)) if(WEP_CVAR(devastator, guiderate)) if(time > self.pushltime) if(!IS_DEAD(self.realowner)) @@ -404,233 +404,233 @@ void W_Devastator_Attack(Weapon thiswep) MUTATOR_CALLHOOK(EditProjectile, self, missile); } - #if 0 - METHOD(Devastator, wr_aim, void(entity thiswep)) - { - // aim and decide to fire if appropriate - self.BUTTON_ATCK = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false); - if(skill >= 2) // skill 0 and 1 bots won't detonate rockets! - { - // decide whether to detonate rockets - entity missile, targetlist, targ; - targetlist = findchainfloat(bot_attack, true); - for(missile = world; (missile = find(missile, classname, "rocket")); ) if(missile.realowner == self) - { - targ = targetlist; - while(targ) - { - if(targ != missile.realowner && vlen(targ.origin - missile.origin) < WEP_CVAR(devastator, radius)) - { - self.BUTTON_ATCK2 = true; - break; - } - targ = targ.chain; - } - } - - if(self.BUTTON_ATCK2) self.BUTTON_ATCK = false; - } - } - #else - METHOD(Devastator, wr_aim, void(entity thiswep)) - { - // aim and decide to fire if appropriate - self.BUTTON_ATCK = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false); - if(skill >= 2) // skill 0 and 1 bots won't detonate rockets! - { - // decide whether to detonate rockets - entity targetlist, targ; - float edgedamage, coredamage, edgeradius, recipricoledgeradius, d; - float selfdamage, teamdamage, enemydamage; - edgedamage = WEP_CVAR(devastator, edgedamage); - coredamage = WEP_CVAR(devastator, damage); - edgeradius = WEP_CVAR(devastator, radius); - recipricoledgeradius = 1 / edgeradius; - selfdamage = 0; - teamdamage = 0; - enemydamage = 0; - targetlist = findchainfloat(bot_attack, true); - FOREACH_ENTITY_ENT(realowner, self, - { - if(it.classname != "rocket") continue; - - targ = targetlist; - while(targ) - { - d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - it.origin); - d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000); - // count potential damage according to type of target - if(targ == self) - selfdamage = selfdamage + d; - else if(targ.team == self.team && teamplay) - teamdamage = teamdamage + d; - else if(bot_shouldattack(targ)) - enemydamage = enemydamage + d; - targ = targ.chain; - } - }); - float desirabledamage; - desirabledamage = enemydamage; - if(time > self.invincible_finished && time > self.spawnshieldtime) - desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent; - if(teamplay && self.team) - desirabledamage = desirabledamage - teamdamage; - - FOREACH_ENTITY_ENT(realowner, self, - { - if(it.classname != "rocket") continue; - - makevectors(it.v_angle); - targ = targetlist; - if(skill > 9) // normal players only do this for the target they are tracking - { - targ = targetlist; - while(targ) - { - if( - (v_forward * normalize(it.origin - targ.origin)< 0.1) - && desirabledamage > 0.1*coredamage - )self.BUTTON_ATCK2 = true; - targ = targ.chain; - } - } - else - { - float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000); - //As the distance gets larger, a correct detonation gets near imposible - //Bots are assumed to use the rocket spawnfunc_light to see if the rocket gets near a player - if(v_forward * normalize(it.origin - self.enemy.origin)< 0.1) - if(IS_PLAYER(self.enemy)) - if(desirabledamage >= 0.1*coredamage) - if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1)) - self.BUTTON_ATCK2 = true; - // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n"); - } - }); - // if we would be doing at X percent of the core damage, detonate it - // but don't fire a new shot at the same time! - if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events - self.BUTTON_ATCK2 = true; - if((skill > 6.5) && (selfdamage > self.health)) - self.BUTTON_ATCK2 = false; - //if(self.BUTTON_ATCK2 == true) - // dprint(ftos(desirabledamage),"\n"); - if(self.BUTTON_ATCK2 == true) self.BUTTON_ATCK = false; - } - } - #endif - METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(WEP_CVAR(devastator, reload_ammo) && actor.clip_load < WEP_CVAR(devastator, ammo)) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else { - if(fire & 1) - { - if(actor.rl_release || WEP_CVAR(devastator, guidestop)) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(devastator, refire))) - { - W_Devastator_Attack(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(devastator, animtime), w_ready); - actor.rl_release = 0; - } - } - else - actor.rl_release = 1; - - if(fire & 2) - if(PS(actor).m_switchweapon == WEP_DEVASTATOR) - { - entity rock; - bool rockfound = false; - for(rock = world; (rock = find(rock, classname, "rocket")); ) if(rock.realowner == actor) - { - if(!rock.rl_detonate_later) - { - rock.rl_detonate_later = true; - rockfound = true; - } - } - if(rockfound) - sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM); - } - } - } - METHOD(Devastator, wr_setup, void(entity thiswep)) - { - self.rl_release = 1; - } - METHOD(Devastator, wr_checkammo1, bool(entity thiswep)) - { - #if 0 - // don't switch while guiding a missile - if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_DEVASTATOR) - { - ammo_amount = false; - if(WEP_CVAR(devastator, reload_ammo)) - { - if(self.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo) && self.(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(devastator, ammo)) - ammo_amount = true; - } - else if(self.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo)) - ammo_amount = true; - return !ammo_amount; - } - #endif - #if 0 - if(self.rl_release == 0) - { - LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: TRUE\n", self.rl_release, self.(thiswep.ammo_field), WEP_CVAR(devastator, ammo)); - return true; - } - else - { - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo); - ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo); - LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s\n", self.rl_release, self.(thiswep.ammo_field), WEP_CVAR(devastator, ammo), (ammo_amount ? "TRUE" : "FALSE")); - return ammo_amount; - } - #else - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo); - ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo); - return ammo_amount; - #endif - } - METHOD(Devastator, wr_checkammo2, bool(entity thiswep)) - { - return false; - } - METHOD(Devastator, wr_resetplayer, void(entity thiswep)) - { - self.lastrocket = NULL; // stop rocket guiding, no revenge from the grave! - self.rl_release = 0; - } - METHOD(Devastator, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, WEP_CVAR(devastator, ammo), SND(RELOAD)); - } - METHOD(Devastator, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_DEVASTATOR_SUICIDE; - } - METHOD(Devastator, wr_killmessage, int(entity thiswep)) - { - if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH)) - return WEAPON_DEVASTATOR_MURDER_SPLASH; - else - return WEAPON_DEVASTATOR_MURDER_DIRECT; - } +#if 0 +METHOD(Devastator, wr_aim, void(entity thiswep)) +{ + // aim and decide to fire if appropriate + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false); + if(skill >= 2) // skill 0 and 1 bots won't detonate rockets! + { + // decide whether to detonate rockets + entity missile, targetlist, targ; + targetlist = findchainfloat(bot_attack, true); + for(missile = world; (missile = find(missile, classname, "rocket")); ) if(missile.realowner == self) + { + targ = targetlist; + while(targ) + { + if(targ != missile.realowner && vlen(targ.origin - missile.origin) < WEP_CVAR(devastator, radius)) + { + PHYS_INPUT_BUTTON_ATCK2(self) = true; + break; + } + targ = targ.chain; + } + } + + if(PHYS_INPUT_BUTTON_ATCK2(self)) PHYS_INPUT_BUTTON_ATCK(self) = false; + } +} +#else +METHOD(Devastator, wr_aim, void(entity thiswep)) +{ + // aim and decide to fire if appropriate + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false); + if(skill >= 2) // skill 0 and 1 bots won't detonate rockets! + { + // decide whether to detonate rockets + entity targetlist, targ; + float edgedamage, coredamage, edgeradius, recipricoledgeradius, d; + float selfdamage, teamdamage, enemydamage; + edgedamage = WEP_CVAR(devastator, edgedamage); + coredamage = WEP_CVAR(devastator, damage); + edgeradius = WEP_CVAR(devastator, radius); + recipricoledgeradius = 1 / edgeradius; + selfdamage = 0; + teamdamage = 0; + enemydamage = 0; + targetlist = findchainfloat(bot_attack, true); + FOREACH_ENTITY_ENT(realowner, self, + { + if(it.classname != "rocket") continue; + + targ = targetlist; + while(targ) + { + d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - it.origin); + d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000); + // count potential damage according to type of target + if(targ == self) + selfdamage = selfdamage + d; + else if(targ.team == self.team && teamplay) + teamdamage = teamdamage + d; + else if(bot_shouldattack(targ)) + enemydamage = enemydamage + d; + targ = targ.chain; + } + }); + float desirabledamage; + desirabledamage = enemydamage; + if(time > self.invincible_finished && time > self.spawnshieldtime) + desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent; + if(teamplay && self.team) + desirabledamage = desirabledamage - teamdamage; + + FOREACH_ENTITY_ENT(realowner, self, + { + if(it.classname != "rocket") continue; + + makevectors(it.v_angle); + targ = targetlist; + if(skill > 9) // normal players only do this for the target they are tracking + { + targ = targetlist; + while(targ) + { + if( + (v_forward * normalize(it.origin - targ.origin)< 0.1) + && desirabledamage > 0.1*coredamage + ) PHYS_INPUT_BUTTON_ATCK2(self) = true; + targ = targ.chain; + } + } + else + { + float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000); + //As the distance gets larger, a correct detonation gets near imposible + //Bots are assumed to use the rocket spawnfunc_light to see if the rocket gets near a player + if(v_forward * normalize(it.origin - self.enemy.origin)< 0.1) + if(IS_PLAYER(self.enemy)) + if(desirabledamage >= 0.1*coredamage) + if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1)) + PHYS_INPUT_BUTTON_ATCK2(self) = true; + // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n"); + } + }); + // if we would be doing at X percent of the core damage, detonate it + // but don't fire a new shot at the same time! + if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events + PHYS_INPUT_BUTTON_ATCK2(self) = true; + if((skill > 6.5) && (selfdamage > self.health)) + PHYS_INPUT_BUTTON_ATCK2(self) = false; + //if(PHYS_INPUT_BUTTON_ATCK2(self) == true) + // dprint(ftos(desirabledamage),"\n"); + if(PHYS_INPUT_BUTTON_ATCK2(self)) PHYS_INPUT_BUTTON_ATCK(self) = false; + } +} +#endif +METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(WEP_CVAR(devastator, reload_ammo) && actor.clip_load < WEP_CVAR(devastator, ammo)) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else { + if(fire & 1) + { + if(actor.rl_release || WEP_CVAR(devastator, guidestop)) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(devastator, refire))) + { + W_Devastator_Attack(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(devastator, animtime), w_ready); + actor.rl_release = 0; + } + } + else + actor.rl_release = 1; + + if(fire & 2) + if(PS(actor).m_switchweapon == WEP_DEVASTATOR) + { + entity rock; + bool rockfound = false; + for(rock = world; (rock = find(rock, classname, "rocket")); ) if(rock.realowner == actor) + { + if(!rock.rl_detonate_later) + { + rock.rl_detonate_later = true; + rockfound = true; + } + } + if(rockfound) + sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM); + } + } +} +METHOD(Devastator, wr_setup, void(entity thiswep)) +{ + self.rl_release = 1; +} +METHOD(Devastator, wr_checkammo1, bool(entity thiswep)) +{ + #if 0 + // don't switch while guiding a missile + if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_DEVASTATOR) + { + ammo_amount = false; + if(WEP_CVAR(devastator, reload_ammo)) + { + if(self.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo) && self.(weapon_load[WEP_DEVASTATOR.m_id]) < WEP_CVAR(devastator, ammo)) + ammo_amount = true; + } + else if(self.(thiswep.ammo_field) < WEP_CVAR(devastator, ammo)) + ammo_amount = true; + return !ammo_amount; + } + #endif + #if 0 + if(self.rl_release == 0) + { + LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: TRUE\n", self.rl_release, self.(thiswep.ammo_field), WEP_CVAR(devastator, ammo)); + return true; + } + else + { + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo); + ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo); + LOG_INFOF("W_Devastator(WR_CHECKAMMO1): %d, %.2f, %d: %s\n", self.rl_release, self.(thiswep.ammo_field), WEP_CVAR(devastator, ammo), (ammo_amount ? "TRUE" : "FALSE")); + return ammo_amount; + } + #else + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(devastator, ammo); + ammo_amount += self.(weapon_load[WEP_DEVASTATOR.m_id]) >= WEP_CVAR(devastator, ammo); + return ammo_amount; + #endif +} +METHOD(Devastator, wr_checkammo2, bool(entity thiswep)) +{ + return false; +} +METHOD(Devastator, wr_resetplayer, void(entity thiswep)) +{ + self.lastrocket = NULL; // stop rocket guiding, no revenge from the grave! + self.rl_release = 0; +} +METHOD(Devastator, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, WEP_CVAR(devastator, ammo), SND(RELOAD)); +} +METHOD(Devastator, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_DEVASTATOR_SUICIDE; +} +METHOD(Devastator, wr_killmessage, Notification(entity thiswep)) +{ + if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH)) + return WEAPON_DEVASTATOR_MURDER_SPLASH; + else + return WEAPON_DEVASTATOR_MURDER_DIRECT; +} #endif #ifdef CSQC - METHOD(Devastator, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 12; - pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTN_NORM); - } +METHOD(Devastator, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 12; + pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTN_NORM); +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/electro.qc b/qcsrc/common/weapons/weapon/electro.qc index 3e93644fb..f539b1492 100644 --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@ -411,7 +411,7 @@ void W_Electro_Attack_Orb(Weapon thiswep) void W_Electro_CheckAttack(Weapon thiswep, entity actor, .entity weaponentity, int fire) {SELFPARAM(); if(self.electro_count > 1) - if(self.BUTTON_ATCK2) + if(PHYS_INPUT_BUTTON_ATCK2(self)) if(weapon_prepareattack(thiswep, actor, weaponentity, true, -1)) { W_Electro_Attack_Orb(WEP_ELECTRO); @@ -425,152 +425,152 @@ void W_Electro_CheckAttack(Weapon thiswep, entity actor, .entity weaponentity, i .float bot_secondary_electromooth; - METHOD(Electro, wr_aim, void(entity thiswep)) - { - self.BUTTON_ATCK = self.BUTTON_ATCK2 = false; - if(vdist(self.origin - self.enemy.origin, >, 1000)) { self.bot_secondary_electromooth = 0; } - if(self.bot_secondary_electromooth == 0) - { - float shoot; - - if(WEP_CVAR_PRI(electro, speed)) - shoot = bot_aim(WEP_CVAR_PRI(electro, speed), 0, WEP_CVAR_PRI(electro, lifetime), false); - else - shoot = bot_aim(1000000, 0, 0.001, false); - - if(shoot) - { - self.BUTTON_ATCK = true; - if(random() < 0.01) self.bot_secondary_electromooth = 1; - } - } - else - { - if(bot_aim(WEP_CVAR_SEC(electro, speed), WEP_CVAR_SEC(electro, speed_up), WEP_CVAR_SEC(electro, lifetime), true)) - { - self.BUTTON_ATCK2 = true; - if(random() < 0.03) self.bot_secondary_electromooth = 0; - } - } - } - METHOD(Electro, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(autocvar_g_balance_electro_reload_ammo) // forced reload // WEAPONTODO - { - float ammo_amount = 0; - if(actor.clip_load >= WEP_CVAR_PRI(electro, ammo)) - ammo_amount = 1; - if(actor.clip_load >= WEP_CVAR_SEC(electro, ammo)) - ammo_amount += 1; - - if(!ammo_amount) - { - thiswep.wr_reload(thiswep, actor, weaponentity); - return; - } - } - - if(fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) - { - W_Electro_Attack_Bolt(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); - } - } - else if(fire & 2) - { - if(time >= actor.electro_secondarytime) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(electro, refire))) - { - W_Electro_Attack_Orb(thiswep); - actor.electro_count = WEP_CVAR_SEC(electro, count); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack); - actor.electro_secondarytime = time + WEP_CVAR_SEC(electro, refire2) * W_WeaponRateFactor(); - } - } - } - METHOD(Electro, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(electro, ammo); - ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_PRI(electro, ammo); - return ammo_amount; - } - METHOD(Electro, wr_checkammo2, bool(entity thiswep)) - { - float ammo_amount; - if(WEP_CVAR(electro, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false. - { - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo); - ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo); - } - else - { - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo); - ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo); - } - return ammo_amount; - } - METHOD(Electro, wr_resetplayer, void(entity thiswep)) - { - self.electro_secondarytime = time; - } - METHOD(Electro, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, min(WEP_CVAR_PRI(electro, ammo), WEP_CVAR_SEC(electro, ammo)), SND(RELOAD)); - } - METHOD(Electro, wr_suicidemessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_ELECTRO_SUICIDE_ORBS; - else - return WEAPON_ELECTRO_SUICIDE_BOLT; - } - METHOD(Electro, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - { - return WEAPON_ELECTRO_MURDER_ORBS; - } - else - { - if(w_deathtype & HITTYPE_BOUNCE) - return WEAPON_ELECTRO_MURDER_COMBO; - else - return WEAPON_ELECTRO_MURDER_BOLT; - } - } +METHOD(Electro, wr_aim, void(entity thiswep)) +{ + PHYS_INPUT_BUTTON_ATCK(self) = PHYS_INPUT_BUTTON_ATCK2(self) = false; + if(vdist(self.origin - self.enemy.origin, >, 1000)) { self.bot_secondary_electromooth = 0; } + if(self.bot_secondary_electromooth == 0) + { + float shoot; + + if(WEP_CVAR_PRI(electro, speed)) + shoot = bot_aim(WEP_CVAR_PRI(electro, speed), 0, WEP_CVAR_PRI(electro, lifetime), false); + else + shoot = bot_aim(1000000, 0, 0.001, false); + + if(shoot) + { + PHYS_INPUT_BUTTON_ATCK(self) = true; + if(random() < 0.01) self.bot_secondary_electromooth = 1; + } + } + else + { + if(bot_aim(WEP_CVAR_SEC(electro, speed), WEP_CVAR_SEC(electro, speed_up), WEP_CVAR_SEC(electro, lifetime), true)) + { + PHYS_INPUT_BUTTON_ATCK2(self) = true; + if(random() < 0.03) self.bot_secondary_electromooth = 0; + } + } +} +METHOD(Electro, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(autocvar_g_balance_electro_reload_ammo) // forced reload // WEAPONTODO + { + float ammo_amount = 0; + if(actor.clip_load >= WEP_CVAR_PRI(electro, ammo)) + ammo_amount = 1; + if(actor.clip_load >= WEP_CVAR_SEC(electro, ammo)) + ammo_amount += 1; + + if(!ammo_amount) + { + thiswep.wr_reload(thiswep, actor, weaponentity); + return; + } + } + + if(fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(electro, refire))) + { + W_Electro_Attack_Bolt(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(electro, animtime), w_ready); + } + } + else if(fire & 2) + { + if(time >= actor.electro_secondarytime) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(electro, refire))) + { + W_Electro_Attack_Orb(thiswep); + actor.electro_count = WEP_CVAR_SEC(electro, count); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(electro, animtime), W_Electro_CheckAttack); + actor.electro_secondarytime = time + WEP_CVAR_SEC(electro, refire2) * W_WeaponRateFactor(); + } + } +} +METHOD(Electro, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(electro, ammo); + ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_PRI(electro, ammo); + return ammo_amount; +} +METHOD(Electro, wr_checkammo2, bool(entity thiswep)) +{ + float ammo_amount; + if(WEP_CVAR(electro, combo_safeammocheck)) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false. + { + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo); + ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo) + WEP_CVAR_PRI(electro, ammo); + } + else + { + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(electro, ammo); + ammo_amount += self.(weapon_load[WEP_ELECTRO.m_id]) >= WEP_CVAR_SEC(electro, ammo); + } + return ammo_amount; +} +METHOD(Electro, wr_resetplayer, void(entity thiswep)) +{ + self.electro_secondarytime = time; +} +METHOD(Electro, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, min(WEP_CVAR_PRI(electro, ammo), WEP_CVAR_SEC(electro, ammo)), SND(RELOAD)); +} +METHOD(Electro, wr_suicidemessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_ELECTRO_SUICIDE_ORBS; + else + return WEAPON_ELECTRO_SUICIDE_BOLT; +} +METHOD(Electro, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + { + return WEAPON_ELECTRO_MURDER_ORBS; + } + else + { + if(w_deathtype & HITTYPE_BOUNCE) + return WEAPON_ELECTRO_MURDER_COMBO; + else + return WEAPON_ELECTRO_MURDER_BOLT; + } +} #endif #ifdef CSQC - METHOD(Electro, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 6; - if(w_deathtype & HITTYPE_SECONDARY) - { - pointparticles(EFFECT_ELECTRO_BALLEXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM); - } - else - { - if(w_deathtype & HITTYPE_BOUNCE) - { - // this is sent as "primary (w_deathtype & HITTYPE_BOUNCE)" to distinguish it from (w_deathtype & HITTYPE_SECONDARY) bounced balls - pointparticles(EFFECT_ELECTRO_COMBO, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_ELECTRO_IMPACT_COMBO, VOL_BASE, ATTEN_NORM); - } - else - { - pointparticles(EFFECT_ELECTRO_IMPACT, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM); - } - } - } +METHOD(Electro, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 6; + if(w_deathtype & HITTYPE_SECONDARY) + { + pointparticles(EFFECT_ELECTRO_BALLEXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM); + } + else + { + if(w_deathtype & HITTYPE_BOUNCE) + { + // this is sent as "primary (w_deathtype & HITTYPE_BOUNCE)" to distinguish it from (w_deathtype & HITTYPE_SECONDARY) bounced balls + pointparticles(EFFECT_ELECTRO_COMBO, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_ELECTRO_IMPACT_COMBO, VOL_BASE, ATTEN_NORM); + } + else + { + pointparticles(EFFECT_ELECTRO_IMPACT, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM); + } + } +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/fireball.qc b/qcsrc/common/weapons/weapon/fireball.qc index 50119a687..8c0d928db 100644 --- a/qcsrc/common/weapons/weapon/fireball.qc +++ b/qcsrc/common/weapons/weapon/fireball.qc @@ -351,96 +351,96 @@ void W_Fireball_Attack2() MUTATOR_CALLHOOK(EditProjectile, self, proj); } - METHOD(Fireball, wr_aim, void(entity thiswep)) - { - self.BUTTON_ATCK = false; - self.BUTTON_ATCK2 = false; - if(self.bot_primary_fireballmooth == 0) - { - if(bot_aim(WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false)) - { - self.BUTTON_ATCK = true; - if(random() < 0.02) self.bot_primary_fireballmooth = 0; - } - } - else - { - if(bot_aim(WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true)) - { - self.BUTTON_ATCK2 = true; - if(random() < 0.01) self.bot_primary_fireballmooth = 1; - } - } - } - METHOD(Fireball, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(fire & 1) - { - if(time >= actor.fireball_primarytime) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(fireball, refire))) - { - W_Fireball_Attack1_Frame0(thiswep, actor, weaponentity, fire); - actor.fireball_primarytime = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor(); - } - } - else if(fire & 2) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(fireball, refire))) - { - W_Fireball_Attack2(); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(fireball, animtime), w_ready); - } - } - } - METHOD(Fireball, wr_setup, void(entity thiswep)) - { - self.ammo_field = ammo_none; - } - METHOD(Fireball, wr_checkammo1, bool(entity thiswep)) - { - return true; // infinite ammo - } - METHOD(Fireball, wr_checkammo2, bool(entity thiswep)) - { - return true; // fireball has infinite ammo - } - METHOD(Fireball, wr_resetplayer, void(entity thiswep)) - { - self.fireball_primarytime = time; - } - METHOD(Fireball, wr_suicidemessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_FIREBALL_SUICIDE_FIREMINE; - else - return WEAPON_FIREBALL_SUICIDE_BLAST; - } - METHOD(Fireball, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_FIREBALL_MURDER_FIREMINE; - else - return WEAPON_FIREBALL_MURDER_BLAST; - } +METHOD(Fireball, wr_aim, void(entity thiswep)) +{ + PHYS_INPUT_BUTTON_ATCK(self) = false; + PHYS_INPUT_BUTTON_ATCK2(self) = false; + if(self.bot_primary_fireballmooth == 0) + { + if(bot_aim(WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false)) + { + PHYS_INPUT_BUTTON_ATCK(self) = true; + if(random() < 0.02) self.bot_primary_fireballmooth = 0; + } + } + else + { + if(bot_aim(WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true)) + { + PHYS_INPUT_BUTTON_ATCK2(self) = true; + if(random() < 0.01) self.bot_primary_fireballmooth = 1; + } + } +} +METHOD(Fireball, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(fire & 1) + { + if(time >= actor.fireball_primarytime) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(fireball, refire))) + { + W_Fireball_Attack1_Frame0(thiswep, actor, weaponentity, fire); + actor.fireball_primarytime = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor(); + } + } + else if(fire & 2) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(fireball, refire))) + { + W_Fireball_Attack2(); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(fireball, animtime), w_ready); + } + } +} +METHOD(Fireball, wr_setup, void(entity thiswep)) +{ + self.ammo_field = ammo_none; +} +METHOD(Fireball, wr_checkammo1, bool(entity thiswep)) +{ + return true; // infinite ammo +} +METHOD(Fireball, wr_checkammo2, bool(entity thiswep)) +{ + return true; // fireball has infinite ammo +} +METHOD(Fireball, wr_resetplayer, void(entity thiswep)) +{ + self.fireball_primarytime = time; +} +METHOD(Fireball, wr_suicidemessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_FIREBALL_SUICIDE_FIREMINE; + else + return WEAPON_FIREBALL_SUICIDE_BLAST; +} +METHOD(Fireball, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_FIREBALL_MURDER_FIREMINE; + else + return WEAPON_FIREBALL_MURDER_BLAST; +} #endif #ifdef CSQC - METHOD(Fireball, wr_impacteffect, void(entity thiswep)) - { - vector org2; - if(w_deathtype & HITTYPE_SECONDARY) - { - // firemine goes out silently - } - else - { - org2 = w_org + w_backoff * 16; - pointparticles(EFFECT_FIREBALL_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_FIREBALL_IMPACT2, VOL_BASE, ATTEN_NORM * 0.25); // long range boom - } - } +METHOD(Fireball, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + if(w_deathtype & HITTYPE_SECONDARY) + { + // firemine goes out silently + } + else + { + org2 = w_org + w_backoff * 16; + pointparticles(EFFECT_FIREBALL_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_FIREBALL_IMPACT2, VOL_BASE, ATTEN_NORM * 0.25); // long range boom + } +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/hagar.qc b/qcsrc/common/weapons/weapon/hagar.qc index ff6088f8f..c66e4a438 100644 --- a/qcsrc/common/weapons/weapon/hagar.qc +++ b/qcsrc/common/weapons/weapon/hagar.qc @@ -309,9 +309,9 @@ void W_Hagar_Attack2_Load(Weapon thiswep, .entity weaponentity) bool stopped = loaded || !enough_ammo; - if(self.BUTTON_ATCK2) + if(PHYS_INPUT_BUTTON_ATCK2(self)) { - if(self.BUTTON_ATCK && WEP_CVAR_SEC(hagar, load_abort)) + if(PHYS_INPUT_BUTTON_ATCK(self) && WEP_CVAR_SEC(hagar, load_abort)) { if(self.hagar_load) { @@ -375,7 +375,7 @@ void W_Hagar_Attack2_Load(Weapon thiswep, .entity weaponentity) } // release if player let go of button or if they've held it in too long - if(!self.BUTTON_ATCK2 || (stopped && self.hagar_loadstep < time && WEP_CVAR_SEC(hagar, load_hold) >= 0)) + if(!PHYS_INPUT_BUTTON_ATCK2(self) || (stopped && self.hagar_loadstep < time && WEP_CVAR_SEC(hagar, load_hold) >= 0)) { self.(weaponentity).state = WS_READY; W_Hagar_Attack2_Load_Release(weaponentity); @@ -397,117 +397,117 @@ void W_Hagar_Attack2_Load(Weapon thiswep, .entity weaponentity) } } - METHOD(Hagar, wr_aim, void(entity thiswep)) - { - if(random()>0.15) - self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false); - else // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming - self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false); - } - METHOD(Hagar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - float loadable_secondary; - loadable_secondary = (WEP_CVAR_SEC(hagar, load) && WEP_CVAR(hagar, secondary)); - - if(loadable_secondary) - W_Hagar_Attack2_Load(thiswep, weaponentity); // must always run each frame - if(autocvar_g_balance_hagar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else if((fire & 1) && !actor.hagar_load && !actor.hagar_loadblock) // not while secondary is loaded or awaiting reset - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hagar, refire))) - { - W_Hagar_Attack(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hagar, refire), w_ready); - } - } - else if((fire & 2) && !loadable_secondary && WEP_CVAR(hagar, secondary)) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hagar, refire))) - { - W_Hagar_Attack2(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hagar, refire), w_ready); - } - } - } - METHOD(Hagar, wr_gonethink, void(entity thiswep)) - { - // we lost the weapon and want to prepare switching away - if(self.hagar_load) - { - .entity weaponentity = weaponentities[0]; // TODO: unhardcode - self.(weaponentity).state = WS_READY; - W_Hagar_Attack2_Load_Release(weaponentity); - } - } - METHOD(Hagar, wr_setup, void(entity thiswep)) - { - self.hagar_loadblock = false; +METHOD(Hagar, wr_aim, void(entity thiswep)) +{ + if(random()>0.15) + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false); + else // not using secondary_speed since these are only 15% and should cause some ricochets without re-aiming + PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_PRI(hagar, speed), 0, WEP_CVAR_PRI(hagar, lifetime), false); +} +METHOD(Hagar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + float loadable_secondary; + loadable_secondary = (WEP_CVAR_SEC(hagar, load) && WEP_CVAR(hagar, secondary)); + + if(loadable_secondary) + W_Hagar_Attack2_Load(thiswep, weaponentity); // must always run each frame + if(autocvar_g_balance_hagar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else if((fire & 1) && !actor.hagar_load && !actor.hagar_loadblock) // not while secondary is loaded or awaiting reset + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hagar, refire))) + { + W_Hagar_Attack(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hagar, refire), w_ready); + } + } + else if((fire & 2) && !loadable_secondary && WEP_CVAR(hagar, secondary)) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hagar, refire))) + { + W_Hagar_Attack2(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hagar, refire), w_ready); + } + } +} +METHOD(Hagar, wr_gonethink, void(entity thiswep)) +{ + // we lost the weapon and want to prepare switching away + if(self.hagar_load) + { + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + self.(weaponentity).state = WS_READY; + W_Hagar_Attack2_Load_Release(weaponentity); + } +} +METHOD(Hagar, wr_setup, void(entity thiswep)) +{ + self.hagar_loadblock = false; - if(self.hagar_load) - { - W_DecreaseAmmo(thiswep, self, WEP_CVAR_SEC(hagar, ammo) * self.hagar_load * -1); // give back ammo if necessary - self.hagar_load = 0; - } - } - METHOD(Hagar, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hagar, ammo); - ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_PRI(hagar, ammo); - return ammo_amount; - } - METHOD(Hagar, wr_checkammo2, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hagar, ammo); - ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo); - return ammo_amount; - } - METHOD(Hagar, wr_resetplayer, void(entity thiswep)) - { - self.hagar_load = 0; - } - METHOD(Hagar, wr_playerdeath, void(entity thiswep)) - { - .entity weaponentity = weaponentities[0]; // TODO: unhardcode - // if we have any rockets loaded when we die, release them - if(self.hagar_load && WEP_CVAR_SEC(hagar, load_releasedeath)) - W_Hagar_Attack2_Load_Release(weaponentity); - } - METHOD(Hagar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - if(!self.hagar_load) // require releasing loaded rockets first - W_Reload(self, min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), SND(RELOAD)); - } - METHOD(Hagar, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_HAGAR_SUICIDE; - } - METHOD(Hagar, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_HAGAR_MURDER_BURST; - else - return WEAPON_HAGAR_MURDER_SPRAY; - } + if(self.hagar_load) + { + W_DecreaseAmmo(thiswep, self, WEP_CVAR_SEC(hagar, ammo) * self.hagar_load * -1); // give back ammo if necessary + self.hagar_load = 0; + } +} +METHOD(Hagar, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hagar, ammo); + ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_PRI(hagar, ammo); + return ammo_amount; +} +METHOD(Hagar, wr_checkammo2, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hagar, ammo); + ammo_amount += self.(weapon_load[WEP_HAGAR.m_id]) >= WEP_CVAR_SEC(hagar, ammo); + return ammo_amount; +} +METHOD(Hagar, wr_resetplayer, void(entity thiswep)) +{ + self.hagar_load = 0; +} +METHOD(Hagar, wr_playerdeath, void(entity thiswep)) +{ + .entity weaponentity = weaponentities[0]; // TODO: unhardcode + // if we have any rockets loaded when we die, release them + if(self.hagar_load && WEP_CVAR_SEC(hagar, load_releasedeath)) + W_Hagar_Attack2_Load_Release(weaponentity); +} +METHOD(Hagar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + if(!self.hagar_load) // require releasing loaded rockets first + W_Reload(self, min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), SND(RELOAD)); +} +METHOD(Hagar, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_HAGAR_SUICIDE; +} +METHOD(Hagar, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_HAGAR_MURDER_BURST; + else + return WEAPON_HAGAR_MURDER_SPRAY; +} #endif #ifdef CSQC - METHOD(Hagar, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 6; - pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - { - if(w_random<0.15) - sound(self, CH_SHOTS, SND_HAGEXP1, VOL_BASE, ATTN_NORM); - else if(w_random<0.7) - sound(self, CH_SHOTS, SND_HAGEXP2, VOL_BASE, ATTN_NORM); - else - sound(self, CH_SHOTS, SND_HAGEXP3, VOL_BASE, ATTN_NORM); - } - } +METHOD(Hagar, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 6; + pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + { + if(w_random<0.15) + sound(self, CH_SHOTS, SND_HAGEXP1, VOL_BASE, ATTN_NORM); + else if(w_random<0.7) + sound(self, CH_SHOTS, SND_HAGEXP2, VOL_BASE, ATTN_NORM); + else + sound(self, CH_SHOTS, SND_HAGEXP3, VOL_BASE, ATTN_NORM); + } +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/hlac.qc b/qcsrc/common/weapons/weapon/hlac.qc index 3c158f608..901634506 100644 --- a/qcsrc/common/weapons/weapon/hlac.qc +++ b/qcsrc/common/weapons/weapon/hlac.qc @@ -169,7 +169,7 @@ void W_HLAC_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int return; } - if(actor.BUTTON_ATCK) + if(PHYS_INPUT_BUTTON_ATCK(actor)) { if(!thiswep.wr_checkammo1(thiswep)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) @@ -207,69 +207,69 @@ void W_HLAC_Attack2_Frame(Weapon thiswep) } } - METHOD(HLAC, wr_aim, void(entity thiswep)) - { - self.BUTTON_ATCK = bot_aim(WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false); - } - METHOD(HLAC, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(autocvar_g_balance_hlac_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else if(fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hlac, refire))) - { - actor.misc_bulletcounter = 0; - W_HLAC_Attack(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame); - } - } - - else if((fire & 2) && WEP_CVAR(hlac, secondary)) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hlac, refire))) - { - W_HLAC_Attack2_Frame(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hlac, animtime), w_ready); - } - } - } - METHOD(HLAC, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hlac, ammo); - ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_PRI(hlac, ammo); - return ammo_amount; - } - METHOD(HLAC, wr_checkammo2, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hlac, ammo); - ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_SEC(hlac, ammo); - return ammo_amount; - } - METHOD(HLAC, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), SND(RELOAD)); - } - METHOD(HLAC, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_HLAC_SUICIDE; - } - METHOD(HLAC, wr_killmessage, int(entity thiswep)) - { - return WEAPON_HLAC_MURDER; - } +METHOD(HLAC, wr_aim, void(entity thiswep)) +{ + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false); +} +METHOD(HLAC, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(autocvar_g_balance_hlac_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else if(fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hlac, refire))) + { + actor.misc_bulletcounter = 0; + W_HLAC_Attack(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame); + } + } + + else if((fire & 2) && WEP_CVAR(hlac, secondary)) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hlac, refire))) + { + W_HLAC_Attack2_Frame(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hlac, animtime), w_ready); + } + } +} +METHOD(HLAC, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(hlac, ammo); + ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_PRI(hlac, ammo); + return ammo_amount; +} +METHOD(HLAC, wr_checkammo2, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(hlac, ammo); + ammo_amount += self.(weapon_load[WEP_HLAC.m_id]) >= WEP_CVAR_SEC(hlac, ammo); + return ammo_amount; +} +METHOD(HLAC, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), SND(RELOAD)); +} +METHOD(HLAC, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_HLAC_SUICIDE; +} +METHOD(HLAC, wr_killmessage, Notification(entity thiswep)) +{ + return WEAPON_HLAC_MURDER; +} #endif #ifdef CSQC - METHOD(HLAC, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 6; - pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); - } +METHOD(HLAC, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 6; + pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/hook.qc b/qcsrc/common/weapons/weapon/hook.qc index d76095ec8..5af5a9ad1 100644 --- a/qcsrc/common/weapons/weapon/hook.qc +++ b/qcsrc/common/weapons/weapon/hook.qc @@ -180,141 +180,137 @@ void W_Hook_Attack2(Weapon thiswep, entity actor) MUTATOR_CALLHOOK(EditProjectile, actor, gren); } - METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if (fire & 1) { - if(!actor.hook) - if(!(actor.hook_state & HOOK_WAITING_FOR_RELEASE)) - if(time > actor.hook_refire) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, -1)) - { - W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo)); - actor.hook_state |= HOOK_FIRING; - actor.hook_state |= HOOK_WAITING_FOR_RELEASE; - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hook, animtime), w_ready); - } - } else { - actor.hook_state |= HOOK_REMOVING; - actor.hook_state &= ~HOOK_WAITING_FOR_RELEASE; - } +METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if (fire & 1) { + if(!actor.hook) + if(!(actor.hook_state & HOOK_WAITING_FOR_RELEASE)) + if(time > actor.hook_refire) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, -1)) + { + W_DecreaseAmmo(thiswep, actor, thiswep.ammo_factor * WEP_CVAR_PRI(hook, ammo)); + actor.hook_state |= HOOK_FIRING; + actor.hook_state |= HOOK_WAITING_FOR_RELEASE; + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hook, animtime), w_ready); + } + } else { + actor.hook_state |= HOOK_REMOVING; + actor.hook_state &= ~HOOK_WAITING_FOR_RELEASE; + } - if(fire & 2) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hook, refire))) - { - W_Hook_Attack2(thiswep, actor); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hook, animtime), w_ready); - } - } + if(fire & 2) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hook, refire))) + { + W_Hook_Attack2(thiswep, actor); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hook, animtime), w_ready); + } + } - if(actor.hook) - { - // if hooked, no bombs, and increase the timer - actor.hook_refire = max(actor.hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor()); + if(actor.hook) + { + // if hooked, no bombs, and increase the timer + actor.hook_refire = max(actor.hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor()); - // hook also inhibits health regeneration, but only for 1 second - if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) - actor.pauseregen_finished = max(actor.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen); - } + // hook also inhibits health regeneration, but only for 1 second + if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) + actor.pauseregen_finished = max(actor.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen); + } - if(actor.hook && actor.hook.state == 1) - { - float hooked_time_max = WEP_CVAR_PRI(hook, hooked_time_max); - if(hooked_time_max > 0) - { - if( time > actor.hook_time_hooked + hooked_time_max ) - actor.hook_state |= HOOK_REMOVING; - } - - float hooked_fuel = thiswep.ammo_factor * WEP_CVAR_PRI(hook, hooked_ammo); - if(hooked_fuel > 0) - { - if( time > actor.hook_time_fueldecrease ) - { - if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) - { - if( actor.ammo_fuel >= (time - actor.hook_time_fueldecrease) * hooked_fuel ) - { - W_DecreaseAmmo(thiswep, actor, (time - actor.hook_time_fueldecrease) * hooked_fuel); - actor.hook_time_fueldecrease = time; - // decrease next frame again - } - else - { - actor.ammo_fuel = 0; - actor.hook_state |= HOOK_REMOVING; - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); - } - } - } - } - } - else - { - actor.hook_time_hooked = time; - actor.hook_time_fueldecrease = time + WEP_CVAR_PRI(hook, hooked_time_free); - } + if(actor.hook && actor.hook.state == 1) + { + float hooked_time_max = WEP_CVAR_PRI(hook, hooked_time_max); + if(hooked_time_max > 0) + { + if( time > actor.hook_time_hooked + hooked_time_max ) + actor.hook_state |= HOOK_REMOVING; + } + + float hooked_fuel = thiswep.ammo_factor * WEP_CVAR_PRI(hook, hooked_ammo); + if(hooked_fuel > 0) + { + if( time > actor.hook_time_fueldecrease ) + { + if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) + { + if( actor.ammo_fuel >= (time - actor.hook_time_fueldecrease) * hooked_fuel ) + { + W_DecreaseAmmo(thiswep, actor, (time - actor.hook_time_fueldecrease) * hooked_fuel); + actor.hook_time_fueldecrease = time; + // decrease next frame again + } + else + { + actor.ammo_fuel = 0; + actor.hook_state |= HOOK_REMOVING; + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + } + } + } + } + } + else + { + actor.hook_time_hooked = time; + actor.hook_time_fueldecrease = time + WEP_CVAR_PRI(hook, hooked_time_free); + } - actor.hook_state = BITSET(actor.hook_state, HOOK_PULLING, (!actor.BUTTON_CROUCH || !autocvar_g_balance_grapplehook_crouchslide)); + actor.hook_state = BITSET(actor.hook_state, HOOK_PULLING, (!PHYS_INPUT_BUTTON_CROUCH(actor) || !autocvar_g_balance_grapplehook_crouchslide)); - if (actor.hook_state & HOOK_FIRING) - { - if (actor.hook) - RemoveGrapplingHook(actor); - WITH(entity, self, actor, FireGrapplingHook()); - actor.hook_state &= ~HOOK_FIRING; - actor.hook_refire = max(actor.hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor()); - } - else if (actor.hook_state & HOOK_REMOVING) - { - if (actor.hook) - RemoveGrapplingHook(actor); - actor.hook_state &= ~HOOK_REMOVING; - } - } - METHOD(Hook, wr_setup, void(entity thiswep)) - { - self.hook_state &= ~HOOK_WAITING_FOR_RELEASE; - } - METHOD(Hook, wr_checkammo1, bool(Hook thiswep)) - { - if (!thiswep.ammo_factor) return true; - if(self.hook) - return self.ammo_fuel > 0; - else - return self.ammo_fuel >= WEP_CVAR_PRI(hook, ammo); - } - METHOD(Hook, wr_checkammo2, bool(Hook thiswep)) - { - // infinite ammo for now - return true; // self.ammo_cells >= WEP_CVAR_SEC(hook, ammo); // WEAPONTODO: see above - } - METHOD(Hook, wr_resetplayer, void(entity thiswep)) - { - RemoveGrapplingHook(self); - self.hook_time = 0; - self.hook_refire = time; - } - METHOD(Hook, wr_suicidemessage, int(entity thiswep)) - { - return false; - } - METHOD(Hook, wr_killmessage, int(entity thiswep)) - { - return WEAPON_HOOK_MURDER; - } + if (actor.hook_state & HOOK_FIRING) + { + if (actor.hook) + RemoveGrapplingHook(actor); + WITH(entity, self, actor, FireGrapplingHook()); + actor.hook_state &= ~HOOK_FIRING; + actor.hook_refire = max(actor.hook_refire, time + autocvar_g_balance_grapplehook_refire * W_WeaponRateFactor()); + } + else if (actor.hook_state & HOOK_REMOVING) + { + if (actor.hook) + RemoveGrapplingHook(actor); + actor.hook_state &= ~HOOK_REMOVING; + } +} +METHOD(Hook, wr_setup, void(entity thiswep)) +{ + self.hook_state &= ~HOOK_WAITING_FOR_RELEASE; +} +METHOD(Hook, wr_checkammo1, bool(Hook thiswep)) +{ + if (!thiswep.ammo_factor) return true; + if(self.hook) + return self.ammo_fuel > 0; + else + return self.ammo_fuel >= WEP_CVAR_PRI(hook, ammo); +} +METHOD(Hook, wr_checkammo2, bool(Hook thiswep)) +{ + // infinite ammo for now + return true; // self.ammo_cells >= WEP_CVAR_SEC(hook, ammo); // WEAPONTODO: see above +} +METHOD(Hook, wr_resetplayer, void(entity thiswep)) +{ + RemoveGrapplingHook(self); + self.hook_time = 0; + self.hook_refire = time; +} +METHOD(Hook, wr_killmessage, Notification(entity thiswep)) +{ + return WEAPON_HOOK_MURDER; +} #endif #ifdef CSQC - METHOD(Hook, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_HOOK_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_HOOKBOMB_IMPACT, VOL_BASE, ATTN_NORM); - } +METHOD(Hook, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_HOOK_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_HOOKBOMB_IMPACT, VOL_BASE, ATTN_NORM); +} #endif @@ -322,6 +318,8 @@ void W_Hook_Attack2(Weapon thiswep, entity actor) #include #include +float autocvar_cl_grapplehook_alpha = 1; + void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float theAlpha, float drawflag, vector vieworg); entityclass(Hook); @@ -419,7 +417,7 @@ void Draw_GrapplingHook(entity this) { default: case NET_ENT_CLIENT_HOOK: - intensity = 1; + intensity = autocvar_cl_grapplehook_alpha; offset = 0; switch(t) { diff --git a/qcsrc/common/weapons/weapon/machinegun.qc b/qcsrc/common/weapons/weapon/machinegun.qc index f220752b3..1b1af4df4 100644 --- a/qcsrc/common/weapons/weapon/machinegun.qc +++ b/qcsrc/common/weapons/weapon/machinegun.qc @@ -146,7 +146,7 @@ void W_MachineGun_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentit w_ready(thiswep, actor, weaponentity, fire); return; } - if(actor.BUTTON_ATCK) + if(PHYS_INPUT_BUTTON_ATCK(actor)) { if(!thiswep.wr_checkammo2(thiswep)) if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) @@ -242,125 +242,125 @@ void W_MachineGun_Attack_Burst(Weapon thiswep, entity actor, .entity weaponentit } - METHOD(MachineGun, wr_aim, void(entity thiswep)) - { - if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200)) - self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false); - else - self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false); - } - METHOD(MachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(WEP_CVAR(machinegun, reload_ammo) && actor.clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else - if(WEP_CVAR(machinegun, mode) == 1) - { - if(fire & 1) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) - { - actor.misc_bulletcounter = 0; - W_MachineGun_Attack_Auto(thiswep, actor, weaponentity, fire); - } - - if(fire & 2) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) - { - if(!thiswep.wr_checkammo2(thiswep)) - if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) - { - W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); - w_ready(thiswep, actor, weaponentity, fire); - return; - } - - W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, burst_ammo)); - - actor.misc_bulletcounter = WEP_CVAR(machinegun, burst) * -1; - W_MachineGun_Attack_Burst(thiswep, actor, weaponentity, fire); - } - } - else - { - - if(fire & 1) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) - { - actor.misc_bulletcounter = 1; - W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id, weaponentity); // sets attack_finished - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame); - } - - if((fire & 2) && WEP_CVAR(machinegun, first)) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) - { - actor.misc_bulletcounter = 1; - W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id | HITTYPE_SECONDARY, weaponentity); // sets attack_finished - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(machinegun, first_refire), w_ready); - } - } - } - METHOD(MachineGun, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount; - if(WEP_CVAR(machinegun, mode) == 1) - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, sustained_ammo); - else - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, first_ammo); - - if(WEP_CVAR(machinegun, reload_ammo)) - { - if(WEP_CVAR(machinegun, mode) == 1) - ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, sustained_ammo); - else - ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo); - } - return ammo_amount; - } - METHOD(MachineGun, wr_checkammo2, bool(entity thiswep)) - { - float ammo_amount; - if(WEP_CVAR(machinegun, mode) == 1) - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, burst_ammo); - else - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, first_ammo); - - if(WEP_CVAR(machinegun, reload_ammo)) - { - if(WEP_CVAR(machinegun, mode) == 1) - ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, burst_ammo); - else - ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo); - } - return ammo_amount; - } - METHOD(MachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo)), SND(RELOAD)); - } - METHOD(MachineGun, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_THINKING_WITH_PORTALS; - } - METHOD(MachineGun, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_MACHINEGUN_MURDER_SNIPE; - else - return WEAPON_MACHINEGUN_MURDER_SPRAY; - } +METHOD(MachineGun, wr_aim, void(entity thiswep)) +{ + if(vdist(self.origin - self.enemy.origin, <, 3000 - bound(0, skill, 10) * 200)) + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false); + else + PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false); +} +METHOD(MachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(WEP_CVAR(machinegun, reload_ammo) && actor.clip_load < min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else + if(WEP_CVAR(machinegun, mode) == 1) + { + if(fire & 1) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) + { + actor.misc_bulletcounter = 0; + W_MachineGun_Attack_Auto(thiswep, actor, weaponentity, fire); + } + + if(fire & 2) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) + { + if(!thiswep.wr_checkammo2(thiswep)) + if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) + { + W_SwitchWeapon_Force(actor, w_getbestweapon(actor)); + w_ready(thiswep, actor, weaponentity, fire); + return; + } + + W_DecreaseAmmo(thiswep, actor, WEP_CVAR(machinegun, burst_ammo)); + + actor.misc_bulletcounter = WEP_CVAR(machinegun, burst) * -1; + W_MachineGun_Attack_Burst(thiswep, actor, weaponentity, fire); + } + } + else + { + + if(fire & 1) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, 0)) + { + actor.misc_bulletcounter = 1; + W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id, weaponentity); // sets attack_finished + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), W_MachineGun_Attack_Frame); + } + + if((fire & 2) && WEP_CVAR(machinegun, first)) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0)) + { + actor.misc_bulletcounter = 1; + W_MachineGun_Attack(WEP_MACHINEGUN, WEP_MACHINEGUN.m_id | HITTYPE_SECONDARY, weaponentity); // sets attack_finished + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(machinegun, first_refire), w_ready); + } + } +} +METHOD(MachineGun, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount; + if(WEP_CVAR(machinegun, mode) == 1) + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, sustained_ammo); + else + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, first_ammo); + + if(WEP_CVAR(machinegun, reload_ammo)) + { + if(WEP_CVAR(machinegun, mode) == 1) + ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, sustained_ammo); + else + ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo); + } + return ammo_amount; +} +METHOD(MachineGun, wr_checkammo2, bool(entity thiswep)) +{ + float ammo_amount; + if(WEP_CVAR(machinegun, mode) == 1) + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, burst_ammo); + else + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(machinegun, first_ammo); + + if(WEP_CVAR(machinegun, reload_ammo)) + { + if(WEP_CVAR(machinegun, mode) == 1) + ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, burst_ammo); + else + ammo_amount += self.(weapon_load[WEP_MACHINEGUN.m_id]) >= WEP_CVAR(machinegun, first_ammo); + } + return ammo_amount; +} +METHOD(MachineGun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo)), SND(RELOAD)); +} +METHOD(MachineGun, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_THINKING_WITH_PORTALS; +} +METHOD(MachineGun, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_MACHINEGUN_MURDER_SNIPE; + else + return WEAPON_MACHINEGUN_MURDER_SPRAY; +} #endif #ifdef CSQC - METHOD(MachineGun, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_MACHINEGUN_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTN_NORM); - } +METHOD(MachineGun, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_MACHINEGUN_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTN_NORM); +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/minelayer.qc b/qcsrc/common/weapons/weapon/minelayer.qc index e5c43f3a4..78aabc451 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qc +++ b/qcsrc/common/weapons/weapon/minelayer.qc @@ -404,175 +404,175 @@ float W_MineLayer_PlacedMines(float detonate) return minfound; } - METHOD(MineLayer, wr_aim, void(entity thiswep)) - { - // aim and decide to fire if appropriate - if(self.minelayer_mines >= WEP_CVAR(minelayer, limit)) - self.BUTTON_ATCK = false; - else - self.BUTTON_ATCK = bot_aim(WEP_CVAR(minelayer, speed), 0, WEP_CVAR(minelayer, lifetime), false); - if(skill >= 2) // skill 0 and 1 bots won't detonate mines! - { - // decide whether to detonate mines - entity targetlist, targ; - float edgedamage, coredamage, edgeradius, recipricoledgeradius, d; - float selfdamage, teamdamage, enemydamage; - edgedamage = WEP_CVAR(minelayer, edgedamage); - coredamage = WEP_CVAR(minelayer, damage); - edgeradius = WEP_CVAR(minelayer, radius); - recipricoledgeradius = 1 / edgeradius; - selfdamage = 0; - teamdamage = 0; - enemydamage = 0; - targetlist = findchainfloat(bot_attack, true); - entity mine = find(world, classname, "mine"); - while(mine) - { - if(mine.realowner != self) - { - mine = find(mine, classname, "mine"); - continue; - } - targ = targetlist; - while(targ) - { - d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - mine.origin); - d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000); - // count potential damage according to type of target - if(targ == self) - selfdamage = selfdamage + d; - else if(targ.team == self.team && teamplay) - teamdamage = teamdamage + d; - else if(bot_shouldattack(targ)) - enemydamage = enemydamage + d; - targ = targ.chain; - } - mine = find(mine, classname, "mine"); - } - float desirabledamage; - desirabledamage = enemydamage; - if(time > self.invincible_finished && time > self.spawnshieldtime) - desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent; - if(teamplay && self.team) - desirabledamage = desirabledamage - teamdamage; - - mine = find(world, classname, "mine"); - while(mine) - { - if(mine.realowner != self) - { - mine = find(mine, classname, "mine"); - continue; - } - makevectors(mine.v_angle); - targ = targetlist; - if(skill > 9) // normal players only do this for the target they are tracking - { - targ = targetlist; - while(targ) - { - if( - (v_forward * normalize(mine.origin - targ.origin)< 0.1) - && desirabledamage > 0.1*coredamage - )self.BUTTON_ATCK2 = true; - targ = targ.chain; - } - }else{ - float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000); - //As the distance gets larger, a correct detonation gets near imposible - //Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player - if(v_forward * normalize(mine.origin - self.enemy.origin)< 0.1) - if(IS_PLAYER(self.enemy)) - if(desirabledamage >= 0.1*coredamage) - if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1)) - self.BUTTON_ATCK2 = true; - // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n"); - } - - mine = find(mine, classname, "mine"); - } - // if we would be doing at X percent of the core damage, detonate it - // but don't fire a new shot at the same time! - if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events - self.BUTTON_ATCK2 = true; - if((skill > 6.5) && (selfdamage > self.health)) - self.BUTTON_ATCK2 = false; - //if(self.BUTTON_ATCK2 == true) - // dprint(ftos(desirabledamage),"\n"); - if(self.BUTTON_ATCK2 == true) self.BUTTON_ATCK = false; - } - } - METHOD(MineLayer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(autocvar_g_balance_minelayer_reload_ammo && actor.clip_load < WEP_CVAR(minelayer, ammo)) // forced reload - { - // not if we're holding the minelayer without enough ammo, but can detonate existing mines - if(!(W_MineLayer_PlacedMines(false) && actor.(thiswep.ammo_field) < WEP_CVAR(minelayer, ammo))) { - thiswep.wr_reload(thiswep, actor, weaponentity); - } - } - else if(fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(minelayer, refire))) - { - W_MineLayer_Attack(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(minelayer, animtime), w_ready); - } - } - - if(fire & 2) - { - if(W_MineLayer_PlacedMines(true)) - sound(actor, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM); - } - } - METHOD(MineLayer, wr_checkammo1, bool(entity thiswep)) - { - int slot = 0; // TODO: unhardcode - // don't switch while placing a mine - if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_MINE_LAYER) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(minelayer, ammo); - ammo_amount += self.(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo); - return ammo_amount; - } - return true; - } - METHOD(MineLayer, wr_checkammo2, bool(entity thiswep)) - { - if(W_MineLayer_PlacedMines(false)) - return true; - else - return false; - } - METHOD(MineLayer, wr_resetplayers, void(entity thiswep)) - { - self.minelayer_mines = 0; - } - METHOD(MineLayer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, WEP_CVAR(minelayer, ammo), SND(RELOAD)); - } - METHOD(MineLayer, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_MINELAYER_SUICIDE; - } - METHOD(MineLayer, wr_killmessage, int(entity thiswep)) - { - return WEAPON_MINELAYER_MURDER; - } +METHOD(MineLayer, wr_aim, void(entity thiswep)) +{ + // aim and decide to fire if appropriate + if(self.minelayer_mines >= WEP_CVAR(minelayer, limit)) + PHYS_INPUT_BUTTON_ATCK(self) = false; + else + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(minelayer, speed), 0, WEP_CVAR(minelayer, lifetime), false); + if(skill >= 2) // skill 0 and 1 bots won't detonate mines! + { + // decide whether to detonate mines + entity targetlist, targ; + float edgedamage, coredamage, edgeradius, recipricoledgeradius, d; + float selfdamage, teamdamage, enemydamage; + edgedamage = WEP_CVAR(minelayer, edgedamage); + coredamage = WEP_CVAR(minelayer, damage); + edgeradius = WEP_CVAR(minelayer, radius); + recipricoledgeradius = 1 / edgeradius; + selfdamage = 0; + teamdamage = 0; + enemydamage = 0; + targetlist = findchainfloat(bot_attack, true); + entity mine = find(world, classname, "mine"); + while(mine) + { + if(mine.realowner != self) + { + mine = find(mine, classname, "mine"); + continue; + } + targ = targetlist; + while(targ) + { + d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - mine.origin); + d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000); + // count potential damage according to type of target + if(targ == self) + selfdamage = selfdamage + d; + else if(targ.team == self.team && teamplay) + teamdamage = teamdamage + d; + else if(bot_shouldattack(targ)) + enemydamage = enemydamage + d; + targ = targ.chain; + } + mine = find(mine, classname, "mine"); + } + float desirabledamage; + desirabledamage = enemydamage; + if(time > self.invincible_finished && time > self.spawnshieldtime) + desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent; + if(teamplay && self.team) + desirabledamage = desirabledamage - teamdamage; + + mine = find(world, classname, "mine"); + while(mine) + { + if(mine.realowner != self) + { + mine = find(mine, classname, "mine"); + continue; + } + makevectors(mine.v_angle); + targ = targetlist; + if(skill > 9) // normal players only do this for the target they are tracking + { + targ = targetlist; + while(targ) + { + if( + (v_forward * normalize(mine.origin - targ.origin)< 0.1) + && desirabledamage > 0.1*coredamage + ) PHYS_INPUT_BUTTON_ATCK2(self) = true; + targ = targ.chain; + } + }else{ + float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000); + //As the distance gets larger, a correct detonation gets near imposible + //Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player + if(v_forward * normalize(mine.origin - self.enemy.origin)< 0.1) + if(IS_PLAYER(self.enemy)) + if(desirabledamage >= 0.1*coredamage) + if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1)) + PHYS_INPUT_BUTTON_ATCK2(self) = true; + // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n"); + } + + mine = find(mine, classname, "mine"); + } + // if we would be doing at X percent of the core damage, detonate it + // but don't fire a new shot at the same time! + if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events + PHYS_INPUT_BUTTON_ATCK2(self) = true; + if((skill > 6.5) && (selfdamage > self.health)) + PHYS_INPUT_BUTTON_ATCK2(self) = false; + //if(PHYS_INPUT_BUTTON_ATCK2(self) == true) + // dprint(ftos(desirabledamage),"\n"); + if(PHYS_INPUT_BUTTON_ATCK2(self)) PHYS_INPUT_BUTTON_ATCK(self) = false; + } +} +METHOD(MineLayer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(autocvar_g_balance_minelayer_reload_ammo && actor.clip_load < WEP_CVAR(minelayer, ammo)) // forced reload + { + // not if we're holding the minelayer without enough ammo, but can detonate existing mines + if(!(W_MineLayer_PlacedMines(false) && actor.(thiswep.ammo_field) < WEP_CVAR(minelayer, ammo))) { + thiswep.wr_reload(thiswep, actor, weaponentity); + } + } + else if(fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(minelayer, refire))) + { + W_MineLayer_Attack(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(minelayer, animtime), w_ready); + } + } + + if(fire & 2) + { + if(W_MineLayer_PlacedMines(true)) + sound(actor, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM); + } +} +METHOD(MineLayer, wr_checkammo1, bool(entity thiswep)) +{ + int slot = 0; // TODO: unhardcode + // don't switch while placing a mine + if(ATTACK_FINISHED(self, slot) <= time || PS(self).m_weapon != WEP_MINE_LAYER) + { + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(minelayer, ammo); + ammo_amount += self.(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo); + return ammo_amount; + } + return true; +} +METHOD(MineLayer, wr_checkammo2, bool(entity thiswep)) +{ + if(W_MineLayer_PlacedMines(false)) + return true; + else + return false; +} +METHOD(MineLayer, wr_resetplayers, void(entity thiswep)) +{ + self.minelayer_mines = 0; +} +METHOD(MineLayer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, WEP_CVAR(minelayer, ammo), SND(RELOAD)); +} +METHOD(MineLayer, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_MINELAYER_SUICIDE; +} +METHOD(MineLayer, wr_killmessage, Notification(entity thiswep)) +{ + return WEAPON_MINELAYER_MURDER; +} #endif #ifdef CSQC - METHOD(MineLayer, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 12; - pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_MINE_EXP, VOL_BASE, ATTN_NORM); - } +METHOD(MineLayer, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 12; + pointparticles(EFFECT_ROCKET_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_MINE_EXP, VOL_BASE, ATTN_NORM); +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/mortar.qc b/qcsrc/common/weapons/weapon/mortar.qc index b361a5050..639de3f4c 100644 --- a/qcsrc/common/weapons/weapon/mortar.qc +++ b/qcsrc/common/weapons/weapon/mortar.qc @@ -298,121 +298,121 @@ void W_Mortar_Attack2(Weapon thiswep) .float bot_secondary_grenademooth; - METHOD(Mortar, wr_aim, void(entity thiswep)) - { - self.BUTTON_ATCK = false; - self.BUTTON_ATCK2 = false; - if(self.bot_secondary_grenademooth == 0) // WEAPONTODO: merge this into using WEP_CVAR_BOTH - { - if(bot_aim(WEP_CVAR_PRI(mortar, speed), WEP_CVAR_PRI(mortar, speed_up), WEP_CVAR_PRI(mortar, lifetime), true)) - { - self.BUTTON_ATCK = true; - if(random() < 0.01) self.bot_secondary_grenademooth = 1; - } - } - else - { - if(bot_aim(WEP_CVAR_SEC(mortar, speed), WEP_CVAR_SEC(mortar, speed_up), WEP_CVAR_SEC(mortar, lifetime), true)) - { - self.BUTTON_ATCK2 = true; - if(random() < 0.02) self.bot_secondary_grenademooth = 0; - } - } - } - /*case WR_CALCINFO: - { - wepinfo_pri_refire = max3(sys_frametime, WEP_CVAR_PRI(mortar, refire), WEP_CVAR_PRI(mortar, animtime)); - wepinfo_pri_dps = (WEP_CVAR_PRI(mortar, damage) * (1 / wepinfo_pri_refire)); - wepinfo_pri_speed = (1 / max(1, (10000 / max(1, WEP_CVAR_PRI(mortar, speed))))); - - // for the range calculation, closer to 1 is better - wepinfo_pri_range_max = 2000 * wepinfo_pri_speed; - wepinfo_pri_range = wepinfo_pri_speed * WEP_CVAR_PRI(mortar, - - wepinfo_sec_refire = max3(sys_frametime, WEP_CVAR_SEC(mortar, refire), WEP_CVAR_SEC(mortar, animtime)); - wepinfo_sec_dps = (WEP_CVAR_SEC(mortar, damage) * (1 / wepinfo_sec_refire)); - - wepinfo_sec_dps = (WEP_CVAR_SEC(mortar, damage) * (1 / max3(sys_frametime, WEP_CVAR_SEC(mortar, refire), WEP_CVAR_SEC(mortar, animtime)))); - wepinfo_ter_dps = 0; - */ - METHOD(Mortar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(autocvar_g_balance_mortar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else if(fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(mortar, refire))) - { - W_Mortar_Attack(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(mortar, animtime), w_ready); - } - } - else if(fire & 2) - { - if(WEP_CVAR_SEC(mortar, remote_detonateprimary)) - { - bool nadefound = false; - entity nade; - for(nade = world; (nade = find(nade, classname, "grenade")); ) if(nade.realowner == actor) - { - if(!nade.gl_detonate_later) - { - nade.gl_detonate_later = true; - nadefound = true; - } - } - if(nadefound) - sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM); - } - else if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(mortar, refire))) - { - W_Mortar_Attack2(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(mortar, animtime), w_ready); - } - } - } - METHOD(Mortar, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(mortar, ammo); - ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_PRI(mortar, ammo); - return ammo_amount; - } - METHOD(Mortar, wr_checkammo2, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(mortar, ammo); - ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_SEC(mortar, ammo); - return ammo_amount; - } - METHOD(Mortar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo)), SND(RELOAD)); // WEAPONTODO - } - METHOD(Mortar, wr_suicidemessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_MORTAR_SUICIDE_BOUNCE; - else - return WEAPON_MORTAR_SUICIDE_EXPLODE; - } - METHOD(Mortar, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_MORTAR_MURDER_BOUNCE; - else - return WEAPON_MORTAR_MURDER_EXPLODE; - } +METHOD(Mortar, wr_aim, void(entity thiswep)) +{ + PHYS_INPUT_BUTTON_ATCK(self) = false; + PHYS_INPUT_BUTTON_ATCK2(self) = false; + if(self.bot_secondary_grenademooth == 0) // WEAPONTODO: merge this into using WEP_CVAR_BOTH + { + if(bot_aim(WEP_CVAR_PRI(mortar, speed), WEP_CVAR_PRI(mortar, speed_up), WEP_CVAR_PRI(mortar, lifetime), true)) + { + PHYS_INPUT_BUTTON_ATCK(self) = true; + if(random() < 0.01) self.bot_secondary_grenademooth = 1; + } + } + else + { + if(bot_aim(WEP_CVAR_SEC(mortar, speed), WEP_CVAR_SEC(mortar, speed_up), WEP_CVAR_SEC(mortar, lifetime), true)) + { + PHYS_INPUT_BUTTON_ATCK2(self) = true; + if(random() < 0.02) self.bot_secondary_grenademooth = 0; + } + } +} +/*case WR_CALCINFO: +{ + wepinfo_pri_refire = max3(sys_frametime, WEP_CVAR_PRI(mortar, refire), WEP_CVAR_PRI(mortar, animtime)); + wepinfo_pri_dps = (WEP_CVAR_PRI(mortar, damage) * (1 / wepinfo_pri_refire)); + wepinfo_pri_speed = (1 / max(1, (10000 / max(1, WEP_CVAR_PRI(mortar, speed))))); + + // for the range calculation, closer to 1 is better + wepinfo_pri_range_max = 2000 * wepinfo_pri_speed; + wepinfo_pri_range = wepinfo_pri_speed * WEP_CVAR_PRI(mortar, + + wepinfo_sec_refire = max3(sys_frametime, WEP_CVAR_SEC(mortar, refire), WEP_CVAR_SEC(mortar, animtime)); + wepinfo_sec_dps = (WEP_CVAR_SEC(mortar, damage) * (1 / wepinfo_sec_refire)); + + wepinfo_sec_dps = (WEP_CVAR_SEC(mortar, damage) * (1 / max3(sys_frametime, WEP_CVAR_SEC(mortar, refire), WEP_CVAR_SEC(mortar, animtime)))); + wepinfo_ter_dps = 0; + */ +METHOD(Mortar, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(autocvar_g_balance_mortar_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else if(fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(mortar, refire))) + { + W_Mortar_Attack(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(mortar, animtime), w_ready); + } + } + else if(fire & 2) + { + if(WEP_CVAR_SEC(mortar, remote_detonateprimary)) + { + bool nadefound = false; + entity nade; + for(nade = world; (nade = find(nade, classname, "grenade")); ) if(nade.realowner == actor) + { + if(!nade.gl_detonate_later) + { + nade.gl_detonate_later = true; + nadefound = true; + } + } + if(nadefound) + sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM); + } + else if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(mortar, refire))) + { + W_Mortar_Attack2(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(mortar, animtime), w_ready); + } + } +} +METHOD(Mortar, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(mortar, ammo); + ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_PRI(mortar, ammo); + return ammo_amount; +} +METHOD(Mortar, wr_checkammo2, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(mortar, ammo); + ammo_amount += self.(weapon_load[WEP_MORTAR.m_id]) >= WEP_CVAR_SEC(mortar, ammo); + return ammo_amount; +} +METHOD(Mortar, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo)), SND(RELOAD)); // WEAPONTODO +} +METHOD(Mortar, wr_suicidemessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_MORTAR_SUICIDE_BOUNCE; + else + return WEAPON_MORTAR_SUICIDE_EXPLODE; +} +METHOD(Mortar, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_MORTAR_MURDER_BOUNCE; + else + return WEAPON_MORTAR_MURDER_EXPLODE; +} #endif #ifdef CSQC - METHOD(Mortar, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 12; - pointparticles(EFFECT_GRENADE_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_GRENADE_IMPACT, VOL_BASE, ATTN_NORM); - } +METHOD(Mortar, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 12; + pointparticles(EFFECT_GRENADE_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_GRENADE_IMPACT, VOL_BASE, ATTN_NORM); +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/porto.qc b/qcsrc/common/weapons/weapon/porto.qc index 56b2759ec..0e667419d 100644 --- a/qcsrc/common/weapons/weapon/porto.qc +++ b/qcsrc/common/weapons/weapon/porto.qc @@ -50,7 +50,7 @@ spawnfunc(weapon_porto) { weapon_defaultspawnfunc(this, WEP_PORTO); } REGISTER_MUTATOR(porto_ticker, true); MUTATOR_HOOKFUNCTION(porto_ticker, SV_StartFrame) { - FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(it.porto_forbidden = max(0, it.porto_forbidden - 1))); + FOREACH_CLIENT(IS_PLAYER(it), it.porto_forbidden = max(0, it.porto_forbidden - 1)); } void W_Porto_Success() @@ -292,95 +292,95 @@ void W_Porto_Attack(float type) MUTATOR_CALLHOOK(EditProjectile, self, gren); } - METHOD(PortoLaunch, wr_aim, void(entity thiswep)) - { - SELFPARAM(); - self.BUTTON_ATCK = false; - self.BUTTON_ATCK2 = false; - if(!WEP_CVAR(porto, secondary)) - if(bot_aim(WEP_CVAR_PRI(porto, speed), 0, WEP_CVAR_PRI(porto, lifetime), false)) - self.BUTTON_ATCK = true; - } - METHOD(PortoLaunch, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(WEP_CVAR(porto, secondary)) - { - if(fire & 1) - if(!actor.porto_current) - if(!actor.porto_forbidden) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(porto, refire))) - { - W_Porto_Attack(0); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); - } - - if(fire & 2) - if(!actor.porto_current) - if(!actor.porto_forbidden) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(porto, refire))) - { - W_Porto_Attack(1); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(porto, animtime), w_ready); - } - } - else - { - if(actor.porto_v_angle_held) - { - if(!(fire & 2)) - { - actor.porto_v_angle_held = 0; - - ClientData_Touch(actor); - } - } - else - { - if(fire & 2) - { - actor.porto_v_angle = actor.v_angle; - actor.porto_v_angle_held = 1; - - ClientData_Touch(actor); - } - } - if(actor.porto_v_angle_held) - makevectors(actor.porto_v_angle); // override the previously set angles - - if(fire & 1) - if(!actor.porto_current) - if(!actor.porto_forbidden) - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(porto, refire))) - { - W_Porto_Attack(-1); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); - } - } - } - METHOD(PortoLaunch, wr_checkammo1, bool(entity this)) - { - // always allow infinite ammo - return true; - } - METHOD(PortoLaunch, wr_checkammo2, bool(entity this)) - { - // always allow infinite ammo - return true; - } - METHOD(PortoLaunch, wr_setup, void(entity thiswep)) - { - SELFPARAM(); - self.ammo_field = ammo_none; - } - METHOD(PortoLaunch, wr_resetplayer, void(entity thiswep)) - { - SELFPARAM(); - self.porto_current = world; - } +METHOD(PortoLaunch, wr_aim, void(entity thiswep)) +{ + SELFPARAM(); + PHYS_INPUT_BUTTON_ATCK(self) = false; + PHYS_INPUT_BUTTON_ATCK2(self) = false; + if(!WEP_CVAR(porto, secondary)) + if(bot_aim(WEP_CVAR_PRI(porto, speed), 0, WEP_CVAR_PRI(porto, lifetime), false)) + PHYS_INPUT_BUTTON_ATCK(self) = true; +} +METHOD(PortoLaunch, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(WEP_CVAR(porto, secondary)) + { + if(fire & 1) + if(!actor.porto_current) + if(!actor.porto_forbidden) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(porto, refire))) + { + W_Porto_Attack(0); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); + } + + if(fire & 2) + if(!actor.porto_current) + if(!actor.porto_forbidden) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(porto, refire))) + { + W_Porto_Attack(1); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(porto, animtime), w_ready); + } + } + else + { + if(actor.porto_v_angle_held) + { + if(!(fire & 2)) + { + actor.porto_v_angle_held = 0; + + ClientData_Touch(actor); + } + } + else + { + if(fire & 2) + { + actor.porto_v_angle = actor.v_angle; + actor.porto_v_angle_held = 1; + + ClientData_Touch(actor); + } + } + if(actor.porto_v_angle_held) + makevectors(actor.porto_v_angle); // override the previously set angles + + if(fire & 1) + if(!actor.porto_current) + if(!actor.porto_forbidden) + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(porto, refire))) + { + W_Porto_Attack(-1); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(porto, animtime), w_ready); + } + } +} +METHOD(PortoLaunch, wr_checkammo1, bool(entity this)) +{ + // always allow infinite ammo + return true; +} +METHOD(PortoLaunch, wr_checkammo2, bool(entity this)) +{ + // always allow infinite ammo + return true; +} +METHOD(PortoLaunch, wr_setup, void(entity thiswep)) +{ + SELFPARAM(); + self.ammo_field = ammo_none; +} +METHOD(PortoLaunch, wr_resetplayer, void(entity thiswep)) +{ + SELFPARAM(); + self.porto_current = world; +} #endif #ifdef CSQC - METHOD(PortoLaunch, wr_impacteffect, void(entity this)) { - LOG_WARNING("Since when does Porto send DamageInfo?\n"); - } +METHOD(PortoLaunch, wr_impacteffect, void(entity this)) { + LOG_WARNING("Since when does Porto send DamageInfo?\n"); +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/rifle.qc b/qcsrc/common/weapons/weapon/rifle.qc index 526ba0e20..c0734d77d 100644 --- a/qcsrc/common/weapons/weapon/rifle.qc +++ b/qcsrc/common/weapons/weapon/rifle.qc @@ -66,7 +66,7 @@ void W_Rifle_FireBullet(Weapon thiswep, float pSpread, float pDamage, float pFor Send_Effect(EFFECT_RIFLE_MUZZLEFLASH, w_shotorg, w_shotdir * 2000, 1); - if(self.BUTTON_ZOOM | self.BUTTON_ZOOMSCRIPT) // if zoomed, shoot from the eye + if(PHYS_INPUT_BUTTON_ZOOM(self) | PHYS_INPUT_BUTTON_ZOOMSCRIPT(self)) // if zoomed, shoot from the eye { w_shotdir = v_forward; w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward; @@ -138,139 +138,139 @@ void W_Rifle_BulletHail(.entity weaponentity, float mode, void() AttackFunc, WFR .float bot_secondary_riflemooth; - METHOD(Rifle, wr_aim, void(entity thiswep)) - { - self.BUTTON_ATCK=false; - self.BUTTON_ATCK2=false; - if(vdist(self.origin - self.enemy.origin, >, 1000)) - self.bot_secondary_riflemooth = 0; - if(self.bot_secondary_riflemooth == 0) - { - if(bot_aim(1000000, 0, 0.001, false)) - { - self.BUTTON_ATCK = true; - if(random() < 0.01) self.bot_secondary_riflemooth = 1; - } - } - else - { - if(bot_aim(1000000, 0, 0.001, false)) - { - self.BUTTON_ATCK2 = true; - if(random() < 0.03) self.bot_secondary_riflemooth = 0; - } - } - } - METHOD(Rifle, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(autocvar_g_balance_rifle_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else - { - actor.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.rifle_accumulator, time); - if(fire & 1) - if(weapon_prepareattack_check(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire))) - if(time >= actor.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost)) - { - weapon_prepareattack_do(actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire)); - W_Rifle_BulletHail(weaponentity, WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire)); - actor.rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost); - } - if(fire & 2) - { - if(WEP_CVAR(rifle, secondary)) - { - if(WEP_CVAR_SEC(rifle, reload)) { - thiswep.wr_reload(thiswep, actor, weaponentity); - } else - { - if(weapon_prepareattack_check(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire))) - if(time >= actor.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost)) - { - weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire)); - W_Rifle_BulletHail(weaponentity, WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire)); - actor.rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost); - } - } - } - } - } - } - METHOD(Rifle, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(rifle, ammo); - ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo); - return ammo_amount; - } - METHOD(Rifle, wr_checkammo2, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(rifle, ammo); - ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo); - return ammo_amount; - } - METHOD(Rifle, wr_resetplayer, void(entity thiswep)) - { - self.rifle_accumulator = time - WEP_CVAR(rifle, bursttime); - } - METHOD(Rifle, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), SND(RELOAD)); - } - METHOD(Rifle, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_THINKING_WITH_PORTALS; - } - METHOD(Rifle, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - { - if(w_deathtype & HITTYPE_BOUNCE) - return WEAPON_RIFLE_MURDER_HAIL_PIERCING; - else - return WEAPON_RIFLE_MURDER_HAIL; - } - else - { - if(w_deathtype & HITTYPE_BOUNCE) - return WEAPON_RIFLE_MURDER_PIERCING; - else - return WEAPON_RIFLE_MURDER; - } - } +METHOD(Rifle, wr_aim, void(entity thiswep)) +{ + PHYS_INPUT_BUTTON_ATCK(self) = false; + PHYS_INPUT_BUTTON_ATCK2(self) = false; + if(vdist(self.origin - self.enemy.origin, >, 1000)) + self.bot_secondary_riflemooth = 0; + if(self.bot_secondary_riflemooth == 0) + { + if(bot_aim(1000000, 0, 0.001, false)) + { + PHYS_INPUT_BUTTON_ATCK(self) = true; + if(random() < 0.01) self.bot_secondary_riflemooth = 1; + } + } + else + { + if(bot_aim(1000000, 0, 0.001, false)) + { + PHYS_INPUT_BUTTON_ATCK2(self) = true; + if(random() < 0.03) self.bot_secondary_riflemooth = 0; + } + } +} +METHOD(Rifle, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(autocvar_g_balance_rifle_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else + { + actor.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.rifle_accumulator, time); + if(fire & 1) + if(weapon_prepareattack_check(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire))) + if(time >= actor.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost)) + { + weapon_prepareattack_do(actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire)); + W_Rifle_BulletHail(weaponentity, WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire)); + actor.rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost); + } + if(fire & 2) + { + if(WEP_CVAR(rifle, secondary)) + { + if(WEP_CVAR_SEC(rifle, reload)) { + thiswep.wr_reload(thiswep, actor, weaponentity); + } else + { + if(weapon_prepareattack_check(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire))) + if(time >= actor.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost)) + { + weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire)); + W_Rifle_BulletHail(weaponentity, WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire)); + actor.rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost); + } + } + } + } + } +} +METHOD(Rifle, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(rifle, ammo); + ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_PRI(rifle, ammo); + return ammo_amount; +} +METHOD(Rifle, wr_checkammo2, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(rifle, ammo); + ammo_amount += self.(weapon_load[WEP_RIFLE.m_id]) >= WEP_CVAR_SEC(rifle, ammo); + return ammo_amount; +} +METHOD(Rifle, wr_resetplayer, void(entity thiswep)) +{ + self.rifle_accumulator = time - WEP_CVAR(rifle, bursttime); +} +METHOD(Rifle, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), SND(RELOAD)); +} +METHOD(Rifle, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_THINKING_WITH_PORTALS; +} +METHOD(Rifle, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + { + if(w_deathtype & HITTYPE_BOUNCE) + return WEAPON_RIFLE_MURDER_HAIL_PIERCING; + else + return WEAPON_RIFLE_MURDER_HAIL; + } + else + { + if(w_deathtype & HITTYPE_BOUNCE) + return WEAPON_RIFLE_MURDER_PIERCING; + else + return WEAPON_RIFLE_MURDER; + } +} #endif #ifdef CSQC - METHOD(Rifle, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_RIFLE_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) - { - sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTN_NORM); - } - } - METHOD(Rifle, wr_init, void(entity thiswep)) - { - if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) - { - precache_pic("gfx/reticle_nex"); - } - } - METHOD(Rifle, wr_zoomreticle, bool(entity thiswep)) - { - if(button_zoom || zoomscript_caught) - { - reticle_image = "gfx/reticle_nex"; - return true; - } - else - { - // no weapon specific image for this weapon - return false; - } - } +METHOD(Rifle, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_RIFLE_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) + { + sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTN_NORM); + } +} +METHOD(Rifle, wr_init, void(entity thiswep)) +{ + if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) + { + precache_pic("gfx/reticle_nex"); + } +} +METHOD(Rifle, wr_zoomreticle, bool(entity thiswep)) +{ + if(button_zoom || zoomscript_caught) + { + reticle_image = "gfx/reticle_nex"; + return true; + } + else + { + // no weapon specific image for this weapon + return false; + } +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/seeker.qc b/qcsrc/common/weapons/weapon/seeker.qc index a25e928cb..a20190256 100644 --- a/qcsrc/common/weapons/weapon/seeker.qc +++ b/qcsrc/common/weapons/weapon/seeker.qc @@ -598,148 +598,148 @@ void W_Seeker_Fire_Tag(Weapon thiswep) // Begin: Genereal weapon functions // ============================ - METHOD(Seeker, wr_aim, void(entity thiswep)) - { - if(WEP_CVAR(seeker, type) == 1) - if(W_Seeker_Tagged_Info(self, self.enemy) != world) - self.BUTTON_ATCK = bot_aim(WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false); - else - self.BUTTON_ATCK2 = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false); - else - self.BUTTON_ATCK = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false); - } - METHOD(Seeker, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(autocvar_g_balance_seeker_reload_ammo && actor.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else if(fire & 1) - { - if(WEP_CVAR(seeker, type) == 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, missile_refire))) - { - W_Seeker_Attack(); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, missile_animtime), w_ready); - } - } - else - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire))) - { - W_Seeker_Fire_Tag(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); - } - } - } - - else if(fire & 2) - { - if(WEP_CVAR(seeker, type) == 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire))) - { - W_Seeker_Fire_Tag(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); - } - } - else - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, flac_refire))) - { - W_Seeker_Fire_Flac(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, flac_animtime), w_ready); - } - } - } - } - METHOD(Seeker, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount; - if(WEP_CVAR(seeker, type) == 1) - { - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, missile_ammo); - ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, missile_ammo); - } - else - { - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo); - ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo); - } - return ammo_amount; - } - METHOD(Seeker, wr_checkammo2, bool(entity thiswep)) - { - float ammo_amount; - if(WEP_CVAR(seeker, type) == 1) - { - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo); - ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo); - } - else - { - ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, flac_ammo); - ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, flac_ammo); - } - return ammo_amount; - } - METHOD(Seeker, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), SND(RELOAD)); - } - METHOD(Seeker, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_SEEKER_SUICIDE; - } - METHOD(Seeker, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_SEEKER_MURDER_TAG; - else - return WEAPON_SEEKER_MURDER_SPRAY; - } +METHOD(Seeker, wr_aim, void(entity thiswep)) +{ + if(WEP_CVAR(seeker, type) == 1) + if(W_Seeker_Tagged_Info(self, self.enemy) != world) + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false); + else + PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false); + else + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false); +} +METHOD(Seeker, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(autocvar_g_balance_seeker_reload_ammo && actor.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else if(fire & 1) + { + if(WEP_CVAR(seeker, type) == 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, missile_refire))) + { + W_Seeker_Attack(); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, missile_animtime), w_ready); + } + } + else + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire))) + { + W_Seeker_Fire_Tag(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); + } + } + } + + else if(fire & 2) + { + if(WEP_CVAR(seeker, type) == 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire))) + { + W_Seeker_Fire_Tag(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); + } + } + else + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, flac_refire))) + { + W_Seeker_Fire_Flac(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, flac_animtime), w_ready); + } + } + } +} +METHOD(Seeker, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount; + if(WEP_CVAR(seeker, type) == 1) + { + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, missile_ammo); + ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, missile_ammo); + } + else + { + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo); + ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo); + } + return ammo_amount; +} +METHOD(Seeker, wr_checkammo2, bool(entity thiswep)) +{ + float ammo_amount; + if(WEP_CVAR(seeker, type) == 1) + { + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo); + ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo); + } + else + { + ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR(seeker, flac_ammo); + ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, flac_ammo); + } + return ammo_amount; +} +METHOD(Seeker, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), SND(RELOAD)); +} +METHOD(Seeker, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_SEEKER_SUICIDE; +} +METHOD(Seeker, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_SEEKER_MURDER_TAG; + else + return WEAPON_SEEKER_MURDER_SPRAY; +} #endif #ifdef CSQC - METHOD(Seeker, wr_impacteffect, void(entity thiswep)) - { - vector org2; - org2 = w_org + w_backoff * 6; - if(w_deathtype & HITTYPE_BOUNCE) - { - if(w_deathtype & HITTYPE_SECONDARY) - { - if(!w_issilent) - sound(self, CH_SHOTS, SND_TAG_IMPACT, 1, ATTEN_NORM); - } - else - { - pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - { - if(w_random<0.15) - sound(self, CH_SHOTS, SND_TAGEXP1, 1, ATTEN_NORM); - else if(w_random<0.7) - sound(self, CH_SHOTS, SND_TAGEXP2, 1, ATTEN_NORM); - else - sound(self, CH_SHOTS, SND_TAGEXP3, 1, ATTEN_NORM); - } - } - } - else - { - pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); - if(!w_issilent) - { - if(w_random<0.15) - sound(self, CH_SHOTS, SND_SEEKEREXP1, 1, ATTEN_NORM); - else if(w_random<0.7) - sound(self, CH_SHOTS, SND_SEEKEREXP2, 1, ATTEN_NORM); - else - sound(self, CH_SHOTS, SND_SEEKEREXP3, 1, ATTEN_NORM); - } - } - } +METHOD(Seeker, wr_impacteffect, void(entity thiswep)) +{ + vector org2; + org2 = w_org + w_backoff * 6; + if(w_deathtype & HITTYPE_BOUNCE) + { + if(w_deathtype & HITTYPE_SECONDARY) + { + if(!w_issilent) + sound(self, CH_SHOTS, SND_TAG_IMPACT, 1, ATTEN_NORM); + } + else + { + pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + { + if(w_random<0.15) + sound(self, CH_SHOTS, SND_TAGEXP1, 1, ATTEN_NORM); + else if(w_random<0.7) + sound(self, CH_SHOTS, SND_TAGEXP2, 1, ATTEN_NORM); + else + sound(self, CH_SHOTS, SND_TAGEXP3, 1, ATTEN_NORM); + } + } + } + else + { + pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + { + if(w_random<0.15) + sound(self, CH_SHOTS, SND_SEEKEREXP1, 1, ATTEN_NORM); + else if(w_random<0.7) + sound(self, CH_SHOTS, SND_SEEKEREXP2, 1, ATTEN_NORM); + else + sound(self, CH_SHOTS, SND_SEEKEREXP3, 1, ATTEN_NORM); + } + } +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/shockwave.qc b/qcsrc/common/weapons/weapon/shockwave.qc index 46cb78e0a..6c6e8e736 100644 --- a/qcsrc/common/weapons/weapon/shockwave.qc +++ b/qcsrc/common/weapons/weapon/shockwave.qc @@ -239,8 +239,7 @@ void W_Shockwave_Melee(Weapon thiswep, entity actor, .entity weaponentity, int f sound(actor, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTN_NORM); weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(shockwave, melee_animtime), w_ready); - entity meleetemp = new(meleetemp); - make_pure(meleetemp); + entity meleetemp = new_pure(meleetemp); meleetemp.owner = meleetemp.realowner = actor; meleetemp.think = W_Shockwave_Melee_Think; meleetemp.nextthink = time + WEP_CVAR(shockwave, melee_delay) * W_WeaponRateFactor(); @@ -672,58 +671,58 @@ void W_Shockwave_Attack() } } - METHOD(Shockwave, wr_aim, void(entity thiswep)) - { - if(vlen(self.origin - self.enemy.origin) <= WEP_CVAR(shockwave, melee_range)) - { self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false); } - else - { self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false); } - } - METHOD(Shockwave, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(fire & 1) - { - if(time >= actor.shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(shockwave, blast_animtime))) - { - W_Shockwave_Attack(); - actor.shockwave_blasttime = time + WEP_CVAR(shockwave, blast_refire) * W_WeaponRateFactor(); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(shockwave, blast_animtime), w_ready); - } - } - } - else if(fire & 2) - { - //if(actor.clip_load >= 0) // we are not currently reloading - if(!actor.crouch) // no crouchmelee please - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR(shockwave, melee_refire))) - { - // attempt forcing playback of the anim by switching to another anim (that we never play) here... - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shockwave_Melee); - } - } - } - METHOD(Shockwave, wr_checkammo1, bool(entity thiswep)) - { - return true; // infinite ammo - } - METHOD(Shockwave, wr_checkammo2, bool(entity thiswep)) - { - // shockwave has infinite ammo - return true; - } - METHOD(Shockwave, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_THINKING_WITH_PORTALS; - } - METHOD(Shockwave, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_SHOCKWAVE_MURDER_SLAP; - else - return WEAPON_SHOCKWAVE_MURDER; - } +METHOD(Shockwave, wr_aim, void(entity thiswep)) +{ + if(vlen(self.origin - self.enemy.origin) <= WEP_CVAR(shockwave, melee_range)) + { PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false); } + else + { PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false); } +} +METHOD(Shockwave, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(fire & 1) + { + if(time >= actor.shockwave_blasttime) // handle refire separately so the secondary can be fired straight after a primary + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(shockwave, blast_animtime))) + { + W_Shockwave_Attack(); + actor.shockwave_blasttime = time + WEP_CVAR(shockwave, blast_refire) * W_WeaponRateFactor(); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(shockwave, blast_animtime), w_ready); + } + } + } + else if(fire & 2) + { + //if(actor.clip_load >= 0) // we are not currently reloading + if(!actor.crouch) // no crouchmelee please + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR(shockwave, melee_refire))) + { + // attempt forcing playback of the anim by switching to another anim (that we never play) here... + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shockwave_Melee); + } + } +} +METHOD(Shockwave, wr_checkammo1, bool(entity thiswep)) +{ + return true; // infinite ammo +} +METHOD(Shockwave, wr_checkammo2, bool(entity thiswep)) +{ + // shockwave has infinite ammo + return true; +} +METHOD(Shockwave, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_THINKING_WITH_PORTALS; +} +METHOD(Shockwave, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_SHOCKWAVE_MURDER_SLAP; + else + return WEAPON_SHOCKWAVE_MURDER; +} #endif #ifdef CSQC @@ -853,13 +852,13 @@ void Net_ReadShockwaveParticle() shockwave.sw_time = time; } - METHOD(Shockwave, wr_impacteffect, void(entity thiswep)) - { - // handled by Net_ReadShockwaveParticle - //vector org2; - //org2 = w_org + w_backoff * 2; - //pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); - } +METHOD(Shockwave, wr_impacteffect, void(entity thiswep)) +{ + // handled by Net_ReadShockwaveParticle + //vector org2; + //org2 = w_org + w_backoff * 2; + //pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/shotgun.qc b/qcsrc/common/weapons/weapon/shotgun.qc index 7da7dfd04..234aaadaf 100644 --- a/qcsrc/common/weapons/weapon/shotgun.qc +++ b/qcsrc/common/weapons/weapon/shotgun.qc @@ -188,8 +188,7 @@ void W_Shotgun_Attack2(Weapon thiswep, entity actor, .entity weaponentity, int f sound(actor, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTEN_NORM); weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(shotgun, animtime), w_ready); - entity meleetemp = new(meleetemp); - make_pure(meleetemp); + entity meleetemp = new_pure(meleetemp); meleetemp.realowner = actor; meleetemp.think = W_Shotgun_Melee_Think; meleetemp.nextthink = time + WEP_CVAR_SEC(shotgun, melee_delay) * W_WeaponRateFactor(); @@ -227,117 +226,117 @@ void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity .float shotgun_primarytime; - METHOD(Shotgun, wr_aim, void(entity thiswep)) - { - if(vdist(self.origin - self.enemy.origin, <=, WEP_CVAR_SEC(shotgun, melee_range))) - self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, false); - else - self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, false); - } - METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(WEP_CVAR(shotgun, reload_ammo) && actor.clip_load < WEP_CVAR_PRI(shotgun, ammo)) // forced reload - { - // don't force reload an empty shotgun if its melee attack is active - if(WEP_CVAR(shotgun, secondary) < 2) { - thiswep.wr_reload(thiswep, actor, weaponentity); - } - } - else - { - if(fire & 1) - { - if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(shotgun, animtime))) - { - W_Shotgun_Attack(thiswep, true); - actor.shotgun_primarytime = time + WEP_CVAR_PRI(shotgun, refire) * W_WeaponRateFactor(); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(shotgun, animtime), w_ready); - } - } - } - else if((fire & 2) && WEP_CVAR(shotgun, secondary) == 2) - { - if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(shotgun, alt_animtime))) - { - W_Shotgun_Attack(thiswep, false); - actor.shotgun_primarytime = time + WEP_CVAR_SEC(shotgun, alt_refire) * W_WeaponRateFactor(); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame1); - } - } - } - } - if(actor.clip_load >= 0) // we are not currently reloading - if(!actor.crouch) // no crouchmelee please - if(WEP_CVAR(shotgun, secondary) == 1) - if(((fire & 1) && actor.(thiswep.ammo_field) <= 0 && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (fire & 2)) - if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(shotgun, refire))) - { - // attempt forcing playback of the anim by switching to another anim (that we never play) here... - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shotgun_Attack2); - } - } - METHOD(Shotgun, wr_setup, void(entity thiswep)) - { - self.ammo_field = ammo_none; - } - METHOD(Shotgun, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo); - ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo); - return ammo_amount; - } - METHOD(Shotgun, wr_checkammo2, bool(entity thiswep)) - { - if(IS_BOT_CLIENT(self)) - if(vdist(self.origin - self.enemy.origin, >, WEP_CVAR_SEC(shotgun, melee_range))) - return false; // bots cannot use secondary out of range (fixes constant melee when out of ammo) - switch(WEP_CVAR(shotgun, secondary)) - { - case 1: return true; // melee does not use ammo - case 2: // secondary triple shot - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo); - ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo); - return ammo_amount; - } - default: return false; // secondary unavailable - } - } - METHOD(Shotgun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, WEP_CVAR_PRI(shotgun, ammo), SND(RELOAD)); // WEAPONTODO - } - METHOD(Shotgun, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_THINKING_WITH_PORTALS; - } - METHOD(Shotgun, wr_killmessage, int(entity thiswep)) - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_SHOTGUN_MURDER_SLAP; - else - return WEAPON_SHOTGUN_MURDER; - } +METHOD(Shotgun, wr_aim, void(entity thiswep)) +{ + if(vdist(self.origin - self.enemy.origin, <=, WEP_CVAR_SEC(shotgun, melee_range))) + PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(1000000, 0, 0.001, false); + else + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 0.001, false); +} +METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(WEP_CVAR(shotgun, reload_ammo) && actor.clip_load < WEP_CVAR_PRI(shotgun, ammo)) // forced reload + { + // don't force reload an empty shotgun if its melee attack is active + if(WEP_CVAR(shotgun, secondary) < 2) { + thiswep.wr_reload(thiswep, actor, weaponentity); + } + } + else + { + if(fire & 1) + { + if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(shotgun, animtime))) + { + W_Shotgun_Attack(thiswep, true); + actor.shotgun_primarytime = time + WEP_CVAR_PRI(shotgun, refire) * W_WeaponRateFactor(); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(shotgun, animtime), w_ready); + } + } + } + else if((fire & 2) && WEP_CVAR(shotgun, secondary) == 2) + { + if(time >= actor.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(shotgun, alt_animtime))) + { + W_Shotgun_Attack(thiswep, false); + actor.shotgun_primarytime = time + WEP_CVAR_SEC(shotgun, alt_refire) * W_WeaponRateFactor(); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), W_Shotgun_Attack3_Frame1); + } + } + } + } + if(actor.clip_load >= 0) // we are not currently reloading + if(!actor.crouch) // no crouchmelee please + if(WEP_CVAR(shotgun, secondary) == 1) + if(((fire & 1) && actor.(thiswep.ammo_field) <= 0 && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (fire & 2)) + if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(shotgun, refire))) + { + // attempt forcing playback of the anim by switching to another anim (that we never play) here... + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, W_Shotgun_Attack2); + } +} +METHOD(Shotgun, wr_setup, void(entity thiswep)) +{ + self.ammo_field = ammo_none; +} +METHOD(Shotgun, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo); + ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo); + return ammo_amount; +} +METHOD(Shotgun, wr_checkammo2, bool(entity thiswep)) +{ + if(IS_BOT_CLIENT(self)) + if(vdist(self.origin - self.enemy.origin, >, WEP_CVAR_SEC(shotgun, melee_range))) + return false; // bots cannot use secondary out of range (fixes constant melee when out of ammo) + switch(WEP_CVAR(shotgun, secondary)) + { + case 1: return true; // melee does not use ammo + case 2: // secondary triple shot + { + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(shotgun, ammo); + ammo_amount += self.(weapon_load[WEP_SHOTGUN.m_id]) >= WEP_CVAR_PRI(shotgun, ammo); + return ammo_amount; + } + default: return false; // secondary unavailable + } +} +METHOD(Shotgun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, WEP_CVAR_PRI(shotgun, ammo), SND(RELOAD)); // WEAPONTODO +} +METHOD(Shotgun, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_THINKING_WITH_PORTALS; +} +METHOD(Shotgun, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_SHOTGUN_MURDER_SLAP; + else + return WEAPON_SHOTGUN_MURDER; +} #endif #ifdef CSQC .float prevric; - METHOD(Shotgun, wr_impacteffect, void(entity thiswep)) - { - vector org2 = w_org + w_backoff * 2; - pointparticles(EFFECT_SHOTGUN_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent && time - self.prevric > 0.25) - { - if(w_random < 0.05) - sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_NORM); - self.prevric = time; - } - } +METHOD(Shotgun, wr_impacteffect, void(entity thiswep)) +{ + vector org2 = w_org + w_backoff * 2; + pointparticles(EFFECT_SHOTGUN_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent && time - self.prevric > 0.25) + { + if(w_random < 0.05) + sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_NORM); + self.prevric = time; + } +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/tuba.qc b/qcsrc/common/weapons/weapon/tuba.qc index 0e429acb2..593af8518 100644 --- a/qcsrc/common/weapons/weapon/tuba.qc +++ b/qcsrc/common/weapons/weapon/tuba.qc @@ -213,9 +213,9 @@ int W_Tuba_GetNote(entity pl, int hittype) case 8: note = +4; break; // e case 9: note = -1; break; // B } - if(pl.BUTTON_CROUCH) + if(PHYS_INPUT_BUTTON_CROUCH(pl)) note -= 12; - if(pl.BUTTON_JUMP) + if(PHYS_INPUT_BUTTON_JUMP(pl)) note += 12; if(hittype & HITTYPE_SECONDARY) note += 7; @@ -287,7 +287,7 @@ void W_Tuba_NoteThink() } self.nextthink = time; dist_mult = WEP_CVAR(tuba, attenuation) / autocvar_snd_soundradius; - FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != self.realowner, LAMBDA( + FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != self.realowner, { v = self.origin - (it.origin + it.view_ofs); vol0 = max(0, 1 - vlen(v) * dist_mult); dir0 = normalize(v); @@ -306,7 +306,7 @@ void W_Tuba_NoteThink() self.SendFlags |= 2; break; } - )); + }); } void W_Tuba_NoteOn(float hittype) @@ -367,9 +367,9 @@ METHOD(Tuba, wr_aim, void(Tuba this)) if (vdist((actor.origin - actor.enemy.origin), <, WEP_CVAR(tuba, radius))) { if (random() > 0.5) - actor.BUTTON_ATCK = 1; + PHYS_INPUT_BUTTON_ATCK(actor) = true; else - actor.BUTTON_ATCK2 = 1; + PHYS_INPUT_BUTTON_ATCK2(actor) = true; } } @@ -464,7 +464,7 @@ METHOD(Tuba, wr_reload, void(Tuba this, entity actor, .entity weaponentity)) METHOD(Tuba, wr_checkammo1, bool(Tuba this)) { return true; } METHOD(Tuba, wr_checkammo2, bool(Tuba this)) { return true; } -METHOD(Tuba, wr_suicidemessage, int(Tuba this)) +METHOD(Tuba, wr_suicidemessage, Notification(Tuba this)) { if (w_deathtype & HITTYPE_BOUNCE) return WEAPON_KLEINBOTTLE_SUICIDE; @@ -473,7 +473,7 @@ METHOD(Tuba, wr_suicidemessage, int(Tuba this)) else return WEAPON_TUBA_SUICIDE; } -METHOD(Tuba, wr_killmessage, int(Tuba this)) +METHOD(Tuba, wr_killmessage, Notification(Tuba this)) { if (w_deathtype & HITTYPE_BOUNCE) return WEAPON_KLEINBOTTLE_MURDER; diff --git a/qcsrc/common/weapons/weapon/vaporizer.qc b/qcsrc/common/weapons/weapon/vaporizer.qc index 2ece54932..92c795421 100644 --- a/qcsrc/common/weapons/weapon/vaporizer.qc +++ b/qcsrc/common/weapons/weapon/vaporizer.qc @@ -339,168 +339,168 @@ void W_RocketMinsta_Attack3 () } } - METHOD(Vaporizer, wr_aim, void(entity thiswep)) - { - if(self.(thiswep.ammo_field) > 0) - self.BUTTON_ATCK = bot_aim(1000000, 0, 1, false); - else - self.BUTTON_ATCK2 = bot_aim(WEP_CVAR_SEC(vaporizer, speed), 0, WEP_CVAR_SEC(vaporizer, lifetime), false); // WEAPONTODO: replace with proper vaporizer cvars - } - METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)); - // if the laser uses load, we also consider its ammo for reloading - if(WEP_CVAR(vaporizer, reload_ammo) && WEP_CVAR_SEC(vaporizer, ammo) && actor.clip_load < min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else if(WEP_CVAR(vaporizer, reload_ammo) && actor.clip_load < vaporizer_ammo) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } - if((fire & 1) && (actor.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(actor)) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(vaporizer, refire))) - { - W_Vaporizer_Attack(thiswep); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(vaporizer, animtime), w_ready); - } - } - if((fire & 2) || ((fire & 1) && !actor.ammo_cells && autocvar_g_rm)) - { - if((autocvar_g_rm && autocvar_g_rm_laser) || autocvar_g_rm_laser == 2) - { - bool rapid = autocvar_g_rm_laser_rapid; - if(actor.jump_interval <= time && !actor.held_down) - { - if(rapid) - actor.held_down = true; - actor.jump_interval = time + autocvar_g_rm_laser_refire; - actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_delay; - damage_goodhits = 0; - W_RocketMinsta_Attack2(); - } - else if(rapid && actor.jump_interval2 <= time && actor.held_down) - { - actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_refire; - damage_goodhits = 0; - W_RocketMinsta_Attack3(); - //weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_rm_laser_rapid_animtime, w_ready); - } - } - else if (actor.jump_interval <= time) - { - // handle refire manually, so that primary and secondary can be fired without conflictions (important for instagib) - actor.jump_interval = time + WEP_CVAR_SEC(vaporizer, refire) * W_WeaponRateFactor(); - - // decrease ammo for the laser? - if(WEP_CVAR_SEC(vaporizer, ammo)) - W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(vaporizer, ammo)); - - // ugly instagib hack to reuse the fire mode of the laser - makevectors(actor.v_angle); - Weapon oldwep = PS(actor).m_weapon; // we can't avoid this hack - PS(actor).m_weapon = WEP_BLASTER; - W_Blaster_Attack( - actor, - WEP_BLASTER.m_id | HITTYPE_SECONDARY, - WEP_CVAR_SEC(vaporizer, shotangle), - WEP_CVAR_SEC(vaporizer, damage), - WEP_CVAR_SEC(vaporizer, edgedamage), - WEP_CVAR_SEC(vaporizer, radius), - WEP_CVAR_SEC(vaporizer, force), - WEP_CVAR_SEC(vaporizer, speed), - WEP_CVAR_SEC(vaporizer, spread), - WEP_CVAR_SEC(vaporizer, delay), - WEP_CVAR_SEC(vaporizer, lifetime) - ); - PS(actor).m_weapon = oldwep; - - // now do normal refire - weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(vaporizer, animtime), w_ready); - } - } - else - actor.held_down = false; - } - METHOD(Vaporizer, wr_setup, void(entity thiswep)) - { - self.ammo_field = (thiswep.ammo_field); - self.vaporizer_lasthit = 0; - } - METHOD(Vaporizer, wr_checkammo1, bool(entity thiswep)) - { - float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)); - float ammo_amount = self.(thiswep.ammo_field) >= vaporizer_ammo; - ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= vaporizer_ammo; - return ammo_amount; - } - METHOD(Vaporizer, wr_checkammo2, bool(entity thiswep)) - { - if(!WEP_CVAR_SEC(vaporizer, ammo)) - return true; - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(vaporizer, ammo); - ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= WEP_CVAR_SEC(vaporizer, ammo); - return ammo_amount; - } - METHOD(Vaporizer, wr_resetplayer, void(entity thiswep)) - { - self.vaporizer_lasthit = 0; - } - METHOD(Vaporizer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)); - float used_ammo; - if(WEP_CVAR_SEC(vaporizer, ammo)) - used_ammo = min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo)); - else - used_ammo = vaporizer_ammo; - - W_Reload(self, used_ammo, SND(RELOAD)); - } - METHOD(Vaporizer, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_THINKING_WITH_PORTALS; - } - METHOD(Vaporizer, wr_killmessage, int(entity thiswep)) - { - return WEAPON_VAPORIZER_MURDER; - } +METHOD(Vaporizer, wr_aim, void(entity thiswep)) +{ + if(self.(thiswep.ammo_field) > 0) + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(1000000, 0, 1, false); + else + PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(WEP_CVAR_SEC(vaporizer, speed), 0, WEP_CVAR_SEC(vaporizer, lifetime), false); // WEAPONTODO: replace with proper vaporizer cvars +} +METHOD(Vaporizer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)); + // if the laser uses load, we also consider its ammo for reloading + if(WEP_CVAR(vaporizer, reload_ammo) && WEP_CVAR_SEC(vaporizer, ammo) && actor.clip_load < min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else if(WEP_CVAR(vaporizer, reload_ammo) && actor.clip_load < vaporizer_ammo) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } + if((fire & 1) && (actor.ammo_cells || !autocvar_g_rm) && !forbidWeaponUse(actor)) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(vaporizer, refire))) + { + W_Vaporizer_Attack(thiswep); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(vaporizer, animtime), w_ready); + } + } + if((fire & 2) || ((fire & 1) && !actor.ammo_cells && autocvar_g_rm)) + { + if((autocvar_g_rm && autocvar_g_rm_laser) || autocvar_g_rm_laser == 2) + { + bool rapid = autocvar_g_rm_laser_rapid; + if(actor.jump_interval <= time && !actor.held_down) + { + if(rapid) + actor.held_down = true; + actor.jump_interval = time + autocvar_g_rm_laser_refire; + actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_delay; + damage_goodhits = 0; + W_RocketMinsta_Attack2(); + } + else if(rapid && actor.jump_interval2 <= time && actor.held_down) + { + actor.jump_interval2 = time + autocvar_g_rm_laser_rapid_refire; + damage_goodhits = 0; + W_RocketMinsta_Attack3(); + //weapon_thinkf(actor, WFRAME_FIRE2, autocvar_g_rm_laser_rapid_animtime, w_ready); + } + } + else if (actor.jump_interval <= time) + { + // handle refire manually, so that primary and secondary can be fired without conflictions (important for instagib) + actor.jump_interval = time + WEP_CVAR_SEC(vaporizer, refire) * W_WeaponRateFactor(); + + // decrease ammo for the laser? + if(WEP_CVAR_SEC(vaporizer, ammo)) + W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(vaporizer, ammo)); + + // ugly instagib hack to reuse the fire mode of the laser + makevectors(actor.v_angle); + Weapon oldwep = PS(actor).m_weapon; // we can't avoid this hack + PS(actor).m_weapon = WEP_BLASTER; + W_Blaster_Attack( + actor, + WEP_BLASTER.m_id | HITTYPE_SECONDARY, + WEP_CVAR_SEC(vaporizer, shotangle), + WEP_CVAR_SEC(vaporizer, damage), + WEP_CVAR_SEC(vaporizer, edgedamage), + WEP_CVAR_SEC(vaporizer, radius), + WEP_CVAR_SEC(vaporizer, force), + WEP_CVAR_SEC(vaporizer, speed), + WEP_CVAR_SEC(vaporizer, spread), + WEP_CVAR_SEC(vaporizer, delay), + WEP_CVAR_SEC(vaporizer, lifetime) + ); + PS(actor).m_weapon = oldwep; + + // now do normal refire + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(vaporizer, animtime), w_ready); + } + } + else + actor.held_down = false; +} +METHOD(Vaporizer, wr_setup, void(entity thiswep)) +{ + self.ammo_field = (thiswep.ammo_field); + self.vaporizer_lasthit = 0; +} +METHOD(Vaporizer, wr_checkammo1, bool(entity thiswep)) +{ + float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)); + float ammo_amount = self.(thiswep.ammo_field) >= vaporizer_ammo; + ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= vaporizer_ammo; + return ammo_amount; +} +METHOD(Vaporizer, wr_checkammo2, bool(entity thiswep)) +{ + if(!WEP_CVAR_SEC(vaporizer, ammo)) + return true; + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(vaporizer, ammo); + ammo_amount += self.(weapon_load[WEP_VAPORIZER.m_id]) >= WEP_CVAR_SEC(vaporizer, ammo); + return ammo_amount; +} +METHOD(Vaporizer, wr_resetplayer, void(entity thiswep)) +{ + self.vaporizer_lasthit = 0; +} +METHOD(Vaporizer, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + float vaporizer_ammo = ((g_instagib) ? 1 : WEP_CVAR_PRI(vaporizer, ammo)); + float used_ammo; + if(WEP_CVAR_SEC(vaporizer, ammo)) + used_ammo = min(vaporizer_ammo, WEP_CVAR_SEC(vaporizer, ammo)); + else + used_ammo = vaporizer_ammo; + + W_Reload(self, used_ammo, SND(RELOAD)); +} +METHOD(Vaporizer, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_THINKING_WITH_PORTALS; +} +METHOD(Vaporizer, wr_killmessage, Notification(entity thiswep)) +{ + return WEAPON_VAPORIZER_MURDER; +} #endif #ifdef CSQC - METHOD(Vaporizer, wr_impacteffect, void(entity thiswep)) - { - vector org2 = w_org + w_backoff * 6; - if(w_deathtype & HITTYPE_SECONDARY) - { - pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); - if(!w_issilent) { sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); } - } - else - { - pointparticles(EFFECT_VORTEX_IMPACT, org2, '0 0 0', 1); - if(!w_issilent) { sound(self, CH_SHOTS, SND_NEXIMPACT, VOL_BASE, ATTN_NORM); } - } - } - METHOD(Vaporizer, wr_init, void(entity thiswep)) - { - if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) - { - precache_pic("gfx/reticle_nex"); - } - } - METHOD(Vaporizer, wr_zoomreticle, bool(entity thiswep)) - { - if(button_zoom || zoomscript_caught) - { - reticle_image = "gfx/reticle_nex"; - return true; - } - else - { - // no weapon specific image for this weapon - return false; - } - } +METHOD(Vaporizer, wr_impacteffect, void(entity thiswep)) +{ + vector org2 = w_org + w_backoff * 6; + if(w_deathtype & HITTYPE_SECONDARY) + { + pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1); + if(!w_issilent) { sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); } + } + else + { + pointparticles(EFFECT_VORTEX_IMPACT, org2, '0 0 0', 1); + if(!w_issilent) { sound(self, CH_SHOTS, SND_NEXIMPACT, VOL_BASE, ATTN_NORM); } + } +} +METHOD(Vaporizer, wr_init, void(entity thiswep)) +{ + if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) + { + precache_pic("gfx/reticle_nex"); + } +} +METHOD(Vaporizer, wr_zoomreticle, bool(entity thiswep)) +{ + if(button_zoom || zoomscript_caught) + { + reticle_image = "gfx/reticle_nex"; + return true; + } + else + { + // no weapon specific image for this weapon + return false; + } +} #endif #endif diff --git a/qcsrc/common/weapons/weapon/vortex.qc b/qcsrc/common/weapons/weapon/vortex.qc index 83ea7e597..d14457b2e 100644 --- a/qcsrc/common/weapons/weapon/vortex.qc +++ b/qcsrc/common/weapons/weapon/vortex.qc @@ -210,193 +210,193 @@ void W_Vortex_Attack(Weapon thiswep, float issecondary) .float vortex_chargepool_pauseregen_finished; - METHOD(Vortex, wr_aim, void(entity thiswep)) - { - if(bot_aim(1000000, 0, 1, false)) - self.BUTTON_ATCK = true; - else - { - if(WEP_CVAR(vortex, charge)) - self.BUTTON_ATCK2 = true; - } - } - METHOD(Vortex, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) - { - if(WEP_CVAR(vortex, charge) && actor.vortex_charge < WEP_CVAR(vortex, charge_limit)) - actor.vortex_charge = min(1, actor.vortex_charge + WEP_CVAR(vortex, charge_rate) * frametime / W_TICSPERFRAME); - - if(WEP_CVAR_SEC(vortex, chargepool)) - if(actor.vortex_chargepool_ammo < 1) - { - if(actor.vortex_chargepool_pauseregen_finished < time) - actor.vortex_chargepool_ammo = min(1, actor.vortex_chargepool_ammo + WEP_CVAR_SEC(vortex, chargepool_regen) * frametime / W_TICSPERFRAME); - actor.pauseregen_finished = max(actor.pauseregen_finished, time + WEP_CVAR_SEC(vortex, chargepool_pause_regen)); - } - - if(autocvar_g_balance_vortex_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo))) { // forced reload - thiswep.wr_reload(thiswep, actor, weaponentity); - } else - { - if(fire & 1) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(vortex, refire))) - { - W_Vortex_Attack(thiswep, 0); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(vortex, animtime), w_ready); - } - } - if((WEP_CVAR(vortex, charge) && !WEP_CVAR(vortex, secondary)) ? (actor.BUTTON_ZOOM | actor.BUTTON_ZOOMSCRIPT) : (fire & 2)) - { - if(WEP_CVAR(vortex, charge)) - { - actor.vortex_charge_rottime = time + WEP_CVAR(vortex, charge_rot_pause); - float dt = frametime / W_TICSPERFRAME; - - if(actor.vortex_charge < 1) - { - if(WEP_CVAR_SEC(vortex, chargepool)) - { - if(WEP_CVAR_SEC(vortex, ammo)) - { - // always deplete if secondary is held - actor.vortex_chargepool_ammo = max(0, actor.vortex_chargepool_ammo - WEP_CVAR_SEC(vortex, ammo) * dt); - - dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate)); - actor.vortex_chargepool_pauseregen_finished = time + WEP_CVAR_SEC(vortex, chargepool_pause_regen); - dt = min(dt, actor.vortex_chargepool_ammo); - dt = max(0, dt); - - actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate); - } - } - - else if(WEP_CVAR_SEC(vortex, ammo)) - { - if(fire & 2) // only eat ammo when the button is pressed - { - dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate)); - if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) - { - // if this weapon is reloadable, decrease its load. Else decrease the player's ammo - if(autocvar_g_balance_vortex_reload_ammo) - { - dt = min(dt, (actor.clip_load - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo)); - dt = max(0, dt); - if(dt > 0) - { - actor.clip_load = max(WEP_CVAR_SEC(vortex, ammo), actor.clip_load - WEP_CVAR_SEC(vortex, ammo) * dt); - } - actor.(weapon_load[WEP_VORTEX.m_id]) = actor.clip_load; - } - else - { - dt = min(dt, (actor.(thiswep.ammo_field) - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo)); - dt = max(0, dt); - if(dt > 0) - { - actor.(thiswep.ammo_field) = max(WEP_CVAR_SEC(vortex, ammo), actor.(thiswep.ammo_field) - WEP_CVAR_SEC(vortex, ammo) * dt); - } - } - } - actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate); - } - } - - else - { - dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate)); - actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate); - } - } - } - else if(WEP_CVAR(vortex, secondary)) - { - if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(vortex, refire))) - { - W_Vortex_Attack(thiswep, 1); - weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(vortex, animtime), w_ready); - } - } - } - } - } - METHOD(Vortex, wr_setup, void(entity thiswep)) - { - self.vortex_lasthit = 0; - } - METHOD(Vortex, wr_checkammo1, bool(entity thiswep)) - { - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(vortex, ammo); - ammo_amount += (autocvar_g_balance_vortex_reload_ammo && self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_PRI(vortex, ammo)); - return ammo_amount; - } - METHOD(Vortex, wr_checkammo2, bool(entity thiswep)) - { - if(WEP_CVAR(vortex, secondary)) - { - // don't allow charging if we don't have enough ammo - float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(vortex, ammo); - ammo_amount += self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_SEC(vortex, ammo); - return ammo_amount; - } - else - { - return false; // zoom is not a fire mode - } - } - METHOD(Vortex, wr_resetplayer, void(entity thiswep)) - { - if (WEP_CVAR(vortex, charge)) { - if (WEP_CVAR_SEC(vortex, chargepool)) { - self.vortex_chargepool_ammo = 1; - } - self.vortex_charge = WEP_CVAR(vortex, charge_start); - } - self.vortex_lasthit = 0; - } - METHOD(Vortex, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) - { - W_Reload(self, min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo)), SND(RELOAD)); - } - METHOD(Vortex, wr_suicidemessage, int(entity thiswep)) - { - return WEAPON_THINKING_WITH_PORTALS; - } - METHOD(Vortex, wr_killmessage, int(entity thiswep)) - { - return WEAPON_VORTEX_MURDER; - } +METHOD(Vortex, wr_aim, void(entity thiswep)) +{ + if(bot_aim(1000000, 0, 1, false)) + PHYS_INPUT_BUTTON_ATCK(self) = true; + else + { + if(WEP_CVAR(vortex, charge)) + PHYS_INPUT_BUTTON_ATCK2(self) = true; + } +} +METHOD(Vortex, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(WEP_CVAR(vortex, charge) && actor.vortex_charge < WEP_CVAR(vortex, charge_limit)) + actor.vortex_charge = min(1, actor.vortex_charge + WEP_CVAR(vortex, charge_rate) * frametime / W_TICSPERFRAME); + + if(WEP_CVAR_SEC(vortex, chargepool)) + if(actor.vortex_chargepool_ammo < 1) + { + if(actor.vortex_chargepool_pauseregen_finished < time) + actor.vortex_chargepool_ammo = min(1, actor.vortex_chargepool_ammo + WEP_CVAR_SEC(vortex, chargepool_regen) * frametime / W_TICSPERFRAME); + actor.pauseregen_finished = max(actor.pauseregen_finished, time + WEP_CVAR_SEC(vortex, chargepool_pause_regen)); + } + + if(autocvar_g_balance_vortex_reload_ammo && actor.clip_load < min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else + { + if(fire & 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(vortex, refire))) + { + W_Vortex_Attack(thiswep, 0); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(vortex, animtime), w_ready); + } + } + if((WEP_CVAR(vortex, charge) && !WEP_CVAR(vortex, secondary)) ? (PHYS_INPUT_BUTTON_ZOOM(actor) | PHYS_INPUT_BUTTON_ZOOMSCRIPT(actor)) : (fire & 2)) + { + if(WEP_CVAR(vortex, charge)) + { + actor.vortex_charge_rottime = time + WEP_CVAR(vortex, charge_rot_pause); + float dt = frametime / W_TICSPERFRAME; + + if(actor.vortex_charge < 1) + { + if(WEP_CVAR_SEC(vortex, chargepool)) + { + if(WEP_CVAR_SEC(vortex, ammo)) + { + // always deplete if secondary is held + actor.vortex_chargepool_ammo = max(0, actor.vortex_chargepool_ammo - WEP_CVAR_SEC(vortex, ammo) * dt); + + dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate)); + actor.vortex_chargepool_pauseregen_finished = time + WEP_CVAR_SEC(vortex, chargepool_pause_regen); + dt = min(dt, actor.vortex_chargepool_ammo); + dt = max(0, dt); + + actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate); + } + } + + else if(WEP_CVAR_SEC(vortex, ammo)) + { + if(fire & 2) // only eat ammo when the button is pressed + { + dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate)); + if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) + { + // if this weapon is reloadable, decrease its load. Else decrease the player's ammo + if(autocvar_g_balance_vortex_reload_ammo) + { + dt = min(dt, (actor.clip_load - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo)); + dt = max(0, dt); + if(dt > 0) + { + actor.clip_load = max(WEP_CVAR_SEC(vortex, ammo), actor.clip_load - WEP_CVAR_SEC(vortex, ammo) * dt); + } + actor.(weapon_load[WEP_VORTEX.m_id]) = actor.clip_load; + } + else + { + dt = min(dt, (actor.(thiswep.ammo_field) - WEP_CVAR_PRI(vortex, ammo)) / WEP_CVAR_SEC(vortex, ammo)); + dt = max(0, dt); + if(dt > 0) + { + actor.(thiswep.ammo_field) = max(WEP_CVAR_SEC(vortex, ammo), actor.(thiswep.ammo_field) - WEP_CVAR_SEC(vortex, ammo) * dt); + } + } + } + actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate); + } + } + + else + { + dt = min(dt, (1 - actor.vortex_charge) / WEP_CVAR(vortex, charge_rate)); + actor.vortex_charge += dt * WEP_CVAR(vortex, charge_rate); + } + } + } + else if(WEP_CVAR(vortex, secondary)) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(vortex, refire))) + { + W_Vortex_Attack(thiswep, 1); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_SEC(vortex, animtime), w_ready); + } + } + } + } +} +METHOD(Vortex, wr_setup, void(entity thiswep)) +{ + self.vortex_lasthit = 0; +} +METHOD(Vortex, wr_checkammo1, bool(entity thiswep)) +{ + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_PRI(vortex, ammo); + ammo_amount += (autocvar_g_balance_vortex_reload_ammo && self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_PRI(vortex, ammo)); + return ammo_amount; +} +METHOD(Vortex, wr_checkammo2, bool(entity thiswep)) +{ + if(WEP_CVAR(vortex, secondary)) + { + // don't allow charging if we don't have enough ammo + float ammo_amount = self.(thiswep.ammo_field) >= WEP_CVAR_SEC(vortex, ammo); + ammo_amount += self.(weapon_load[WEP_VORTEX.m_id]) >= WEP_CVAR_SEC(vortex, ammo); + return ammo_amount; + } + else + { + return false; // zoom is not a fire mode + } +} +METHOD(Vortex, wr_resetplayer, void(entity thiswep)) +{ + if (WEP_CVAR(vortex, charge)) { + if (WEP_CVAR_SEC(vortex, chargepool)) { + self.vortex_chargepool_ammo = 1; + } + self.vortex_charge = WEP_CVAR(vortex, charge_start); + } + self.vortex_lasthit = 0; +} +METHOD(Vortex, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(self, min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo)), SND(RELOAD)); +} +METHOD(Vortex, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_THINKING_WITH_PORTALS; +} +METHOD(Vortex, wr_killmessage, Notification(entity thiswep)) +{ + return WEAPON_VORTEX_MURDER; +} #endif #ifdef CSQC - METHOD(Vortex, wr_impacteffect, void(entity thiswep)) - { - vector org2 = w_org + w_backoff * 6; - pointparticles(EFFECT_VORTEX_IMPACT, org2, '0 0 0', 1); - if(!w_issilent) - sound(self, CH_SHOTS, SND_NEXIMPACT, VOL_BASE, ATTN_NORM); - } - METHOD(Vortex, wr_init, void(entity thiswep)) - { - if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) - { - precache_pic("gfx/reticle_nex"); - } - } - METHOD(Vortex, wr_zoomreticle, bool(entity thiswep)) - { - if(button_zoom || zoomscript_caught || (!WEP_CVAR(vortex, secondary) && button_attack2)) - { - reticle_image = "gfx/reticle_nex"; - return true; - } - else - { - // no weapon specific image for this weapon - return false; - } - } +METHOD(Vortex, wr_impacteffect, void(entity thiswep)) +{ + vector org2 = w_org + w_backoff * 6; + pointparticles(EFFECT_VORTEX_IMPACT, org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, SND_NEXIMPACT, VOL_BASE, ATTN_NORM); +} +METHOD(Vortex, wr_init, void(entity thiswep)) +{ + if(autocvar_cl_reticle && autocvar_cl_reticle_weapon) + { + precache_pic("gfx/reticle_nex"); + } +} +METHOD(Vortex, wr_zoomreticle, bool(entity thiswep)) +{ + if(button_zoom || zoomscript_caught || (!WEP_CVAR(vortex, secondary) && button_attack2)) + { + reticle_image = "gfx/reticle_nex"; + return true; + } + else + { + // no weapon specific image for this weapon + return false; + } +} #endif #endif diff --git a/qcsrc/lib/accumulate.qh b/qcsrc/lib/accumulate.qh index a32649f5c..c265325f8 100644 --- a/qcsrc/lib/accumulate.qh +++ b/qcsrc/lib/accumulate.qh @@ -10,7 +10,6 @@ func() #else #ifdef HAVE_YO_DAWG_CPP -// TODO make ascii art pic of xzibit // YO DAWG! // I HERD YO LIEK MACROS // SO I PUT A MACRO DEFINITION IN YO MACRO DEFINITION diff --git a/qcsrc/lib/bool.qh b/qcsrc/lib/bool.qh index 9889f778a..dc50c771f 100644 --- a/qcsrc/lib/bool.qh +++ b/qcsrc/lib/bool.qh @@ -6,10 +6,6 @@ const int false = 0; #endif -// Transitional aliases -[[deprecated("use true")]][[alias("true")]] const bool TRUE; -[[deprecated("use false")]][[alias("false")]] const bool FALSE; - #define boolean(value) ((value) != 0) // get true/false value of a string with multiple different inputs diff --git a/qcsrc/lib/defer.qh b/qcsrc/lib/defer.qh index 070c09275..b923062bc 100644 --- a/qcsrc/lib/defer.qh +++ b/qcsrc/lib/defer.qh @@ -37,8 +37,7 @@ */ void defer(entity this, float fdelay, void() func) { - entity e = new(deferred); - make_pure(e); + entity e = new_pure(deferred); e.owner = this; e.use = func; e.think = defer_think; diff --git a/qcsrc/lib/enumclass.qh b/qcsrc/lib/enumclass.qh index 412e9db6b..68b106a5c 100644 --- a/qcsrc/lib/enumclass.qh +++ b/qcsrc/lib/enumclass.qh @@ -8,16 +8,21 @@ // zero overhead mode, use this for releases -#define ENUMCLASS(id) typedef int id; enum { +#define ENUMCLASS(id) typedef int id; enum { CASE(id, Null) #define CASE(class, id) class##_##id, #define ENUMCLASS_END(id) }; +#define ORDINAL(it) (it) +#define ENUMCAST(T, it) (it) #else // edict overhead mode, use this for type checking -#define ENUMCLASS(id) CLASS(id, Object) -#define CASE(class, id) class class##_##id; STATIC_INIT(class##_##id) { class##_##id = NEW(class); } +.int enum_ordinal; +#define ENUMCLASS(id) CLASS(id, Object) int id##_count; const noref entity id##_Null = nil; CASE(id, Null__) +#define CASE(class, id) class class##_##id; STATIC_INIT(class##_##id) { entity e = class##_##id = NEW(class); e.enum_ordinal = class##_count++; } #define ENUMCLASS_END(id) ENDCLASS(id) +#define ORDINAL(it) ((it).enum_ordinal) +#define ENUMCAST(T, it) ftoe(etof(T##_Null__) + (it)) #endif diff --git a/qcsrc/lib/iter.qh b/qcsrc/lib/iter.qh index f5200a41a..89b455ab5 100644 --- a/qcsrc/lib/iter.qh +++ b/qcsrc/lib/iter.qh @@ -107,6 +107,21 @@ noref string _FOREACH_ENTITY_mutex; } MACRO_END +#ifndef MENUQC +entity(vector org, float rad, .entity tofield) _findradius_tofield = #22; +#define FOREACH_ENTITY_RADIUS(org, dist, cond, body) FOREACH_ENTITY_RADIUS_UNORDERED(org, dist, cond, body) +.entity _FOREACH_ENTITY_RADIUS_next; +noref string _FOREACH_ENTITY_RADIUS_mutex; +#define FOREACH_ENTITY_RADIUS_UNORDERED(org, dist, cond, body) \ + MACRO_BEGIN { \ + if (_FOREACH_ENTITY_RADIUS_mutex) LOG_SEVEREF("Loop mutex held by %s", _FOREACH_ENTITY_RADIUS_mutex); \ + _FOREACH_ENTITY_RADIUS_mutex = __FUNC__; \ + entity _foundchain_first = _findradius_tofield(org, dist, _FOREACH_ENTITY_RADIUS_next); \ + FOREACH_LIST(_foundchain, _FOREACH_ENTITY_RADIUS_next, cond, body); \ + _FOREACH_ENTITY_RADIUS_mutex = string_null; \ + } MACRO_END +#endif + #define FOREACH_ENTITY_CLASS(class, cond, body) ORDERED(FOREACH_ENTITY_CLASS)(class, cond, body) #define FOREACH_ENTITY_CLASS_ORDERED(class, cond, body) FOREACH_ENTITY_ORDERED(it.classname == class && (cond), body) diff --git a/qcsrc/lib/linkedlist.qh b/qcsrc/lib/linkedlist.qh index a8e4aaa09..07d99b4f1 100644 --- a/qcsrc/lib/linkedlist.qh +++ b/qcsrc/lib/linkedlist.qh @@ -67,7 +67,7 @@ entity LL_POP(LinkedList this) #define LL_DELETE_2(this, dtor) \ MACRO_BEGIN \ { \ - LL_CLEAR(this, dtor); \ + LL_CLEAR_2(this, dtor); \ remove(this); \ this = NULL; \ } MACRO_END diff --git a/qcsrc/lib/log.qh b/qcsrc/lib/log.qh index 01dc645f5..68c974dc3 100644 --- a/qcsrc/lib/log.qh +++ b/qcsrc/lib/log.qh @@ -1,5 +1,7 @@ #pragma once +#include "progname.qh" + #define assert(expr, ...) _assert(LOG_SEVERE, expr, __VA_ARGS__) #define devassert(...) MACRO_BEGIN if (autocvar_developer) assert(__VA_ARGS__); MACRO_END @@ -38,7 +40,7 @@ string(string...) strcat0n = #115; #define _LOG(f, level, s) \ MACRO_BEGIN { \ - f(sprintf("^9[::" level "^9] [" __FILE__ "^7:^9%s^7:^9" STR(__LINE__) "] \n^7%s\n", __FUNC__, s)); \ + f(sprintf("^9[::^7" PROGNAME "^9::" level "^9] [" __FILE__ "^7:^9%s^7:^9" STR(__LINE__) "] \n^7%s\n", __FUNC__, s)); \ } MACRO_END #define LOG_FATAL(...) _LOG_FATAL(strcat0n(__VA_ARGS__)) diff --git a/qcsrc/lib/net.qh b/qcsrc/lib/net.qh index b0320eadb..b364ced54 100644 --- a/qcsrc/lib/net.qh +++ b/qcsrc/lib/net.qh @@ -145,9 +145,7 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); } void UncustomizeEntitiesRun() { - FOREACH_ENTITY_FLOAT(uncustomizeentityforclient_set, true, LAMBDA( - WITH(entity, self, it, it.uncustomizeentityforclient()); - )); + FOREACH_ENTITY_FLOAT(uncustomizeentityforclient_set, true, WITH(entity, self, it, it.uncustomizeentityforclient())); } STRING_ITERATOR(g_buf, string_null, 0); @@ -265,28 +263,14 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); } v += ReadByte(); // note: this is unsigned return v; } - vector ReadInt48_t() - { - vector v; - v.x = ReadInt24_t(); - v.y = ReadInt24_t(); - v.z = 0; - return v; - } - vector ReadInt72_t() - { - vector v; - v.x = ReadInt24_t(); - v.y = ReadInt24_t(); - v.z = ReadInt24_t(); - return v; - } + #define ReadInt48_t() vec3(ReadInt24_t(), ReadInt24_t(), 0) + #define ReadInt72_t() vec3(ReadInt24_t(), ReadInt24_t(), ReadInt24_t()) int _ReadSByte; #define ReadSByte() (_ReadSByte = ReadByte(), (_ReadSByte & BIT(7) ? -128 : 0) + (_ReadSByte & BITS(7))) #define ReadFloat() ReadCoord() - vector ReadVector() { vector v; v.x = ReadFloat(); v.y = ReadFloat(); v.z = ReadFloat(); return v; } - vector ReadVector2D() { vector v; v.x = ReadFloat(); v.y = ReadFloat(); v.z = 0; return v; } + #define ReadVector() vec3(ReadFloat(), ReadFloat(), ReadFloat()) + #define ReadVector2D() vec3(ReadFloat(), ReadFloat(), 0) float ReadApproxPastTime() { diff --git a/qcsrc/lib/oo.qh b/qcsrc/lib/oo.qh index 7ecc745d0..8d50d2b92 100644 --- a/qcsrc/lib/oo.qh +++ b/qcsrc/lib/oo.qh @@ -12,7 +12,7 @@ .vector origin; .bool pure_data; -/** deprecated, use new_pure or NEW(class) */ +/** @deprecated, use new_pure or NEW(class) */ #define make_pure(e) \ MACRO_BEGIN \ { \ @@ -34,6 +34,7 @@ entity _spawn(); #define SPAWN_PURE 0 #endif +// pure entities: need no .origin #if SPAWN_PURE entity spawn_pure() = #600; #else @@ -50,6 +51,9 @@ entity __spawn(string _classname, string _sourceLoc, bool pure) #ifdef CSQC setorigin(this, '0 0 10000'); #endif + #ifdef SVQC + setorigin(this, '0 0 -10000'); + #endif } return this; } @@ -77,7 +81,6 @@ entity _clearentity_ent; STATIC_INIT(clearentity) { _clearentity_ent = new_pure(clearentity); - make_pure(_clearentity_ent); } void clearentity(entity e) { diff --git a/qcsrc/lib/registry.qh b/qcsrc/lib/registry.qh index 490ffd303..434473a86 100644 --- a/qcsrc/lib/registry.qh +++ b/qcsrc/lib/registry.qh @@ -21,14 +21,26 @@ * REGISTER_REGISTRY(Foos) */ #define REGISTRY(id, max) \ - void Register##id() {} \ + void Register##id(); \ + [[accumulate]] REGISTRY_BEGIN(id) {} \ + [[accumulate]] REGISTRY_END(id) {} \ + void _Register##id() {} \ + void Register##id() { REGISTRY_BEGIN_(id); _Register##id(); REGISTRY_END_(id); } \ const int id##_MAX = max; \ + int id##_COUNT; \ noref entity id##_first, id##_last; \ _R_MAP(_##id, id##_MAX); \ SHUTDOWN(id) { _R_DEL(_##id); } \ - int id##_COUNT; \ entity _##id##_from(int i, entity null) { if (i >= 0 && i < id##_COUNT) { entity e = _R_GET(_##id, i); if (e) return e; } return null; } +/** Called before initializing a registry. */ +#define REGISTRY_BEGIN(id) [[accumulate]] void REGISTRY_BEGIN_(id) { noref void() f = Register##id; } void REGISTRY_BEGIN_(id) +#define REGISTRY_BEGIN_(id) Register##id##_First() + +/** Called after initializing a registry. */ +#define REGISTRY_END(id) [[accumulate]] void REGISTRY_END_(id) { noref void() f = Register##id; } void REGISTRY_END_(id) +#define REGISTRY_END_(id) Register##id##_Done() + REGISTRY(Registries, BITS(8)) /** registered item identifier */ @@ -68,7 +80,7 @@ REGISTRY(Registries, BITS(8)) Register_##id##_init(this); \ Register_##id##_init_post(this); \ } \ - ACCUMULATE_FUNCTION(Register##registry, Register_##id) \ + ACCUMULATE_FUNCTION(_Register##registry, Register_##id) \ REGISTER_INIT(id) #define REGISTRY_PUSH(registry, fld, it) MACRO_BEGIN { \ @@ -146,7 +158,7 @@ void Registry_send(string id, string hash); string algo = "MD4"; \ string join = ":"; \ string s = ""; \ - FOREACH(id, true, LAMBDA(s = strcat(s, join, it.registered_id))); \ + FOREACH(id, true, s = strcat(s, join, it.registered_id)); \ s = substring(s, strlen(join), -1); \ string h = REGISTRY_HASH(id) = strzone(digest_hex(algo, s)); \ LOG_TRACEF(#id ": %s\n[%s]\n", h, s); \ diff --git a/qcsrc/lib/replicate.qh b/qcsrc/lib/replicate.qh index eae9a6e6f..f69b6072b 100644 --- a/qcsrc/lib/replicate.qh +++ b/qcsrc/lib/replicate.qh @@ -2,6 +2,13 @@ #ifndef MENUQC + /** + * Replicate a client cvar into a server field + * + * @param fld The field to replicate into + * @param type The field type + * @param cvar The cvar name + */ #define REPLICATE(...) EVAL_REPLICATE(OVERLOAD(REPLICATE, __VA_ARGS__)) #define EVAL_REPLICATE(...) __VA_ARGS__ diff --git a/qcsrc/lib/sortlist.qc b/qcsrc/lib/sortlist.qc index fecc79bdf..1d8726c89 100644 --- a/qcsrc/lib/sortlist.qc +++ b/qcsrc/lib/sortlist.qc @@ -2,8 +2,7 @@ entity Sort_Spawn() { - entity sort = new(sortlist); - make_pure(sort); + entity sort = new_pure(sortlist); sort.sort_next = NULL; sort.chain = sort; return sort; diff --git a/qcsrc/lib/spawnfunc.qh b/qcsrc/lib/spawnfunc.qh index f9c056fbd..9d1090bac 100644 --- a/qcsrc/lib/spawnfunc.qh +++ b/qcsrc/lib/spawnfunc.qh @@ -152,6 +152,7 @@ noref bool require_spawnfunc_prefix; FIELD_SCALAR(fld, platmovetype) \ FIELD_SCALAR(fld, race_place) \ FIELD_SCALAR(fld, radius) \ + FIELD_SCALAR(fld, respawntimestart) \ FIELD_SCALAR(fld, respawntimejitter) \ FIELD_SCALAR(fld, respawntime) \ FIELD_SCALAR(fld, restriction) \ diff --git a/qcsrc/lib/stats.qh b/qcsrc/lib/stats.qh index ea7671a1c..2d10d9c46 100644 --- a/qcsrc/lib/stats.qh +++ b/qcsrc/lib/stats.qh @@ -107,7 +107,7 @@ REGISTRY_SORT(Stats) REGISTRY_CHECK(Stats) STATIC_INIT(RegisterStats_renumber) { - FOREACH(Stats, true, LAMBDA(it.m_id = STATS_ENGINE_RESERVE + i)); + FOREACH(Stats, true, it.m_id = STATS_ENGINE_RESERVE + i); } #ifdef SVQC STATIC_INIT(stats_add) { stats_add(); } diff --git a/qcsrc/lib/string.qh b/qcsrc/lib/string.qh index bd0c8d30f..47a8175ca 100644 --- a/qcsrc/lib/string.qh +++ b/qcsrc/lib/string.qh @@ -16,7 +16,6 @@ } #endif -// TODO: macro string seconds_tostring(float sec) { float minutes = floor(sec / 60); diff --git a/qcsrc/lib/urllib.qc b/qcsrc/lib/urllib.qc index 0a48ef6cd..80145d8b8 100644 --- a/qcsrc/lib/urllib.qc +++ b/qcsrc/lib/urllib.qc @@ -94,8 +94,7 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass) // attempts to close will result in a reading handle // create a writing end that does nothing yet - e = new(url_single_fopen_file); - make_pure(e); + e = new_pure(url_single_fopen_file); e.url_url = strzone(url); e.url_fh = URL_FH_CURL; e.url_wbuf = buf_create(); @@ -143,8 +142,7 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass) // Make a dummy handle object (no buffers at // all). Wait for data to come from the // server, then call the callback - e = new(url_single_fopen_file); - make_pure(e); + e = new_pure(url_single_fopen_file); e.url_url = strzone(url); e.url_fh = URL_FH_CURL; e.url_rbuf = -1; @@ -165,8 +163,7 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass) { case FILE_WRITE: case FILE_APPEND: - e = new(url_single_fopen_stdout); - make_pure(e); + e = new_pure(url_single_fopen_stdout); e.url_fh = URL_FH_STDOUT; e.url_ready = rdy; e.url_ready_pass = pass; @@ -189,8 +186,7 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass) } else { - e = new(url_single_fopen_file); - make_pure(e); + e = new_pure(url_single_fopen_file); e.url_fh = fh; e.url_ready = rdy; e.url_ready_pass = pass; @@ -364,8 +360,7 @@ void url_multi_fopen(string url, int mode, url_ready_func rdy, entity pass) return; } - entity me = new(url_multi); - make_pure(me); + entity me = new_pure(url_multi); me.url_url = strzone(url); me.url_attempt = 0; me.url_mode = mode; diff --git a/qcsrc/lib/vector.qh b/qcsrc/lib/vector.qh index 21b931e93..def1dae2d 100644 --- a/qcsrc/lib/vector.qh +++ b/qcsrc/lib/vector.qh @@ -87,7 +87,9 @@ float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) { ret } MACRO_END noref vector _vec2; -#define vec2(v) (_vec2 = (v), _vec2.z = 0, _vec2) +#define vec2(...) EVAL(OVERLOAD(vec2, __VA_ARGS__)) +#define vec2_1(v) (_vec2 = (v), _vec2.z = 0, _vec2) +#define vec2_2(x, y) (_vec2_x = (x), _vec2_y = (y), _vec2) noref vector _vec3; #define vec3(_x, _y, _z) (_vec3.x = (_x), _vec3.y = (_y), _vec3.z = (_z), _vec3) @@ -104,6 +106,16 @@ vector rotate(vector v, float a) noref vector _yinvert; #define yinvert(v) (_yinvert = (v), _yinvert.y = 1 - _yinvert.y, _yinvert) +/** + * @param dir the directional vector + * @param norm the normalized normal + * @returns dir reflected by norm + */ +vector reflect(vector dir, vector norm) +{ + return dir - 2 * (dir * norm) * norm; +} + #ifndef MENUQC vector get_corner_position(entity box, int corner) { diff --git a/qcsrc/lib/warpzone/common.qc b/qcsrc/lib/warpzone/common.qc index 5a9b2abf9..99332dba6 100644 --- a/qcsrc/lib/warpzone/common.qc +++ b/qcsrc/lib/warpzone/common.qc @@ -186,8 +186,7 @@ void WarpZone_Trace_InitTransform() { if(!WarpZone_trace_transform) { - WarpZone_trace_transform = new(warpzone_trace_transform); - make_pure(WarpZone_trace_transform); + WarpZone_trace_transform = new_pure(warpzone_trace_transform); } WarpZone_Accumulator_Clear(WarpZone_trace_transform); } @@ -573,8 +572,8 @@ vector WarpZoneLib_NearestPointOnBox(vector mi, vector ma, vector org) bool WarpZoneLib_BadEntity(entity e) { - string s = e.classname; if (is_pure(e)) return true; + string s = e.classname; switch (s) { // case "net_linked": // actually some real entities are linked without classname, fail @@ -591,68 +590,62 @@ bool WarpZoneLib_BadEntity(entity e) .float WarpZone_findradius_hit; .entity WarpZone_findradius_next; -void WarpZone_FindRadius_Recurse(vector org, float rad, vector org0, vector transform, vector shift, float needlineofsight) -// blast origin of current search original blast origin how to untransform (victim to blast system) -{ - vector org_new; - vector org0_new; - vector shift_new, transform_new; - vector p; - entity e, e0; - entity wz; - if(rad <= 0) - return; - e0 = findradius(org, rad); - wz = world; - - for(e = e0; e; e = e.chain) - { - if(WarpZoneLib_BadEntity(e)) - continue; - p = WarpZoneLib_NearestPointOnBox(e.origin + e.mins, e.origin + e.maxs, org0); - if(needlineofsight) +void WarpZone_FindRadius_Recurse( + /** blast origin of current search */ + vector org, + float rad, + /** original blast origin */ + vector org0, + /** how to untransform (victim to blast system) */ + vector transform, + vector shift, + bool needlineofsight) +{ + if (rad <= 0) return; + entity wz = NULL; + FOREACH_ENTITY_RADIUS(org, rad, !WarpZoneLib_BadEntity(it), { + vector p = WarpZoneLib_NearestPointOnBox(it.origin + it.mins, it.origin + it.maxs, org0); + if (needlineofsight) { - traceline(org, p, MOVE_NOMONSTERS, e); - if(trace_fraction < 1) - continue; + traceline(org, p, MOVE_NOMONSTERS, it); + if (trace_fraction < 1) continue; } - if(!e.WarpZone_findradius_hit || vlen2(e.WarpZone_findradius_dist) > vlen2(org0 - p)) + if (!it.WarpZone_findradius_hit || vlen2(it.WarpZone_findradius_dist) > vlen2(org0 - p)) { - e.WarpZone_findradius_nearest = p; - e.WarpZone_findradius_dist = org0 - p; - e.WarpZone_findradius_findorigin = org; - e.WarpZone_findradius_findradius = rad; - if(e.classname == "warpzone_refsys") + it.WarpZone_findradius_nearest = p; + it.WarpZone_findradius_dist = org0 - p; + it.WarpZone_findradius_findorigin = org; + it.WarpZone_findradius_findradius = rad; + if (it.classname == "warpzone_refsys") { // ignore, especially: do not overwrite the refsys parameters } - else if(e.classname == "trigger_warpzone") + else if (it.classname == "trigger_warpzone") { - e.WarpZone_findradius_next = wz; - wz = e; - e.WarpZone_findradius_hit = 1; - e.enemy.WarpZone_findradius_dist = '0 0 0'; // we don't want to go through this zone ever again - e.enemy.WarpZone_findradius_hit = 1; + it.WarpZone_findradius_next = wz; + wz = it; + it.WarpZone_findradius_hit = 1; + it.enemy.WarpZone_findradius_dist = '0 0 0'; // we don't want to go through this zone ever again + it.enemy.WarpZone_findradius_hit = 1; } else { - e.warpzone_transform = transform; - e.warpzone_shift = shift; - e.WarpZone_findradius_hit = 1; + it.warpzone_transform = transform; + it.warpzone_shift = shift; + it.WarpZone_findradius_hit = 1; } } - } - for(e = wz; e; e = e.WarpZone_findradius_next) + }); + for(entity e = wz; e; e = e.WarpZone_findradius_next) { - if(WarpZoneLib_BadEntity(e)) - continue; + if (WarpZoneLib_BadEntity(e)) continue; - org0_new = WarpZone_TransformOrigin(e, org); + vector org0_new = WarpZone_TransformOrigin(e, org); traceline(e.warpzone_targetorigin, org0_new, MOVE_NOMONSTERS, e); - org_new = trace_endpos; + vector org_new = trace_endpos; - transform_new = AnglesTransform_Multiply(e.warpzone_transform, transform); - shift_new = AnglesTransform_Multiply_GetPostShift(e.warpzone_transform, e.warpzone_shift, transform, shift); + vector transform_new = AnglesTransform_Multiply(e.warpzone_transform, transform); + vector shift_new = AnglesTransform_Multiply_GetPostShift(e.warpzone_transform, e.warpzone_shift, transform, shift); WarpZone_FindRadius_Recurse( org_new, bound(0, rad - vlen(org_new - org0_new), rad - 8), @@ -663,14 +656,13 @@ void WarpZone_FindRadius_Recurse(vector org, float rad, vector org0, e.enemy.WarpZone_findradius_hit = 0; } } -entity WarpZone_FindRadius(vector org, float rad, float needlineofsight) +entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight) { - entity e0, e; + if (!warpzone_warpzones_exist && !needlineofsight) return findradius(org, rad); WarpZone_FindRadius_Recurse(org, rad, org, '0 0 0', '0 0 0', needlineofsight); - e0 = findchainfloat(WarpZone_findradius_hit, 1); - for(e = e0; e; e = e.chain) - e.WarpZone_findradius_hit = 0; - return e0; + entity list_first = findchainfloat(WarpZone_findradius_hit, 1); + FOREACH_LIST(list, chain, true, it.WarpZone_findradius_hit = 0); + return list_first; } .entity WarpZone_refsys; diff --git a/qcsrc/qcc.sh b/qcsrc/qcc.sh index 1678e668c..b3ad199b8 100755 --- a/qcsrc/qcc.sh +++ b/qcsrc/qcc.sh @@ -18,9 +18,9 @@ case ${MODE} in esac CPP="${CPP} -I. ${QCCIDENT} ${QCCDEFS} -D${PROG}" -set -x ${CPP} -MMD -MP -MT ${OUT} -Wall -Wundef -Werror -o ../.tmp/${MODE}.txt ${IN} ${CPP} -dM 1>../.tmp/${MODE}_macros.txt -H 2>../.tmp/${MODE}_includes.txt ${IN} sed 's/^#\(line\)\? \([[:digit:]]\+\) "\(.*\)".*/\n#pragma file(\3)\n#pragma line(\2)/g' ../.tmp/${MODE}.txt > ../.tmp/${MODE}.qc cd ${MODE} +echo $(basename ${QCC}) ${QCCFLAGS} -o ${OUT} ${MODE}.qc ${QCC} ${QCCFLAGS} -o ${OUT} ../../.tmp/${MODE}.qc diff --git a/qcsrc/server/_all.qh b/qcsrc/server/_all.qh index 47a562fe7..6a78f5320 100644 --- a/qcsrc/server/_all.qh +++ b/qcsrc/server/_all.qh @@ -20,14 +20,14 @@ const string STR_OBSERVER = "observer"; #define IS_VEHICLE(v) (v.vehicle_flags & VHF_ISVEHICLE) #define IS_TURRET(v) (v.turret_flags & TUR_FLAG_ISTURRET) -// NOTE: FOR_EACH_CLIENTSLOT deprecated! Use the following instead: FOREACH_CLIENTSLOT(true, LAMBDA(yourcode)); -// NOTE: FOR_EACH_CLIENT deprecated! Use the following instead: FOREACH_CLIENT(true, LAMBDA(yourcode)); -// NOTE: FOR_EACH_REALCLIENT deprecated! Use the following instead: FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA(yourcode)); +// NOTE: FOR_EACH_CLIENTSLOT deprecated! Use the following instead: FOREACH_CLIENTSLOT(true, { code; }); +// NOTE: FOR_EACH_CLIENT deprecated! Use the following instead: FOREACH_CLIENT(true, { code; }); +// NOTE: FOR_EACH_REALCLIENT deprecated! Use the following instead: FOREACH_CLIENT(IS_REAL_CLIENT(it), { code; }); -// NOTE: FOR_EACH_PLAYER deprecated! Use the following instead: FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(yourcode)); -// NOTE: FOR_EACH_SPEC deprecated! Use the following instead: FOREACH_CLIENT(IS_SPEC(it), LAMBDA(yourcode)); -// NOTE: FOR_EACH_OBSERVER deprecated! Use the following instead: FOREACH_CLIENT(IS_OBSERVER(it), LAMBDA(yourcode)); -// NOTE: FOR_EACH_REALPLAYER deprecated! Use the following instead: FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA(yourcode)); +// NOTE: FOR_EACH_PLAYER deprecated! Use the following instead: FOREACH_CLIENT(IS_PLAYER(it), { code; }); +// NOTE: FOR_EACH_SPEC deprecated! Use the following instead: FOREACH_CLIENT(IS_SPEC(it), { code; }); +// NOTE: FOR_EACH_OBSERVER deprecated! Use the following instead: FOREACH_CLIENT(IS_OBSERVER(it), { code; }); +// NOTE: FOR_EACH_REALPLAYER deprecated! Use the following instead: FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { code; }); #define FOREACH_CLIENTSLOT(cond, body) \ MACRO_BEGIN { \ @@ -41,7 +41,7 @@ const string STR_OBSERVER = "observer"; #define FOREACH_CLIENT(cond, body) FOREACH_CLIENTSLOT(IS_CLIENT(it) && (cond), body) -// NOTE: FOR_EACH_MONSTER deprecated! Use the following instead: FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(yourcode)); +// NOTE: FOR_EACH_MONSTER deprecated! Use the following instead: FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, { code; }); #include #include diff --git a/qcsrc/server/anticheat.qc b/qcsrc/server/anticheat.qc index 865010ff5..0e0121db6 100644 --- a/qcsrc/server/anticheat.qc +++ b/qcsrc/server/anticheat.qc @@ -5,9 +5,8 @@ #include "defs.qh" #include "miscfunctions.qh" - - #include "command/common.qh" +#include .float anticheat_jointime; @@ -66,33 +65,33 @@ void anticheat_physics(entity this) // div0_evade -> SPECTATORS makevectors(this.v_angle); - if(this.anticheat_div0_evade_offset == 0) + if(CS(this).anticheat_div0_evade_offset == 0) { f = fabs(anticheat_div0_evade_evasion_delta - floor(anticheat_div0_evade_evasion_delta) - 0.5) * 2; // triangle function - this.anticheat_div0_evade_offset = servertime + sys_frametime * (3 * f - 1); - this.anticheat_div0_evade_v_angle = this.v_angle; - this.anticheat_div0_evade_forward_initial = v_forward; - MEAN_ACCUMULATE(this, anticheat_div0_evade, 0, 1); + CS(this).anticheat_div0_evade_offset = servertime + sys_frametime * (3 * f - 1); + CS(this).anticheat_div0_evade_v_angle = this.v_angle; + CS(this).anticheat_div0_evade_forward_initial = v_forward; + MEAN_ACCUMULATE(CS(this), anticheat_div0_evade, 0, 1); } else { - if(time < this.anticheat_div0_evade_offset) - this.anticheat_div0_evade_v_angle = this.v_angle; - MEAN_ACCUMULATE(this, anticheat_div0_evade, 0.5 - 0.5 * (this.anticheat_div0_evade_forward_initial * v_forward), 1); + if(time < CS(this).anticheat_div0_evade_offset) + CS(this).anticheat_div0_evade_v_angle = this.v_angle; + MEAN_ACCUMULATE(CS(this), anticheat_div0_evade, 0.5 - 0.5 * (CS(this).anticheat_div0_evade_forward_initial * v_forward), 1); } - MEAN_ACCUMULATE(this, anticheat_div0_strafebot_old, movement_oddity(this.movement, this.anticheat_div0_strafebot_movement_prev), 1); - this.anticheat_div0_strafebot_movement_prev = this.movement; + MEAN_ACCUMULATE(CS(this), anticheat_div0_strafebot_old, movement_oddity(this.movement, CS(this).anticheat_div0_strafebot_movement_prev), 1); + CS(this).anticheat_div0_strafebot_movement_prev = this.movement; // Note: this actually tries to detect snap-aim. - if(this.anticheat_div0_strafebot_forward_prev && time > this.anticheat_fixangle_endtime) { - float cosangle = this.anticheat_div0_strafebot_forward_prev * v_forward; + if(CS(this).anticheat_div0_strafebot_forward_prev && time > CS(this).anticheat_fixangle_endtime) { + float cosangle = CS(this).anticheat_div0_strafebot_forward_prev * v_forward; float angle = cosangle < -1 ? M_PI : cosangle > 1 ? 0 : acos(cosangle); /* if (angle >= 10 * M_PI / 180) - printf("SNAP %s: %f for %f, %f since fixangle\n", this.netname, angle * 180 / M_PI, cosangle, time - this.anticheat_fixangle_endtime); + printf("SNAP %s: %f for %f, %f since fixangle\n", this.netname, angle * 180 / M_PI, cosangle, time - CS(this).anticheat_fixangle_endtime); */ - MEAN_ACCUMULATE(this, anticheat_div0_strafebot_new, angle / M_PI, 1); + MEAN_ACCUMULATE(CS(this), anticheat_div0_strafebot_new, angle / M_PI, 1); if (autocvar_slowmo > 0) { // Technically this is a NOP, as the engine should be ensuring @@ -101,62 +100,63 @@ void anticheat_physics(entity this) float dt = max(0.001, frametime) / autocvar_slowmo; float anglespeed = angle / dt; - MEAN_ACCUMULATE(this, anticheat_idle_snapaim_signal, anglespeed, dt); - MEAN_ACCUMULATE(this, anticheat_idle_snapaim_noise, anglespeed, dt); - MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m2, anglespeed, dt); - MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m3, anglespeed, dt); - MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m4, anglespeed, dt); - MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m7, anglespeed, dt); - MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m10, anglespeed, dt); + MEAN_ACCUMULATE(CS(this), anticheat_idle_snapaim_signal, anglespeed, dt); + MEAN_ACCUMULATE(CS(this), anticheat_idle_snapaim_noise, anglespeed, dt); + MEAN_ACCUMULATE(CS(this), anticheat_idle_snapaim_m2, anglespeed, dt); + MEAN_ACCUMULATE(CS(this), anticheat_idle_snapaim_m3, anglespeed, dt); + MEAN_ACCUMULATE(CS(this), anticheat_idle_snapaim_m4, anglespeed, dt); + MEAN_ACCUMULATE(CS(this), anticheat_idle_snapaim_m7, anglespeed, dt); + MEAN_ACCUMULATE(CS(this), anticheat_idle_snapaim_m10, anglespeed, dt); } } - this.anticheat_div0_strafebot_forward_prev = v_forward; + CS(this).anticheat_div0_strafebot_forward_prev = v_forward; // generic speedhack detection: correlate anticheat_speedhack_movetime (UPDATED BEFORE THIS) and server time - this.anticheat_speedhack_movetime_frac += frametime; - f = floor(this.anticheat_speedhack_movetime_frac); - this.anticheat_speedhack_movetime_frac -= f; - this.anticheat_speedhack_movetime_count += f; - this.anticheat_speedhack_movetime = this.anticheat_speedhack_movetime_frac + this.anticheat_speedhack_movetime_count; - f = this.anticheat_speedhack_movetime - servertime; - if(this.anticheat_speedhack_offset == 0) - this.anticheat_speedhack_offset = f; + CS(this).anticheat_speedhack_movetime_frac += frametime; + f = floor(CS(this).anticheat_speedhack_movetime_frac); + CS(this).anticheat_speedhack_movetime_frac -= f; + CS(this).anticheat_speedhack_movetime_count += f; + CS(this).anticheat_speedhack_movetime = CS(this).anticheat_speedhack_movetime_frac + CS(this).anticheat_speedhack_movetime_count; + f = CS(this).anticheat_speedhack_movetime - servertime; + if(CS(this).anticheat_speedhack_offset == 0) + CS(this).anticheat_speedhack_offset = f; else { - MEAN_ACCUMULATE(this, anticheat_speedhack, max(0, f - this.anticheat_speedhack_offset), 1); - this.anticheat_speedhack_offset += (f - this.anticheat_speedhack_offset) * frametime * 0.1; + MEAN_ACCUMULATE(CS(this), anticheat_speedhack, max(0, f - CS(this).anticheat_speedhack_offset), 1); + CS(this).anticheat_speedhack_offset += (f - CS(this).anticheat_speedhack_offset) * frametime * 0.1; } // new generic speedhack detection - if (this.anticheat_speedhack_lasttime > 0) { - float dt = servertime - this.anticheat_speedhack_lasttime; + if (CS(this).anticheat_speedhack_lasttime > 0) { + float dt = servertime - CS(this).anticheat_speedhack_lasttime; const float falloff = 0.2; - this.anticheat_speedhack_accu *= exp(-dt * falloff); - this.anticheat_speedhack_accu += frametime * falloff; + CS(this).anticheat_speedhack_accu *= exp(-dt * falloff); + CS(this).anticheat_speedhack_accu += frametime * falloff; // NOTE: at cl_netfps x, this actually averages not to 1, but to 1/x * falloff / (1 - exp(-1/x * falloff)) // For 15 netfps (absolute minimum bearable), and 0.2 falloff, this is: 1.0067 - this.anticheat_speedhack_lasttime = servertime; - MEAN_ACCUMULATE(this, anticheat_speedhack_m1, this.anticheat_speedhack_accu, frametime); - MEAN_ACCUMULATE(this, anticheat_speedhack_m2, this.anticheat_speedhack_accu, frametime); - MEAN_ACCUMULATE(this, anticheat_speedhack_m3, this.anticheat_speedhack_accu, frametime); - MEAN_ACCUMULATE(this, anticheat_speedhack_m4, this.anticheat_speedhack_accu, frametime); - MEAN_ACCUMULATE(this, anticheat_speedhack_m5, this.anticheat_speedhack_accu, frametime); + CS(this).anticheat_speedhack_lasttime = servertime; + MEAN_ACCUMULATE(CS(this), anticheat_speedhack_m1, CS(this).anticheat_speedhack_accu, frametime); + MEAN_ACCUMULATE(CS(this), anticheat_speedhack_m2, CS(this).anticheat_speedhack_accu, frametime); + MEAN_ACCUMULATE(CS(this), anticheat_speedhack_m3, CS(this).anticheat_speedhack_accu, frametime); + MEAN_ACCUMULATE(CS(this), anticheat_speedhack_m4, CS(this).anticheat_speedhack_accu, frametime); + MEAN_ACCUMULATE(CS(this), anticheat_speedhack_m5, CS(this).anticheat_speedhack_accu, frametime); } else { - this.anticheat_speedhack_accu = 1; - this.anticheat_speedhack_lasttime = servertime; + CS(this).anticheat_speedhack_accu = 1; + CS(this).anticheat_speedhack_lasttime = servertime; } } void anticheat_spectatecopy(entity spectatee) {SELFPARAM(); // div0_evade -> SPECTATORS - self.angles = spectatee.anticheat_div0_evade_v_angle; + self.angles = CS(spectatee).anticheat_div0_evade_v_angle; } void anticheat_prethink() -{SELFPARAM(); +{ + SELFPARAM(); // div0_evade -> SPECTATORS - self.anticheat_div0_evade_offset = 0; + CS(this).anticheat_div0_evade_offset = 0; } string anticheat_display(float f, float tmin, float mi, float ma) @@ -175,47 +175,47 @@ void anticheat_report() if(!autocvar_sv_eventlog) return; // TODO(divVerent): Use xonstat to acquire good thresholds. - GameLogEcho(strcat(":anticheat:_time:", ftos(self.playerid), ":", ftos(servertime - self.anticheat_jointime))); - GameLogEcho(strcat(":anticheat:speedhack:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack), 240, 0, 9999))); // Actually this one seems broken. - GameLogEcho(strcat(":anticheat:speedhack_m1:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m1), 240, 1.01, 1.25))); - GameLogEcho(strcat(":anticheat:speedhack_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m2), 240, 1.01, 1.25))); - GameLogEcho(strcat(":anticheat:speedhack_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m3), 240, 1.01, 1.25))); - GameLogEcho(strcat(":anticheat:speedhack_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m4), 240, 1.01, 1.25))); - GameLogEcho(strcat(":anticheat:speedhack_m5:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m5), 240, 1.01, 1.25))); - GameLogEcho(strcat(":anticheat:div0_strafebot_old:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_div0_strafebot_old), 120, 0.15, 0.4))); - GameLogEcho(strcat(":anticheat:div0_strafebot_new:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_div0_strafebot_new), 120, 0.25, 0.8))); - GameLogEcho(strcat(":anticheat:div0_evade:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_div0_evade), 120, 0.2, 0.5))); - GameLogEcho(strcat(":anticheat:idle_snapaim:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_signal) - MEAN_EVALUATE(self, anticheat_idle_snapaim_noise), 120, 0, 9999))); - GameLogEcho(strcat(":anticheat:idle_snapaim_signal:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_signal), 120, 0, 9999))); - GameLogEcho(strcat(":anticheat:idle_snapaim_noise:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_noise), 120, 0, 9999))); - GameLogEcho(strcat(":anticheat:idle_snapaim_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m2), 120, 0, 9999))); - GameLogEcho(strcat(":anticheat:idle_snapaim_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m3), 120, 0, 9999))); - GameLogEcho(strcat(":anticheat:idle_snapaim_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m4), 120, 0, 9999))); - GameLogEcho(strcat(":anticheat:idle_snapaim_m7:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m7), 120, 0, 9999))); - GameLogEcho(strcat(":anticheat:idle_snapaim_m10:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m10), 120, 0, 9999))); + GameLogEcho(strcat(":anticheat:_time:", ftos(self.playerid), ":", ftos(servertime - CS(self).anticheat_jointime))); + GameLogEcho(strcat(":anticheat:speedhack:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack), 240, 0, 9999))); // Actually this one seems broken. + GameLogEcho(strcat(":anticheat:speedhack_m1:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m1), 240, 1.01, 1.25))); + GameLogEcho(strcat(":anticheat:speedhack_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m2), 240, 1.01, 1.25))); + GameLogEcho(strcat(":anticheat:speedhack_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m3), 240, 1.01, 1.25))); + GameLogEcho(strcat(":anticheat:speedhack_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m4), 240, 1.01, 1.25))); + GameLogEcho(strcat(":anticheat:speedhack_m5:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_speedhack_m5), 240, 1.01, 1.25))); + GameLogEcho(strcat(":anticheat:div0_strafebot_old:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_div0_strafebot_old), 120, 0.15, 0.4))); + GameLogEcho(strcat(":anticheat:div0_strafebot_new:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_div0_strafebot_new), 120, 0.25, 0.8))); + GameLogEcho(strcat(":anticheat:div0_evade:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_div0_evade), 120, 0.2, 0.5))); + GameLogEcho(strcat(":anticheat:idle_snapaim:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_signal) - MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_noise), 120, 0, 9999))); + GameLogEcho(strcat(":anticheat:idle_snapaim_signal:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_signal), 120, 0, 9999))); + GameLogEcho(strcat(":anticheat:idle_snapaim_noise:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_noise), 120, 0, 9999))); + GameLogEcho(strcat(":anticheat:idle_snapaim_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m2), 120, 0, 9999))); + GameLogEcho(strcat(":anticheat:idle_snapaim_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m3), 120, 0, 9999))); + GameLogEcho(strcat(":anticheat:idle_snapaim_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m4), 120, 0, 9999))); + GameLogEcho(strcat(":anticheat:idle_snapaim_m7:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m7), 120, 0, 9999))); + GameLogEcho(strcat(":anticheat:idle_snapaim_m10:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m10), 120, 0, 9999))); } float anticheat_getvalue(string id) {SELFPARAM(); switch(id) { - case "_time": return servertime - self.anticheat_jointime; - case "speedhack": return MEAN_EVALUATE(self, anticheat_speedhack); - case "speedhack_m1": return MEAN_EVALUATE(self, anticheat_speedhack_m1); - case "speedhack_m2": return MEAN_EVALUATE(self, anticheat_speedhack_m2); - case "speedhack_m3": return MEAN_EVALUATE(self, anticheat_speedhack_m3); - case "speedhack_m4": return MEAN_EVALUATE(self, anticheat_speedhack_m4); - case "speedhack_m5": return MEAN_EVALUATE(self, anticheat_speedhack_m5); - case "div0_strafebot_old": return MEAN_EVALUATE(self, anticheat_div0_strafebot_old); - case "div0_strafebot_new": return MEAN_EVALUATE(self, anticheat_div0_strafebot_new); - case "div0_evade": return MEAN_EVALUATE(self, anticheat_div0_evade); - case "idle_snapaim": return MEAN_EVALUATE(self, anticheat_idle_snapaim_signal) - MEAN_EVALUATE(self, anticheat_idle_snapaim_noise); - case "idle_snapaim_signal": return MEAN_EVALUATE(self, anticheat_idle_snapaim_signal); - case "idle_snapaim_noise": return MEAN_EVALUATE(self, anticheat_idle_snapaim_noise); - case "idle_snapaim_m2": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m2); - case "idle_snapaim_m3": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m3); - case "idle_snapaim_m4": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m4); - case "idle_snapaim_m7": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m7); - case "idle_snapaim_m10": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m10); + case "_time": return servertime - CS(self).anticheat_jointime; + case "speedhack": return MEAN_EVALUATE(CS(self), anticheat_speedhack); + case "speedhack_m1": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m1); + case "speedhack_m2": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m2); + case "speedhack_m3": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m3); + case "speedhack_m4": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m4); + case "speedhack_m5": return MEAN_EVALUATE(CS(self), anticheat_speedhack_m5); + case "div0_strafebot_old": return MEAN_EVALUATE(CS(self), anticheat_div0_strafebot_old); + case "div0_strafebot_new": return MEAN_EVALUATE(CS(self), anticheat_div0_strafebot_new); + case "div0_evade": return MEAN_EVALUATE(CS(self), anticheat_div0_evade); + case "idle_snapaim": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_signal) - MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_noise); + case "idle_snapaim_signal": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_signal); + case "idle_snapaim_noise": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_noise); + case "idle_snapaim_m2": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m2); + case "idle_snapaim_m3": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m3); + case "idle_snapaim_m4": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m4); + case "idle_snapaim_m7": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m7); + case "idle_snapaim_m10": return MEAN_EVALUATE(CS(self), anticheat_idle_snapaim_m10); } return -1; } @@ -225,26 +225,19 @@ void anticheat_startframe() anticheat_div0_evade_evasion_delta += frametime * (0.5 + random()); } -void anticheat_fixangle() -{SELFPARAM(); - self.anticheat_fixangle_endtime = servertime + ANTILAG_LATENCY(self) + 0.2; +void anticheat_fixangle(entity this) +{ + CS(this).anticheat_fixangle_endtime = servertime + ANTILAG_LATENCY(this) + 0.2; } void anticheat_endframe() {SELFPARAM(); - FOREACH_CLIENT(true, LAMBDA( - if(it.fixangle) - WITH(entity, self, it, anticheat_fixangle()); - )); + FOREACH_CLIENT(it.fixangle, anticheat_fixangle(it)); anticheat_div0_evade_evasion_delta += frametime * (0.5 + random()); } void anticheat_init(entity this) { - this.anticheat_speedhack_offset = 0; - this.anticheat_jointime = servertime; -} - -void anticheat_shutdown() -{ + CS(this).anticheat_speedhack_offset = 0; + CS(this).anticheat_jointime = servertime; } diff --git a/qcsrc/server/anticheat.qh b/qcsrc/server/anticheat.qh index 5e6599b7e..e1055ac44 100644 --- a/qcsrc/server/anticheat.qh +++ b/qcsrc/server/anticheat.qh @@ -3,7 +3,6 @@ void anticheat_init(entity this); void anticheat_report(); -void anticheat_shutdown(); void anticheat_physics(entity this); void anticheat_spectatecopy(entity spectatee); @@ -14,5 +13,5 @@ float anticheat_getvalue(string name); void anticheat_startframe(); void anticheat_endframe(); -void anticheat_fixangle(); +void anticheat_fixangle(entity this); #endif diff --git a/qcsrc/server/antilag.qc b/qcsrc/server/antilag.qc index 36734976c..02cdc2028 100644 --- a/qcsrc/server/antilag.qc +++ b/qcsrc/server/antilag.qc @@ -1,7 +1,8 @@ #if defined(CSQC) #elif defined(MENUQC) #elif defined(SVQC) - #include "../common/vehicles/all.qh" + #include + #include #include "antilag.qh" #endif @@ -22,34 +23,34 @@ void antilag_record(entity e, float t) if(e.vehicle) antilag_record(e.vehicle, t); - if(time < e.(antilag_times[e.antilag_index])) + if(time < CS(e).antilag_times[CS(e).antilag_index]) return; - e.antilag_index = e.antilag_index + 1; - if(e.antilag_index >= ANTILAG_MAX_ORIGINS) - e.antilag_index = 0; - e.(antilag_times[e.antilag_index]) = t; - e.(antilag_origins[e.antilag_index]) = e.origin; + CS(e).antilag_index += 1; + if(CS(e).antilag_index >= ANTILAG_MAX_ORIGINS) + CS(e).antilag_index = 0; + CS(e).antilag_times[CS(e).antilag_index] = t; + CS(e).antilag_origins[CS(e).antilag_index] = e.origin; - if(e.antilag_debug) - te_spark(antilag_takebackorigin(e, t - e.antilag_debug), '0 0 0', 32); + if(CS(e).antilag_debug) + te_spark(antilag_takebackorigin(e, t - CS(e).antilag_debug), '0 0 0', 32); } // finds the index BEFORE t float antilag_find(entity e, float t) { - for(int i = e.antilag_index; i > 0; --i) - if(e.(antilag_times[i]) >= t) - if(e.(antilag_times[i - 1]) < t) + for(int i = CS(e).antilag_index; i > 0; --i) + if(CS(e).antilag_times[i] >= t) + if(CS(e).antilag_times[i - 1] < t) return i - 1; - if(e.(antilag_times[0]) >= t) - if(e.(antilag_times[ANTILAG_MAX_ORIGINS - 1]) < t) + if(CS(e).antilag_times[0] >= t) + if(CS(e).antilag_times[ANTILAG_MAX_ORIGINS - 1] < t) return ANTILAG_MAX_ORIGINS - 1; - for(int i = ANTILAG_MAX_ORIGINS - 1; i > e.antilag_index + 1; --i) - if(e.(antilag_times[i]) >= t) - if(e.(antilag_times[i - 1]) < t) + for(int i = ANTILAG_MAX_ORIGINS - 1; i > CS(e).antilag_index + 1; --i) + if(CS(e).antilag_times[i] >= t) + if(CS(e).antilag_times[i - 1] < t) return i - 1; // if we get here, t is sandwiched nowhere, so let's assume it's in the present @@ -62,8 +63,8 @@ vector antilag_takebackorigin(entity e, float t) if (i0 < 0) { // IN THE PRESENT - if(e.antilag_takenback) - return e.antilag_saved_origin; + if(CS(e).antilag_takenback) + return CS(e).antilag_saved_origin; else return e.origin; } @@ -71,7 +72,7 @@ vector antilag_takebackorigin(entity e, float t) if (i1 >= ANTILAG_MAX_ORIGINS) i1 = 0; - return lerpv(e.(antilag_times[i0]), e.(antilag_origins[i0]), e.(antilag_times[i1]), e.(antilag_origins[i1]), t); + return lerpv(CS(e).antilag_times[i0], CS(e).antilag_origins[i0], CS(e).antilag_times[i1], CS(e).antilag_origins[i1], t); } vector antilag_takebackavgvelocity(entity e, float t0, float t1) @@ -94,12 +95,12 @@ void antilag_takeback(entity e, float t) if(e.vehicle) antilag_takeback(e.vehicle, t); - if(!e.antilag_takenback) - e.antilag_saved_origin = e.origin; + if(!CS(e).antilag_takenback) + CS(e).antilag_saved_origin = e.origin; vector org = antilag_takebackorigin(e, t); setorigin(e, org); - e.antilag_takenback = true; + CS(e).antilag_takenback = true; } void antilag_restore(entity e) @@ -110,11 +111,11 @@ void antilag_restore(entity e) if(e.vehicle) antilag_restore(e.vehicle); - if(!e.antilag_takenback) + if(!CS(e).antilag_takenback) return; - setorigin(e, e.antilag_saved_origin); - e.antilag_takenback = false; + setorigin(e, CS(e).antilag_saved_origin); + CS(e).antilag_takenback = false; } void antilag_clear(entity e) @@ -122,8 +123,8 @@ void antilag_clear(entity e) antilag_restore(e); for (int i = 0; i < ANTILAG_MAX_ORIGINS; ++i) { - e.(antilag_times[i]) = -2342; - e.(antilag_origins[i]) = e.origin; + CS(e).antilag_times[i] = -2342; + CS(e).antilag_origins[i] = e.origin; } - e.antilag_index = ANTILAG_MAX_ORIGINS - 1; // next one is 0 + CS(e).antilag_index = ANTILAG_MAX_ORIGINS - 1; // next one is 0 } diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 3c4e4c43f..cd950738e 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -72,7 +72,7 @@ float autocvar_g_antilag_nudge; float autocvar_g_balance_armor_blockpercent; int autocvar_g_balance_armor_limit; float autocvar_g_balance_armor_regen; -float autocvar_g_balance_armor_regenlinear; // TODO: int/bool? +float autocvar_g_balance_armor_regenlinear; int autocvar_g_balance_armor_regenstable; float autocvar_g_balance_armor_rot; float autocvar_g_balance_armor_rotlinear; @@ -465,6 +465,8 @@ vector autocvar_g_nades_throw_offset; bool autocvar_g_nades_spawn; int autocvar_g_nades_spawn_count; bool autocvar_g_nades_client_select; +bool autocvar_g_nades_pickup = true; +float autocvar_g_nades_pickup_time = 2; float autocvar_g_nades_nade_lifetime; float autocvar_g_nades_nade_minforce; float autocvar_g_nades_nade_maxforce; diff --git a/qcsrc/server/bot/aim.qc b/qcsrc/server/bot/aim.qc index 79f0a2758..67057181b 100644 --- a/qcsrc/server/bot/aim.qc +++ b/qcsrc/server/bot/aim.qc @@ -133,7 +133,7 @@ float bot_shouldattack(entity e) return false; if (IS_DEAD(e)) return false; - if (e.BUTTON_CHAT) + if (PHYS_INPUT_BUTTON_CHAT(e)) return false; if(e.flags & FL_NOTARGET) return false; diff --git a/qcsrc/server/bot/bot.qc b/qcsrc/server/bot/bot.qc index 468b32c4a..72ebfcb2e 100644 --- a/qcsrc/server/bot/bot.qc +++ b/qcsrc/server/bot/bot.qc @@ -92,17 +92,16 @@ void bot_think() // skill 0 = ping 0.7 (slightly drunk) // clear buttons - self.BUTTON_ATCK = 0; - self.button1 = 0; - self.BUTTON_JUMP = 0; - self.BUTTON_ATCK2 = 0; - self.BUTTON_ZOOM = 0; - self.BUTTON_CROUCH = 0; - self.BUTTON_HOOK = 0; - self.BUTTON_INFO = 0; - self.button8 = 0; - self.BUTTON_CHAT = 0; - self.BUTTON_USE = 0; + PHYS_INPUT_BUTTON_ATCK(self) = false; + PHYS_INPUT_BUTTON_JUMP(self) = false; + PHYS_INPUT_BUTTON_ATCK2(self) = false; + PHYS_INPUT_BUTTON_ZOOM(self) = false; + PHYS_INPUT_BUTTON_CROUCH(self) = false; + PHYS_INPUT_BUTTON_HOOK(self) = false; + PHYS_INPUT_BUTTON_INFO(self) = false; + PHYS_INPUT_BUTTON_DRAG(self) = false; + PHYS_INPUT_BUTTON_CHAT(self) = false; + PHYS_INPUT_BUTTON_USE(self) = false; if (time < game_starttime) { @@ -117,7 +116,7 @@ void bot_think() { if (self.deadflag == DEAD_DEAD) { - self.BUTTON_JUMP = 1; // press jump to respawn + PHYS_INPUT_BUTTON_JUMP(self) = true; // press jump to respawn self.bot_strategytime = 0; } } diff --git a/qcsrc/server/bot/havocbot/havocbot.qc b/qcsrc/server/bot/havocbot/havocbot.qc index 134e78401..260e8e661 100644 --- a/qcsrc/server/bot/havocbot/havocbot.qc +++ b/qcsrc/server/bot/havocbot/havocbot.qc @@ -108,12 +108,12 @@ void havocbot_ai() w.wr_aim(w); if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self)) { - self.BUTTON_ATCK = false; - self.BUTTON_ATCK2 = false; + PHYS_INPUT_BUTTON_ATCK(self) = false; + PHYS_INPUT_BUTTON_ATCK2(self) = false; } else { - if(self.BUTTON_ATCK||self.BUTTON_ATCK2) + if(PHYS_INPUT_BUTTON_ATCK(self) || PHYS_INPUT_BUTTON_ATCK2(self)) self.lastfiredweapon = PS(self).m_weapon.m_id; } } @@ -246,7 +246,7 @@ void havocbot_keyboard_movement(vector destorg) keyboard.z = 0; self.havocbot_keyboard = keyboard * maxspeed; - if (self.havocbot_ducktime>time) self.BUTTON_CROUCH=true; + if (self.havocbot_ducktime>time) PHYS_INPUT_BUTTON_CROUCH(self) = true; keyboard = self.havocbot_keyboard; blend = bound(0,vlen(destorg-self.origin)/autocvar_bot_ai_keyboard_distance,1); // When getting close move with 360 degree @@ -273,7 +273,7 @@ void havocbot_bunnyhop(vector dir) if(self.aistatus & AI_STATUS_DANGER_AHEAD) { self.aistatus &= ~AI_STATUS_RUNNING; - self.BUTTON_JUMP = false; + PHYS_INPUT_BUTTON_JUMP(self) = false; self.bot_canruntogoal = 0; self.bot_timelastseengoal = 0; return; @@ -349,12 +349,12 @@ void havocbot_bunnyhop(vector dir) { self.aistatus &= ~AI_STATUS_RUNNING; if(bunnyhopdistance > autocvar_bot_ai_bunnyhop_stopdistance) - self.BUTTON_JUMP = true; + PHYS_INPUT_BUTTON_JUMP(self) = true; } else { self.aistatus |= AI_STATUS_RUNNING; - self.BUTTON_JUMP = true; + PHYS_INPUT_BUTTON_JUMP(self) = true; } } } @@ -374,7 +374,7 @@ void havocbot_bunnyhop(vector dir) if((IS_ONGROUND(self)) == 0) { if(self.velocity.z < 0 || vlen(self.velocity) self.rocketjumptime) { - self.BUTTON_ATCK2 = true; + PHYS_INPUT_BUTTON_ATCK2(self) = true; self.rocketjumptime = 0; } return; @@ -617,7 +617,7 @@ void havocbot_movetogoal() PS(self).m_switchweapon = WEP_DEVASTATOR; self.v_angle_x = 90; - self.BUTTON_ATCK = true; + PHYS_INPUT_BUTTON_ATCK(self) = true; self.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay); return; } @@ -638,9 +638,9 @@ void havocbot_movetogoal() if(self.waterlevel>WATERLEVEL_SWIMMING) dir.z = 1; else if(self.velocity.z >= 0 && !(self.waterlevel == WATERLEVEL_WETFEET && self.watertype == CONTENT_WATER)) - self.BUTTON_JUMP = true; + PHYS_INPUT_BUTTON_JUMP(self) = true; else - self.BUTTON_JUMP = false; + PHYS_INPUT_BUTTON_JUMP(self) = false; makevectors(self.v_angle.y * '0 1 0'); self.movement_x = dir * v_forward * maxspeed; self.movement_y = dir * v_right * maxspeed; @@ -696,9 +696,9 @@ void havocbot_movetogoal() { if(self.velocity.z >= 0 && !(self.watertype == CONTENT_WATER && gco.z < self.origin.z) && ( !(self.waterlevel == WATERLEVEL_WETFEET && self.watertype == CONTENT_WATER) || self.aistatus & AI_STATUS_OUT_WATER)) - self.BUTTON_JUMP = true; + PHYS_INPUT_BUTTON_JUMP(self) = true; else - self.BUTTON_JUMP = false; + PHYS_INPUT_BUTTON_JUMP(self) = false; } dir = normalize(flatdir); makevectors(self.v_angle.y * '0 1 0'); @@ -722,7 +722,7 @@ void havocbot_movetogoal() s = trace_fraction; tracebox(self.origin + jumpstepheightvec, self.mins, self.maxs, self.origin + self.velocity * 0.2 + jumpstepheightvec, false, self); if (trace_fraction > s) - self.BUTTON_JUMP = 1; + PHYS_INPUT_BUTTON_JUMP(self) = true; } } @@ -738,7 +738,7 @@ void havocbot_movetogoal() // Check head-banging against walls if(vlen(self.origin + self.view_ofs - trace_endpos) < 25 && !(self.aistatus & AI_STATUS_OUT_WATER)) { - self.BUTTON_JUMP = true; + PHYS_INPUT_BUTTON_JUMP(self) = true; if(self.facingwalltime && time > self.facingwalltime) { self.ignoregoal = self.goalcurrent; @@ -767,7 +767,7 @@ void havocbot_movetogoal() self.aistatus &= ~AI_STATUS_DANGER_AHEAD; if(trace_fraction == 1 && self.jumppadcount == 0 && !self.goalcurrent.wphardwired ) - if((IS_ONGROUND(self)) || (self.aistatus & AI_STATUS_RUNNING) || self.BUTTON_JUMP == true) + if((IS_ONGROUND(self)) || (self.aistatus & AI_STATUS_RUNNING) || PHYS_INPUT_BUTTON_JUMP(self)) { // Look downwards traceline(dst_ahead , dst_down, true, world); @@ -815,7 +815,7 @@ void havocbot_movetogoal() dir = normalize(dir + dodge + evadeobstacle + evadelava); // self.bot_dodgevector = dir; - // self.bot_dodgevector_jumpbutton = self.BUTTON_JUMP; + // self.bot_dodgevector_jumpbutton = PHYS_INPUT_BUTTON_JUMP(self); } if(time < self.ladder_time) @@ -834,7 +834,7 @@ void havocbot_movetogoal() //dir = self.bot_dodgevector; //if (self.bot_dodgevector_jumpbutton) - // self.BUTTON_JUMP = 1; + // PHYS_INPUT_BUTTON_JUMP(self) = true; self.movement_x = dir * v_forward * maxspeed; self.movement_y = dir * v_right * maxspeed; self.movement_z = dir * v_up * maxspeed; @@ -849,8 +849,8 @@ void havocbot_movetogoal() if(skill+self.bot_moveskill >= autocvar_bot_ai_bunnyhop_skilloffset) havocbot_bunnyhop(dir); - if ((dir * v_up) >= autocvar_sv_jumpvelocity*0.5 && (IS_ONGROUND(self))) self.BUTTON_JUMP=1; - if (((dodge * v_up) > 0) && random()*frametime >= 0.2*bound(0,(10-skill-self.bot_dodgeskill)*0.1,1)) self.BUTTON_JUMP=true; + if ((dir * v_up) >= autocvar_sv_jumpvelocity*0.5 && (IS_ONGROUND(self))) PHYS_INPUT_BUTTON_JUMP(self) = true; + if (((dodge * v_up) > 0) && random()*frametime >= 0.2*bound(0,(10-skill-self.bot_dodgeskill)*0.1,1)) PHYS_INPUT_BUTTON_JUMP(self) = true; if (((dodge * v_up) < 0) && random()*frametime >= 0.5*bound(0,(10-skill-self.bot_dodgeskill)*0.1,1)) self.havocbot_ducktime=time+0.3/bound(0.1,skill+self.bot_dodgeskill,10); } diff --git a/qcsrc/server/bot/scripting.qc b/qcsrc/server/bot/scripting.qc index f42adceef..7b349f479 100644 --- a/qcsrc/server/bot/scripting.qc +++ b/qcsrc/server/bot/scripting.qc @@ -824,13 +824,13 @@ const int BOT_CMD_KEY_CHAT = BIT(10); float bot_presskeys() {SELFPARAM(); self.movement = '0 0 0'; - self.BUTTON_JUMP = false; - self.BUTTON_CROUCH = false; - self.BUTTON_ATCK = false; - self.BUTTON_ATCK2 = false; - self.BUTTON_USE = false; - self.BUTTON_HOOK = false; - self.BUTTON_CHAT = false; + PHYS_INPUT_BUTTON_JUMP(self) = false; + PHYS_INPUT_BUTTON_CROUCH(self) = false; + PHYS_INPUT_BUTTON_ATCK(self) = false; + PHYS_INPUT_BUTTON_ATCK2(self) = false; + PHYS_INPUT_BUTTON_USE(self) = false; + PHYS_INPUT_BUTTON_HOOK(self) = false; + PHYS_INPUT_BUTTON_CHAT(self) = false; if(self.bot_cmd_keys == BOT_CMD_KEY_NONE) return false; @@ -846,25 +846,25 @@ float bot_presskeys() self.movement_y = -autocvar_sv_maxspeed; if(self.bot_cmd_keys & BOT_CMD_KEY_JUMP) - self.BUTTON_JUMP = true; + PHYS_INPUT_BUTTON_JUMP(self) = true; if(self.bot_cmd_keys & BOT_CMD_KEY_CROUCH) - self.BUTTON_CROUCH = true; + PHYS_INPUT_BUTTON_CROUCH(self) = true; if(self.bot_cmd_keys & BOT_CMD_KEY_ATTACK1) - self.BUTTON_ATCK = true; + PHYS_INPUT_BUTTON_ATCK(self) = true; if(self.bot_cmd_keys & BOT_CMD_KEY_ATTACK2) - self.BUTTON_ATCK2 = true; + PHYS_INPUT_BUTTON_ATCK2(self) = true; if(self.bot_cmd_keys & BOT_CMD_KEY_USE) - self.BUTTON_USE = true; + PHYS_INPUT_BUTTON_USE(self) = true; if(self.bot_cmd_keys & BOT_CMD_KEY_HOOK) - self.BUTTON_HOOK = true; + PHYS_INPUT_BUTTON_HOOK(self) = true; if(self.bot_cmd_keys & BOT_CMD_KEY_CHAT) - self.BUTTON_CHAT = true; + PHYS_INPUT_BUTTON_CHAT(self) = true; return true; } @@ -986,15 +986,14 @@ float bot_cmd_releasekey() float bot_cmd_pause() {SELFPARAM(); - self.button1 = 0; - self.button8 = 0; - self.BUTTON_USE = 0; - self.BUTTON_ATCK = 0; - self.BUTTON_JUMP = 0; - self.BUTTON_HOOK = 0; - self.BUTTON_CHAT = 0; - self.BUTTON_ATCK2 = 0; - self.BUTTON_CROUCH = 0; + PHYS_INPUT_BUTTON_DRAG(self) = false; + PHYS_INPUT_BUTTON_USE(self) = false; + PHYS_INPUT_BUTTON_ATCK(self) = false; + PHYS_INPUT_BUTTON_JUMP(self) = false; + PHYS_INPUT_BUTTON_HOOK(self) = false; + PHYS_INPUT_BUTTON_CHAT(self) = false; + PHYS_INPUT_BUTTON_ATCK2(self) = false; + PHYS_INPUT_BUTTON_CROUCH(self) = false; self.movement = '0 0 0'; self.bot_cmd_keys = BOT_CMD_KEY_NONE; @@ -1113,7 +1112,7 @@ void bot_setcurrentcommand() if(!self.bot_cmd_current) { - self.bot_cmd_current = new(bot_cmd); + self.bot_cmd_current = new_pure(bot_cmd); self.bot_cmd_current.is_bot_cmd = true; } diff --git a/qcsrc/server/bot/waypoints.qc b/qcsrc/server/bot/waypoints.qc index e2e505ace..178bc637c 100644 --- a/qcsrc/server/bot/waypoints.qc +++ b/qcsrc/server/bot/waypoints.qc @@ -28,7 +28,6 @@ entity waypoint_spawn(vector m1, vector m2, float f) } w = new(waypoint); - make_pure(w); w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; w.wpflags = f; setorigin(w, (m1 + m2) * 0.5); diff --git a/qcsrc/server/cheats.qc b/qcsrc/server/cheats.qc index c30e3d45a..b82b19a4a 100644 --- a/qcsrc/server/cheats.qc +++ b/qcsrc/server/cheats.qc @@ -12,6 +12,8 @@ #include "../common/deathtypes/all.qh" #include "../common/util.qh" +#include + #include "../common/monsters/all.qh" #include "../common/weapons/all.qh" @@ -34,7 +36,6 @@ float CheatCommand(float argc) { return 0; } float CheatFrame() { return 0; } void CheatInit() { cheatcount_total = world.cheatcount; } void CheatShutdown() { } -void CheatShutdownClient() { } void Drag_MoveDrag(entity from, entity to) { } #else @@ -53,10 +54,6 @@ void CheatShutdown() { } -void CheatShutdownClient() -{ -} - float CheatsAllowed(float i, float argc, float fr) // the cheat gets passed as argument for possible future ACL checking {SELFPARAM(); // dead people cannot cheat @@ -784,7 +781,7 @@ float Drag(float force_allow_pick, float ischeat) default: if(Drag_IsDragging(self)) { - if(self.BUTTON_DRAG) + if(PHYS_INPUT_BUTTON_DRAG(self)) { if(self.impulse == 10 || self.impulse == 15 || self.impulse == 18) { @@ -816,7 +813,7 @@ float Drag(float force_allow_pick, float ischeat) else { if(Drag_CanDrag(self)) - if(self.BUTTON_DRAG) + if(PHYS_INPUT_BUTTON_DRAG(self)) { crosshair_trace_plusvisibletriggers(self); entity e = trace_ent; diff --git a/qcsrc/server/cheats.qh b/qcsrc/server/cheats.qh index 7301df4a0..4ead519eb 100644 --- a/qcsrc/server/cheats.qh +++ b/qcsrc/server/cheats.qh @@ -9,7 +9,6 @@ float cheatcount_total; .float cheatcount; void CheatInit(); void CheatShutdown(); -void CheatShutdownClient(); float CheatImpulse(int imp); float CheatCommand(float argc); float CheatFrame(); diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 3f9fdd41b..6d5a4641a 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -23,7 +23,7 @@ #include "bot/navigation.qh" #include "../common/ent_cs.qh" -#include "../common/state.qh" +#include #include "../common/triggers/teleporters.qh" @@ -86,8 +86,7 @@ bool ClientData_Send(entity this, entity to, int sf) void ClientData_Attach(entity this) { - Net_LinkEntity(this.clientdata = new(clientdata), false, 0, ClientData_Send); - make_pure(this.clientdata); + Net_LinkEntity(this.clientdata = new_pure(clientdata), false, 0, ClientData_Send); self.clientdata.drawonlytoclient = this; self.clientdata.owner = this; } @@ -161,147 +160,138 @@ void setplayermodel(entity e, string modelname) player_setupanimsformodel(); } -/* -============= -PutObserverInServer - -putting a client as observer in the server -============= -*/ void FixPlayermodel(entity player); +/** putting a client as observer in the server */ void PutObserverInServer() { SELFPARAM(); + bool mutator_returnvalue = MUTATOR_CALLHOOK(MakePlayerObserver); PlayerState_detach(this); - entity spot; - self.hud = HUD_NORMAL; - - if(IS_PLAYER(self)) { Send_Effect(EFFECT_SPAWN_NEUTRAL, self.origin, '0 0 0', 1); } - - spot = SelectSpawnPoint (true); - if(!spot) - error("No spawnpoints for observers?!?\n"); - RemoveGrapplingHook(self); // Wazat's Grappling Hook - - if(IS_REAL_CLIENT(self)) - { - msg_entity = self; - WriteByte(MSG_ONE, SVC_SETVIEW); - WriteEntity(MSG_ONE, self); - } - - self.frags = FRAGS_SPECTATOR; - self.bot_attack = false; - bool mutator_returnvalue = MUTATOR_CALLHOOK(MakePlayerObserver); + if (IS_PLAYER(this) && this.health >= 1) { + // despawn effect + Send_Effect(EFFECT_SPAWN_NEUTRAL, this.origin, '0 0 0', 1); + } - Portal_ClearAll(self); + { + entity spot = SelectSpawnPoint(true); + if (!spot) LOG_FATAL("No spawnpoints for observers?!?"); + this.angles = spot.angles; + this.angles_z = 0; + this.fixangle = true; + // offset it so that the spectator spawns higher off the ground, looks better this way + setorigin(this, spot.origin + STAT(PL_VIEW_OFS, NULL)); + this.prevorigin = this.origin; + if (IS_REAL_CLIENT(this)) + { + msg_entity = this; + WriteByte(MSG_ONE, SVC_SETVIEW); + WriteEntity(MSG_ONE, this); + } + // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY + // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS" + setmodel(this, MDL_Null); + setsize(this, STAT(PL_CROUCH_MIN, NULL), STAT(PL_CROUCH_MAX, NULL)); + this.view_ofs = '0 0 0'; + } - Unfreeze(self); + RemoveGrapplingHook(this); + Portal_ClearAll(this); + Unfreeze(this); - if(self.alivetime) + if (this.alivetime) { - if(!warmup_stage) - PS_GR_P_ADDVAL(self, PLAYERSTATS_ALIVETIME, time - self.alivetime); - self.alivetime = 0; + if (!warmup_stage) + PS_GR_P_ADDVAL(this, PLAYERSTATS_ALIVETIME, time - this.alivetime); + this.alivetime = 0; } - if(self.vehicle) - vehicles_exit(VHEF_RELEASE); + if (this.vehicle) vehicles_exit(VHEF_RELEASE); - WaypointSprite_PlayerDead(self); + WaypointSprite_PlayerDead(this); - if(!mutator_returnvalue) // mutator prevents resetting teams - self.team = -1; // move this as it is needed to log the player spectating in eventlog + if (mutator_returnvalue) { + // mutator prevents resetting teams+score + } else { + this.team = -1; // move this as it is needed to log the player spectating in eventlog + this.frags = FRAGS_SPECTATOR; + PlayerScore_Clear(this); // clear scores when needed + } - if(self.killcount != FRAGS_SPECTATOR) + if (this.killcount != FRAGS_SPECTATOR) { - Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, self.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, this.netname); if(!intermission_running) if(autocvar_g_chat_nospectators == 1 || (!(warmup_stage || gameover) && autocvar_g_chat_nospectators == 2)) - Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CHAT_NOSPECTATORS); + Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CHAT_NOSPECTATORS); - if(self.just_joined == false) { - LogTeamchange(self.playerid, -1, 4); + if(this.just_joined == false) { + LogTeamchange(this.playerid, -1, 4); } else - self.just_joined = false; + this.just_joined = false; } - PlayerScore_Clear(self); // clear scores when needed - - accuracy_resend(self); + accuracy_resend(this); - self.spectatortime = time; - - self.classname = STR_OBSERVER; - self.iscreature = false; - self.teleportable = TELEPORT_SIMPLE; - self.damagedbycontents = false; - self.health = FRAGS_SPECTATOR; - self.takedamage = DAMAGE_NO; - self.solid = SOLID_NOT; - self.movetype = MOVETYPE_FLY_WORLDONLY; // user preference is controlled by playerprethink - self.flags = FL_CLIENT | FL_NOTARGET; - self.armorvalue = 666; - self.effects = 0; - self.armorvalue = autocvar_g_balance_armor_start; - self.pauserotarmor_finished = 0; - self.pauserothealth_finished = 0; - self.pauseregen_finished = 0; - self.damageforcescale = 0; - self.death_time = 0; - self.respawn_flags = 0; - self.respawn_time = 0; - self.stat_respawn_time = 0; - self.alpha = 0; - self.scale = 0; - self.fade_time = 0; - self.pain_frame = 0; - self.pain_finished = 0; - self.strength_finished = 0; - self.invincible_finished = 0; - self.superweapons_finished = 0; - self.pushltime = 0; - self.istypefrag = 0; - self.think = func_null; - self.nextthink = 0; - self.hook_time = 0; - self.deadflag = DEAD_NO; - self.angles = spot.angles; - self.angles_z = 0; - self.fixangle = true; - self.crouch = false; - self.revival_time = 0; - - setorigin (self, (spot.origin + STAT(PL_VIEW_OFS, NULL))); // offset it so that the spectator spawns higher off the ground, looks better this way - self.prevorigin = self.origin; - self.items = 0; - self.weapons = '0 0 0'; - self.model = ""; - FixPlayermodel(self); - setmodel(self, MDL_Null); - self.drawonlytoclient = self; - - setsize (self, STAT(PL_CROUCH_MIN, NULL), STAT(PL_CROUCH_MAX, NULL)); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY - self.view_ofs = '0 0 0'; // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS" - - PS(self).m_weapon = WEP_Null; - self.weaponname = ""; - PS(self).m_switchingweapon = WEP_Null; - self.weaponmodel = ""; + this.spectatortime = time; + this.bot_attack = false; + this.hud = HUD_NORMAL; + this.classname = STR_OBSERVER; + this.iscreature = false; + this.teleportable = TELEPORT_SIMPLE; + this.damagedbycontents = false; + this.health = FRAGS_SPECTATOR; + this.takedamage = DAMAGE_NO; + this.solid = SOLID_NOT; + this.movetype = MOVETYPE_FLY_WORLDONLY; // user preference is controlled by playerprethink + this.flags = FL_CLIENT | FL_NOTARGET; + this.armorvalue = 666; + this.effects = 0; + this.armorvalue = autocvar_g_balance_armor_start; + this.pauserotarmor_finished = 0; + this.pauserothealth_finished = 0; + this.pauseregen_finished = 0; + this.damageforcescale = 0; + this.death_time = 0; + this.respawn_flags = 0; + this.respawn_time = 0; + this.stat_respawn_time = 0; + this.alpha = 0; + this.scale = 0; + this.fade_time = 0; + this.pain_frame = 0; + this.pain_finished = 0; + this.strength_finished = 0; + this.invincible_finished = 0; + this.superweapons_finished = 0; + this.pushltime = 0; + this.istypefrag = 0; + this.think = func_null; + this.nextthink = 0; + this.hook_time = 0; + this.deadflag = DEAD_NO; + this.crouch = false; + this.revival_time = 0; + + this.items = 0; + this.weapons = '0 0 0'; + this.drawonlytoclient = this; + + this.weaponname = ""; + this.weaponmodel = ""; for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { - self.weaponentities[slot] = NULL; - } - self.exteriorweaponentity = world; - self.killcount = FRAGS_SPECTATOR; - self.velocity = '0 0 0'; - self.avelocity = '0 0 0'; - self.punchangle = '0 0 0'; - self.punchvector = '0 0 0'; - self.oldvelocity = self.velocity; - self.fire_endtime = -1; - self.event_damage = func_null; + this.weaponentities[slot] = NULL; + } + this.exteriorweaponentity = NULL; + this.killcount = FRAGS_SPECTATOR; + this.velocity = '0 0 0'; + this.avelocity = '0 0 0'; + this.punchangle = '0 0 0'; + this.punchvector = '0 0 0'; + this.oldvelocity = this.velocity; + this.fire_endtime = -1; + this.event_damage = func_null; } int player_getspecies(entity this) @@ -529,8 +519,7 @@ void PutClientInServer() this.revival_time = 0; this.air_finished = time + 12; - entity spawnevent = new(spawnevent); - make_pure(spawnevent); + entity spawnevent = new_pure(spawnevent); spawnevent.owner = this; Net_LinkEntity(spawnevent, false, 0.5, SpawnEvent_Send); @@ -557,7 +546,7 @@ void PutClientInServer() this.bot_attack = true; this.monster_attack = true; - this.BUTTON_ATCK = this.BUTTON_JUMP = this.BUTTON_ATCK2 = false; + PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_JUMP(this) = PHYS_INPUT_BUTTON_ATCK2(this) = false; if (this.killcount == FRAGS_SPECTATOR) { PlayerScore_Clear(this); @@ -670,8 +659,7 @@ void ClientInit_CheckUpdate() void ClientInit_Spawn() {SELFPARAM(); - entity e = new(clientinit); - make_pure(e); + entity e = new_pure(clientinit); e.think = ClientInit_CheckUpdate; Net_LinkEntity(e, false, 0, ClientInit_SendEntity); @@ -906,7 +894,7 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 self.killindicator.colormod = Team_ColorRGB(targetteam); if(IS_REAL_CLIENT(self)) if(self.killindicator.cnt > 0) - Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, APP_TEAM_NUM_4(targetteam, CENTER_TEAMCHANGE_), self.killindicator.cnt); + Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, APP_TEAM_NUM(targetteam, CENTER_TEAMCHANGE), self.killindicator.cnt); } } @@ -996,22 +984,7 @@ void ClientConnect() #endif this.version_nagtime = time + 10 + random() * 10; - // TODO: xonstat elo.txt support, until then just 404s - if (false && IS_REAL_CLIENT(this)) { PlayerStats_PlayerBasic_CheckUpdate(this); } - ClientState_attach(this); - // TODO: fold all of these into ClientState - DecodeLevelParms(this); - PlayerScore_Attach(this); - ClientData_Attach(this); - accuracy_init(this); - Inventory_new(this); - playerdemo_init(this); - anticheat_init(this); - entcs_attach(this); - W_HitPlotOpen(this); - - bot_clientconnect(this); // identify the right forced team if (autocvar_g_campaign) @@ -1078,27 +1051,16 @@ void ClientConnect() this.netname_previous = strzone(this.netname); - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((teamplay && IS_PLAYER(this)) ? APP_TEAM_ENT_4(this, INFO_JOIN_CONNECT_TEAM_) : INFO_JOIN_CONNECT), this.netname); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((teamplay && IS_PLAYER(this)) ? APP_TEAM_ENT(this, INFO_JOIN_CONNECT_TEAM) : INFO_JOIN_CONNECT), this.netname); stuffcmd(this, clientstuff, "\n"); stuffcmd(this, "cl_particles_reloadeffects\n"); // TODO do we still need this? FixClientCvars(this); - // Grappling hook - stuffcmd(this, "alias +hook +button6\n"); - stuffcmd(this, "alias -hook -button6\n"); - - // Jetpack binds - stuffcmd(this, "alias +jetpack +button10\n"); - stuffcmd(this, "alias -jetpack -button10\n"); - // get version info from player stuffcmd(this, "cmd clientversion $gameversion\n"); - // get other cvars from player - GetCvars(0); - // notify about available teams if (teamplay) { @@ -1167,45 +1129,24 @@ Called when a client disconnects from the server */ .entity chatbubbleentity; void ReadyCount(); -void ClientDisconnect () +void ClientDisconnect() { SELFPARAM(); - ClientState_detach(this); - if(self.vehicle) - vehicles_exit(VHEF_RELEASE); - - if (!IS_CLIENT(self)) - { - LOG_INFO("Warning: ClientDisconnect without ClientConnect\n"); - return; - } - - PlayerStats_GameReport_FinalizePlayer(self); - - if ( self.active_minigame ) - part_minigame(self); + assert(IS_CLIENT(this), return); - if(IS_PLAYER(self)) { Send_Effect(EFFECT_SPAWN_NEUTRAL, self.origin, '0 0 0', 1); } + PlayerStats_GameReport_FinalizePlayer(this); + if (this.vehicle) vehicles_exit(VHEF_RELEASE); + if (this.active_minigame) part_minigame(this); + if (IS_PLAYER(this)) Send_Effect(EFFECT_SPAWN_NEUTRAL, this.origin, '0 0 0', 1); - CheatShutdownClient(); - - W_HitPlotClose(self); - - anticheat_report(); - anticheat_shutdown(); - - playerdemo_shutdown(); - - bot_clientdisconnect(); - - entcs_detach(self); + if (autocvar_sv_eventlog) + GameLogEcho(strcat(":part:", ftos(this.playerid))); - if(autocvar_sv_eventlog) - GameLogEcho(strcat(":part:", ftos(self.playerid))); + Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, this.netname); - Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, self.netname); + MUTATOR_CALLHOOK(ClientDisconnect); - MUTATOR_CALLHOOK(ClientDisconnect); + ClientState_detach(this); Portal_ClearAll(self); @@ -1217,39 +1158,23 @@ void ClientDisconnect () self.flags &= ~FL_CLIENT; - if (self.chatbubbleentity) - remove (self.chatbubbleentity); - - if (self.killindicator) - remove (self.killindicator); + if (this.chatbubbleentity) remove(this.chatbubbleentity); + if (this.killindicator) remove(this.killindicator); WaypointSprite_PlayerGone(); bot_relinkplayerlist(); - accuracy_free(self); - Inventory_delete(self); - ClientData_Detach(this); - PlayerScore_Detach(self); + if (self.netname_previous) strunzone(self.netname_previous); + if (self.clientstatus) strunzone(self.clientstatus); + if (self.weaponorder_byimpulse) strunzone(self.weaponorder_byimpulse); + if (self.personal) remove(self.personal); - if(self.netname_previous) - strunzone(self.netname_previous); - if(self.clientstatus) - strunzone(self.clientstatus); - if(self.weaponorder_byimpulse) - strunzone(self.weaponorder_byimpulse); - - if(self.personal) - remove(self.personal); - - self.playerid = 0; + this.playerid = 0; ReadyCount(); - - // free cvars - GetCvars(-1); + if (vote_called && IS_REAL_CLIENT(this)) VoteCount(false); } -.float BUTTON_CHAT; void ChatBubbleThink() {SELFPARAM(); self.nextthink = time; @@ -1267,7 +1192,7 @@ void ChatBubbleThink() { if ( self.owner.active_minigame ) self.mdl = "models/sprites/minigame_busy.iqm"; - else if ( self.owner.BUTTON_CHAT ) + else if (PHYS_INPUT_BUTTON_CHAT(self.owner)) self.mdl = "models/misc/chatbubble.spr"; } @@ -1603,66 +1528,64 @@ spectate mode routines void SpectateCopy(entity this, entity spectatee) { - MUTATOR_CALLHOOK(SpectateCopy, spectatee, self); - self.armortype = spectatee.armortype; - self.armorvalue = spectatee.armorvalue; - self.ammo_cells = spectatee.ammo_cells; - self.ammo_plasma = spectatee.ammo_plasma; - self.ammo_shells = spectatee.ammo_shells; - self.ammo_nails = spectatee.ammo_nails; - self.ammo_rockets = spectatee.ammo_rockets; - self.ammo_fuel = spectatee.ammo_fuel; - self.clip_load = spectatee.clip_load; - self.clip_size = spectatee.clip_size; - self.effects = spectatee.effects & EFMASK_CHEAP; // eat performance - self.health = spectatee.health; - self.impulse = 0; - self.items = spectatee.items; - self.last_pickup = spectatee.last_pickup; - self.hit_time = spectatee.hit_time; - self.strength_finished = spectatee.strength_finished; - self.invincible_finished = spectatee.invincible_finished; - self.pressedkeys = spectatee.pressedkeys; - self.weapons = spectatee.weapons; - PS(self).m_switchweapon = PS(spectatee).m_switchweapon; - PS(self).m_switchingweapon = PS(spectatee).m_switchingweapon; - PS(self).m_weapon = PS(spectatee).m_weapon; - self.vortex_charge = spectatee.vortex_charge; - self.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo; - self.hagar_load = spectatee.hagar_load; - self.arc_heat_percent = spectatee.arc_heat_percent; - self.minelayer_mines = spectatee.minelayer_mines; - self.punchangle = spectatee.punchangle; - self.view_ofs = spectatee.view_ofs; - self.velocity = spectatee.velocity; - self.dmg_take = spectatee.dmg_take; - self.dmg_save = spectatee.dmg_save; - self.dmg_inflictor = spectatee.dmg_inflictor; - self.v_angle = spectatee.v_angle; - self.angles = spectatee.v_angle; - STAT(FROZEN, self) = STAT(FROZEN, spectatee); - self.revive_progress = spectatee.revive_progress; - if(!self.BUTTON_USE) - self.fixangle = true; - setorigin(self, spectatee.origin); - setsize(self, spectatee.mins, spectatee.maxs); + MUTATOR_CALLHOOK(SpectateCopy, spectatee, this); + PS(this) = PS(spectatee); + this.armortype = spectatee.armortype; + this.armorvalue = spectatee.armorvalue; + this.ammo_cells = spectatee.ammo_cells; + this.ammo_plasma = spectatee.ammo_plasma; + this.ammo_shells = spectatee.ammo_shells; + this.ammo_nails = spectatee.ammo_nails; + this.ammo_rockets = spectatee.ammo_rockets; + this.ammo_fuel = spectatee.ammo_fuel; + this.clip_load = spectatee.clip_load; + this.clip_size = spectatee.clip_size; + this.effects = spectatee.effects & EFMASK_CHEAP; // eat performance + this.health = spectatee.health; + this.impulse = 0; + this.items = spectatee.items; + this.last_pickup = spectatee.last_pickup; + this.hit_time = spectatee.hit_time; + this.strength_finished = spectatee.strength_finished; + this.invincible_finished = spectatee.invincible_finished; + this.pressedkeys = spectatee.pressedkeys; + this.weapons = spectatee.weapons; + this.vortex_charge = spectatee.vortex_charge; + this.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo; + this.hagar_load = spectatee.hagar_load; + this.arc_heat_percent = spectatee.arc_heat_percent; + this.minelayer_mines = spectatee.minelayer_mines; + this.punchangle = spectatee.punchangle; + this.view_ofs = spectatee.view_ofs; + this.velocity = spectatee.velocity; + this.dmg_take = spectatee.dmg_take; + this.dmg_save = spectatee.dmg_save; + this.dmg_inflictor = spectatee.dmg_inflictor; + this.v_angle = spectatee.v_angle; + this.angles = spectatee.v_angle; + STAT(FROZEN, this) = STAT(FROZEN, spectatee); + this.revive_progress = spectatee.revive_progress; + if(!PHYS_INPUT_BUTTON_USE(this)) + this.fixangle = true; + setorigin(this, spectatee.origin); + setsize(this, spectatee.mins, spectatee.maxs); SetZoomState(spectatee.zoomstate); anticheat_spectatecopy(spectatee); - self.hud = spectatee.hud; + this.hud = spectatee.hud; if(spectatee.vehicle) { - self.fixangle = false; - //self.velocity = spectatee.vehicle.velocity; - self.vehicle_health = spectatee.vehicle_health; - self.vehicle_shield = spectatee.vehicle_shield; - self.vehicle_energy = spectatee.vehicle_energy; - self.vehicle_ammo1 = spectatee.vehicle_ammo1; - self.vehicle_ammo2 = spectatee.vehicle_ammo2; - self.vehicle_reload1 = spectatee.vehicle_reload1; - self.vehicle_reload2 = spectatee.vehicle_reload2; - - msg_entity = self; + this.fixangle = false; + //this.velocity = spectatee.vehicle.velocity; + this.vehicle_health = spectatee.vehicle_health; + this.vehicle_shield = spectatee.vehicle_shield; + this.vehicle_energy = spectatee.vehicle_energy; + this.vehicle_ammo1 = spectatee.vehicle_ammo1; + this.vehicle_ammo2 = spectatee.vehicle_ammo2; + this.vehicle_reload1 = spectatee.vehicle_reload1; + this.vehicle_reload2 = spectatee.vehicle_reload2; + + msg_entity = this; WriteByte (MSG_ONE, SVC_SETVIEWANGLES); WriteAngle(MSG_ONE, spectatee.v_angle.x); @@ -1670,9 +1593,9 @@ void SpectateCopy(entity this, entity spectatee) WriteAngle(MSG_ONE, spectatee.v_angle.z); //WriteByte (MSG_ONE, SVC_SETVIEW); - // WriteEntity(MSG_ONE, self); + // WriteEntity(MSG_ONE, this); //makevectors(spectatee.v_angle); - //setorigin(self, spectatee.origin - v_forward * 400 + v_up * 300);*/ + //setorigin(this, spectatee.origin - v_forward * 400 + v_up * 300);*/ } } @@ -1823,11 +1746,11 @@ void LeaveSpectatorMode() if(autocvar_g_campaign) { campaign_bots_may_start = 1; } - Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN); + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CPID_PREVENT_JOIN); PutClientInServer(); - if(IS_PLAYER(self)) { Send_Notification(NOTIF_ALL, world, MSG_INFO, ((teamplay) ? APP_TEAM_ENT_4(this, INFO_JOIN_PLAY_TEAM_) : INFO_JOIN_PLAY), self.netname); } + if(IS_PLAYER(self)) { Send_Notification(NOTIF_ALL, world, MSG_INFO, ((teamplay && this.team != -1) ? APP_TEAM_ENT(this, INFO_JOIN_PLAY_TEAM) : INFO_JOIN_PLAY), self.netname); } } else stuffcmd(self, "menu_showteamselect\n"); @@ -1902,12 +1825,12 @@ void PrintWelcomeMessage() if(self.motd_actived_time == 0) { if (autocvar_g_campaign) { - if ((IS_PLAYER(self) && self.BUTTON_INFO) || (!IS_PLAYER(self))) { + if ((IS_PLAYER(self) && PHYS_INPUT_BUTTON_INFO(self)) || (!IS_PLAYER(self))) { self.motd_actived_time = time; Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, campaign_message); } } else { - if (self.BUTTON_INFO) { + if (PHYS_INPUT_BUTTON_INFO(self)) { self.motd_actived_time = time; Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage()); } @@ -1916,30 +1839,30 @@ void PrintWelcomeMessage() else if(self.motd_actived_time > 0) // showing MOTD or campaign message { if (autocvar_g_campaign) { - if (self.BUTTON_INFO) + if (PHYS_INPUT_BUTTON_INFO(self)) self.motd_actived_time = time; else if ((time - self.motd_actived_time > 2) && IS_PLAYER(self)) { // hide it some seconds after BUTTON_INFO has been released self.motd_actived_time = 0; - Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD); + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CPID_MOTD); } } else { - if (self.BUTTON_INFO) + if (PHYS_INPUT_BUTTON_INFO(self)) self.motd_actived_time = time; else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released self.motd_actived_time = 0; - Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD); + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CPID_MOTD); } } } else //if(self.motd_actived_time < 0) // just connected, motd is active { - if(self.BUTTON_INFO) // BUTTON_INFO hides initial MOTD + if(PHYS_INPUT_BUTTON_INFO(self)) // BUTTON_INFO hides initial MOTD self.motd_actived_time = -2; // wait until BUTTON_INFO gets released else if(self.motd_actived_time == -2 || IS_PLAYER(self) || IS_SPEC(self)) { // instanctly hide MOTD self.motd_actived_time = 0; - Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD); + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CPID_MOTD); } } } @@ -1953,21 +1876,21 @@ void ObserverThink() } float prefered_movetype; if (self.flags & FL_JUMPRELEASED) { - if (self.BUTTON_JUMP && !self.version_mismatch) { + if (PHYS_INPUT_BUTTON_JUMP(self) && !self.version_mismatch) { self.flags &= ~FL_JUMPRELEASED; self.flags |= FL_SPAWNING; - } else if(self.BUTTON_ATCK && !self.version_mismatch) { + } else if(PHYS_INPUT_BUTTON_ATCK(self) && !self.version_mismatch) { self.flags &= ~FL_JUMPRELEASED; if(SpectateNext()) { self.classname = STR_SPECTATOR; } } else { - prefered_movetype = ((!self.BUTTON_USE ? self.cvar_cl_clippedspectating : !self.cvar_cl_clippedspectating) ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP); + prefered_movetype = ((!PHYS_INPUT_BUTTON_USE(self) ? self.cvar_cl_clippedspectating : !self.cvar_cl_clippedspectating) ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP); if (self.movetype != prefered_movetype) self.movetype = prefered_movetype; } } else { - if (!(self.BUTTON_ATCK || self.BUTTON_JUMP)) { + if (!(PHYS_INPUT_BUTTON_ATCK(self) || PHYS_INPUT_BUTTON_JUMP(self))) { self.flags |= FL_JUMPRELEASED; if(self.flags & FL_SPAWNING) { @@ -1987,10 +1910,10 @@ void SpectatorThink() self.impulse = 0; } if (self.flags & FL_JUMPRELEASED) { - if (self.BUTTON_JUMP && !self.version_mismatch) { + if (PHYS_INPUT_BUTTON_JUMP(self) && !self.version_mismatch) { self.flags &= ~FL_JUMPRELEASED; self.flags |= FL_SPAWNING; - } else if(self.BUTTON_ATCK || self.impulse == 10 || self.impulse == 15 || self.impulse == 18 || (self.impulse >= 200 && self.impulse <= 209)) { + } else if(PHYS_INPUT_BUTTON_ATCK(self) || self.impulse == 10 || self.impulse == 15 || self.impulse == 18 || (self.impulse >= 200 && self.impulse <= 209)) { self.flags &= ~FL_JUMPRELEASED; if(SpectateNext()) { self.classname = STR_SPECTATOR; @@ -2008,7 +1931,7 @@ void SpectatorThink() PutClientInServer(); } self.impulse = 0; - } else if (self.BUTTON_ATCK2) { + } else if (PHYS_INPUT_BUTTON_ATCK2(self)) { self.flags &= ~FL_JUMPRELEASED; self.classname = STR_OBSERVER; PutClientInServer(); @@ -2017,7 +1940,7 @@ void SpectatorThink() PutObserverInServer(); } } else { - if (!(self.BUTTON_ATCK || self.BUTTON_ATCK2)) { + if (!(PHYS_INPUT_BUTTON_ATCK(self) || PHYS_INPUT_BUTTON_ATCK2(self))) { self.flags |= FL_JUMPRELEASED; if(self.flags & FL_SPAWNING) { @@ -2229,9 +2152,9 @@ void PlayerPreThink () if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button { - if(self.BUTTON_USE && !self.usekeypressed) + if(PHYS_INPUT_BUTTON_USE(self) && !self.usekeypressed) PlayerUseKey(); - self.usekeypressed = self.BUTTON_USE; + self.usekeypressed = PHYS_INPUT_BUTTON_USE(self); } if(IS_REAL_CLIENT(self)) @@ -2278,7 +2201,7 @@ void PlayerPreThink () float button_pressed; if(frametime) player_anim(); - button_pressed = (self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE); + button_pressed = (PHYS_INPUT_BUTTON_ATCK(self) || PHYS_INPUT_BUTTON_JUMP(self) || PHYS_INPUT_BUTTON_ATCK2(self) || PHYS_INPUT_BUTTON_HOOK(self) || PHYS_INPUT_BUTTON_USE(self)); if (self.deadflag == DEAD_DYING) { @@ -2328,7 +2251,7 @@ void PlayerPreThink () self.prevorigin = self.origin; - float do_crouch = self.BUTTON_CROUCH; + float do_crouch = PHYS_INPUT_BUTTON_CROUCH(self); if(self.hook.state) do_crouch = 0; if(self.vehicle) @@ -2415,10 +2338,10 @@ void PlayerPreThink () // WEAPONTODO: Add weapon request for this if(!zoomstate_set) SetZoomState( - self.BUTTON_ZOOM - || self.BUTTON_ZOOMSCRIPT - || (self.BUTTON_ATCK2 && PS(self).m_weapon == WEP_VORTEX) - || (self.BUTTON_ATCK2 && PS(self).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0) + PHYS_INPUT_BUTTON_ZOOM(self) + || PHYS_INPUT_BUTTON_ZOOMSCRIPT(self) + || (PHYS_INPUT_BUTTON_ATCK2(self) && PS(self).m_weapon == WEP_VORTEX) + || (PHYS_INPUT_BUTTON_ATCK2(self) && PS(self).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0) ); // WEAPONTODO float oldspectatee_status; @@ -2504,7 +2427,7 @@ void PlayerPostThink () if(self.idlekick_lasttimeleft) { self.idlekick_lasttimeleft = 0; - Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_IDLING); + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CPID_IDLING); } } else diff --git a/qcsrc/server/cl_impulse.qc b/qcsrc/server/cl_impulse.qc index 917a95f17..926eeacea 100644 --- a/qcsrc/server/cl_impulse.qc +++ b/qcsrc/server/cl_impulse.qc @@ -53,7 +53,11 @@ #define X(slot) \ IMPULSE(weapon_group_##slot) \ { \ - if (IS_DEAD(this)) return; \ + if (IS_DEAD(this)) \ + { \ + this.impulse = IMP_weapon_group_##slot.impulse; \ + return; \ + } \ W_NextWeaponOnImpulse(slot); \ } X(1) @@ -74,7 +78,11 @@ X(0) IMPULSE(weapon_priority_##slot##_##dir) \ { \ if (this.vehicle) return; \ - if (IS_DEAD(this)) return; \ + if (IS_DEAD(this)) \ + { \ + this.impulse = IMP_weapon_priority_##slot##_##dir.impulse; \ + return; \ + } \ noref int prev = -1; \ noref int best = 0; \ noref int next = +1; \ @@ -120,7 +128,11 @@ X(9, next) IMPULSE(weapon_byid_##i) \ { \ if (this.vehicle) return; \ - if (IS_DEAD(this)) return; \ + if (IS_DEAD(this)) \ + { \ + this.impulse = IMP_weapon_byid_##i.impulse; \ + return; \ + } \ W_SwitchWeapon(Weapons_from(WEP_FIRST + i)); \ } X(0) @@ -152,42 +164,66 @@ X(23) IMPULSE(weapon_next_byid) { if (this.vehicle) return; - if (IS_DEAD(this)) return; + if (IS_DEAD(this)) + { + this.impulse = IMP_weapon_next_byid.impulse; + return; + } W_NextWeapon(0); } IMPULSE(weapon_prev_byid) { if (this.vehicle) return; - if (IS_DEAD(this)) return; + if (IS_DEAD(this)) + { + this.impulse = IMP_weapon_prev_byid.impulse; + return; + } W_PreviousWeapon(0); } IMPULSE(weapon_next_bygroup) { if (this.vehicle) return; - if (IS_DEAD(this)) return; + if (IS_DEAD(this)) + { + this.impulse = IMP_weapon_next_bygroup.impulse; + return; + } W_NextWeapon(1); } IMPULSE(weapon_prev_bygroup) { if (this.vehicle) return; - if (IS_DEAD(this)) return; + if (IS_DEAD(this)) + { + this.impulse = IMP_weapon_prev_bygroup.impulse; + return; + } W_PreviousWeapon(1); } IMPULSE(weapon_next_bypriority) { if (this.vehicle) return; - if (IS_DEAD(this)) return; + if (IS_DEAD(this)) + { + this.impulse = IMP_weapon_next_bypriority.impulse; + return; + } W_NextWeapon(2); } IMPULSE(weapon_prev_bypriority) { if (this.vehicle) return; - if (IS_DEAD(this)) return; + if (IS_DEAD(this)) + { + this.impulse = IMP_weapon_prev_bypriority.impulse; + return; + } W_PreviousWeapon(2); } diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index fe0951e87..46743ce2e 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -361,7 +361,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, { this.pusher = attacker; this.pushltime = time + autocvar_g_maxpushtime; - this.istypefrag = this.BUTTON_CHAT; + this.istypefrag = PHYS_INPUT_BUTTON_CHAT(this); } else if(time < this.pushltime) { @@ -435,7 +435,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, { if(deathtype == DEATH_FALL.m_id) PlayerSound(this, playersound_fall, CH_PAIN, VOICETYPE_PLAYERSOUND); - else if(this.health > 75) // TODO make a "gentle" version? + else if(this.health > 75) PlayerSound(this, playersound_pain100, CH_PAIN, VOICETYPE_PLAYERSOUND); else if(this.health > 50) PlayerSound(this, playersound_pain75, CH_PAIN, VOICETYPE_PLAYERSOUND); @@ -514,7 +514,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, if(valid_damage_for_weaponstats) WeaponStats_LogKill(awep.m_id, abot, PS(this).m_weapon.m_id, vbot); - if(autocvar_sv_gentle < 1) // TODO make a "gentle" version? + if(autocvar_sv_gentle < 1) if(sound_allowed(MSG_BROADCAST, attacker)) { if(deathtype == DEATH_DROWN.m_id) diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index 5c052e2d9..9246f7aa1 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -179,8 +179,8 @@ void ClientCommand_join(float request) if (autocvar_g_campaign) campaign_bots_may_start = 1; self.classname = STR_PLAYER; PlayerScore_Clear(self); - Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN); - Send_Notification(NOTIF_ALL, world, MSG_INFO, ((teamplay) ? APP_TEAM_ENT_4(this, INFO_JOIN_PLAY_TEAM_) : INFO_JOIN_PLAY), self.netname); + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CPID_PREVENT_JOIN); + Send_Notification(NOTIF_ALL, world, MSG_INFO, ((teamplay && self.team != -1) ? APP_TEAM_ENT(this, INFO_JOIN_PLAY_TEAM) : INFO_JOIN_PLAY), self.netname); PutClientInServer(); } else diff --git a/qcsrc/server/command/common.qc b/qcsrc/server/command/common.qc index 4c155d07d..d2a8f6ec9 100644 --- a/qcsrc/server/command/common.qc +++ b/qcsrc/server/command/common.qc @@ -4,7 +4,7 @@ #include "../scores.qh" #include -#include +#include #include diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index 33e9273bb..056cb0db4 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -735,31 +735,6 @@ void GameCommand_extendmatchtime(float request) } } -void GameCommand_find(float request, float argc) // is this even needed? We have prvm_edicts command and such ANYWAY -{ - switch (request) - { - case CMD_REQUEST_COMMAND: - { - entity client; - - for (client = world; (client = find(client, classname, argv(1))); ) - LOG_INFO(etos(client), "\n"); - - return; - } - - default: - LOG_INFO("Incorrect parameters for ^2find^7\n"); - case CMD_REQUEST_USAGE: - { - LOG_INFO("\nUsage:^3 sv_cmd find classname\n"); - LOG_INFO(" Where 'classname' is the classname to search for.\n"); - return; - } - } -} - void GameCommand_gametype(float request, float argc) { switch (request) @@ -1778,7 +1753,6 @@ SERVER_COMMAND(defer_clear_all, "Clear all queued defer commands for all clients SERVER_COMMAND(delrec, "Delete race time record for a map") { GameCommand_delrec(request, arguments); } SERVER_COMMAND(effectindexdump, "Dump list of effects from code and effectinfo.txt") { GameCommand_effectindexdump(request); } SERVER_COMMAND(extendmatchtime, "Increase the timelimit value incrementally") { GameCommand_extendmatchtime(request); } -SERVER_COMMAND(find, "Search through entities for matching classname") { GameCommand_find(request, arguments); } SERVER_COMMAND(gametype, "Simple command to change the active gametype") { GameCommand_gametype(request, arguments); } SERVER_COMMAND(gettaginfo, "Get specific information about a weapon model") { GameCommand_gettaginfo(request, arguments); } SERVER_COMMAND(gotomap, "Simple command to switch to another map") { GameCommand_gotomap(request, arguments); } diff --git a/qcsrc/server/command/vote.qc b/qcsrc/server/command/vote.qc index 76f08bdc9..1e00e8562 100644 --- a/qcsrc/server/command/vote.qc +++ b/qcsrc/server/command/vote.qc @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include @@ -86,8 +86,7 @@ bool Nagger_SendEntity(entity this, entity to, float sendflags) void Nagger_Init() { - Net_LinkEntity(nagger = new(nagger), false, 0, Nagger_SendEntity); - make_pure(nagger); + Net_LinkEntity(nagger = new_pure(nagger), false, 0, Nagger_SendEntity); } void Nagger_VoteChanged() @@ -215,7 +214,7 @@ void VoteCount(float first_count) Nagger_VoteCountChanged(); // add up all the votes from each connected client - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA( + FOREACH_CLIENT(IS_REAL_CLIENT(it) && IS_CLIENT(it), LAMBDA( ++vote_player_count; if (IS_PLAYER(it)) ++vote_real_player_count; switch (it.vote_selection) @@ -445,8 +444,7 @@ void ReadyRestart_force() // initiate the restart-countdown-announcer entity if (autocvar_sv_ready_restart_after_countdown) { - entity restart_timer = new(restart_timer); - make_pure(restart_timer); + entity restart_timer = new_pure(restart_timer); restart_timer.think = ReadyRestart_think; restart_timer.nextthink = game_starttime; } diff --git a/qcsrc/server/command/vote.qh b/qcsrc/server/command/vote.qh index 98b000e75..0cab6c1d4 100644 --- a/qcsrc/server/command/vote.qh +++ b/qcsrc/server/command/vote.qh @@ -54,4 +54,5 @@ float restart_mapalreadyrestarted; // bool, indicates whether reset_map() was al void reset_map(float dorespawn); void ReadyCount(); void ReadyRestart_force(); +void VoteCount(float first_count); #endif diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index dd47b86a4..27755db96 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -6,22 +6,6 @@ #define INDEPENDENT_ATTACK_FINISHED 1 -// TODO: deprecated: remove. Replaced by physics.qh PHYS_INPUT_BUTTON_* - -#define BUTTON_ATCK button0 -#define BUTTON_JUMP button2 -#define BUTTON_ATCK2 button3 -#define BUTTON_ZOOM button4 -#define BUTTON_CROUCH button5 -#define BUTTON_HOOK button6 -#define BUTTON_INFO button7 -#define BUTTON_DRAG button8 -#define BUTTON_USE buttonuse -#define BUTTON_CHAT buttonchat -#define BUTTON_PRYDON cursor_active -#define BUTTON_ZOOMSCRIPT button9 -#define BUTTON_JETPACK button10 - // Globals float g_footsteps, g_grappling_hook, g_instagib; @@ -106,6 +90,7 @@ void() player_setupanimsformodel; .float scheduledrespawntime; .float respawntime; .float respawntimejitter; +.float respawntimestart; //.float chasecam; .float damageforcescale; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 23897720e..37ccf37eb 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -14,7 +14,7 @@ #include "weapons/selection.qh" #include "../common/constants.qh" #include "../common/deathtypes/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/physics/movetypes/movetypes.qh" #include "../common/playerstats.qh" #include "../common/teams.qh" @@ -125,7 +125,7 @@ string AppendItemcodes(string s, entity player) s = strcat(s, "I"); if(player.flagcarried != world) s = strcat(s, "F"); - if(player.BUTTON_CHAT) + if(PHYS_INPUT_BUTTON_CHAT(player)) s = strcat(s, "T"); if(player.kh_next) s = strcat(s, "K"); @@ -174,7 +174,7 @@ void Obituary_SpecialDeath( NOTIF_ONE, notif_target, MSG_MULTI, - deathent.death_msgmurder.nent_id, + deathent.death_msgmurder, s1, s2, s3, "", f1, f2, f3, 0 ); @@ -182,7 +182,7 @@ void Obituary_SpecialDeath( NOTIF_ALL_EXCEPT, notif_target, MSG_INFO, - deathent.death_msgmurder.nent_msginfo.nent_id, + deathent.death_msgmurder.nent_msginfo, s1, s2, s3, "", f1, f2, f3, 0 ); @@ -196,7 +196,7 @@ void Obituary_SpecialDeath( NOTIF_ONE, notif_target, MSG_MULTI, - deathent.death_msgself.nent_id, + deathent.death_msgself, s1, s2, s3, "", f1, f2, f3, 0 ); @@ -204,7 +204,7 @@ void Obituary_SpecialDeath( NOTIF_ALL_EXCEPT, notif_target, MSG_INFO, - deathent.death_msgself.nent_msginfo.nent_id, + deathent.death_msgself.nent_msginfo, s1, s2, s3, "", f1, f2, f3, 0 ); @@ -225,7 +225,7 @@ float Obituary_WeaponDeath( if (death_weapon != WEP_Null) { w_deathtype = deathtype; - int death_message = ((murder) ? death_weapon.wr_killmessage(death_weapon) : death_weapon.wr_suicidemessage(death_weapon)); + Notification death_message = ((murder) ? death_weapon.wr_killmessage(death_weapon) : death_weapon.wr_suicidemessage(death_weapon)); w_deathtype = false; if (death_message) @@ -238,11 +238,12 @@ float Obituary_WeaponDeath( s1, s2, s3, "", f1, f2, 0, 0 ); + // send the info part to everyone Send_Notification_WOCOVA( NOTIF_ALL_EXCEPT, notif_target, MSG_INFO, - msg_multi_notifs[death_message - 1].nent_msginfo.nent_id, + death_message.nent_msginfo, s1, s2, s3, "", f1, f2, 0, 0 ); @@ -342,7 +343,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype) Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname); Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker.netname); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(targ.team, INFO_DEATH_TEAMKILL_), targ.netname, attacker.netname, deathlocation, targ.killcount); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL), targ.netname, attacker.netname, deathlocation, targ.killcount); // In this case, the death message will ALWAYS be "foo was betrayed by bar" // No need for specific death/weapon messages... @@ -395,7 +396,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype) CHOICE_TYPEFRAG, targ.netname, kill_count_to_attacker, - (IS_BOT_CLIENT(targ) ? NO_MSG : targ.ping) + (IS_BOT_CLIENT(targ) ? -1 : targ.ping) ); Send_Notification( NOTIF_ONE, @@ -406,7 +407,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype) kill_count_to_target, attacker.health, attacker.armorvalue, - (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping) + (IS_BOT_CLIENT(attacker) ? -1 : attacker.ping) ); } else @@ -418,7 +419,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype) CHOICE_FRAG, targ.netname, kill_count_to_attacker, - (IS_BOT_CLIENT(targ) ? NO_MSG : targ.ping) + (IS_BOT_CLIENT(targ) ? -1 : targ.ping) ); Send_Notification( NOTIF_ONE, @@ -429,7 +430,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype) kill_count_to_target, attacker.health, attacker.armorvalue, - (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping) + (IS_BOT_CLIENT(attacker) ? -1 : attacker.ping) ); } @@ -800,7 +801,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d { if(deathtype != DEATH_FIRE.m_id) { - if(victim.BUTTON_CHAT) + if(PHYS_INPUT_BUTTON_CHAT(victim)) attacker.typehitsound += 1; else attacker.damage_dealt += damage; diff --git a/qcsrc/server/g_damage.qh b/qcsrc/server/g_damage.qh index 1f4f3b5d2..6a8ca99b4 100644 --- a/qcsrc/server/g_damage.qh +++ b/qcsrc/server/g_damage.qh @@ -16,7 +16,7 @@ #include "autocvars.qh" #include "constants.qh" #include "defs.qh" - #include "../common/notifications.qh" + #include "../common/notifications/all.qh" #include "../common/deathtypes/all.qh" #include "mutators/all.qh" #include "../common/turrets/sv_turrets.qh" diff --git a/qcsrc/server/g_hook.qc b/qcsrc/server/g_hook.qc index 4a3277928..c0509a3f6 100644 --- a/qcsrc/server/g_hook.qc +++ b/qcsrc/server/g_hook.qc @@ -251,7 +251,7 @@ void GrapplingHookThink() self.aiment.nextthink = time + autocvar_g_balance_grapplehook_nade_time; // set time after letting go? aim_ent.pusher = self.realowner; aim_ent.pushltime = time + autocvar_g_maxpushtime; - aim_ent.istypefrag = aim_ent.BUTTON_CHAT; + aim_ent.istypefrag = PHYS_INPUT_BUTTON_CHAT(aim_ent); } } @@ -333,7 +333,7 @@ void GrapplingHook_Damage(entity this, entity inflictor, entity attacker, float { this.realowner.pusher = attacker; this.realowner.pushltime = time + autocvar_g_maxpushtime; - this.realowner.istypefrag = this.realowner.BUTTON_CHAT; + this.realowner.istypefrag = PHYS_INPUT_BUTTON_CHAT(this.realowner); } RemoveGrapplingHook(this.realowner); } diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 5fc7b9f99..fac96e11f 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -24,7 +24,7 @@ #include "../common/monsters/all.qh" #include "../common/monsters/sv_monsters.qh" #include "../common/vehicles/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/physics/player.qh" #include "../common/playerstats.qh" #include "../common/stats.qh" @@ -80,8 +80,7 @@ void PingPLReport_Think() } void PingPLReport_Spawn() { - pingplreport = new(pingplreport); - make_pure(pingplreport); + pingplreport = new_pure(pingplreport); pingplreport.think = PingPLReport_Think; pingplreport.nextthink = time; } @@ -232,7 +231,6 @@ void cvar_changes_init() BADPREFIX("g_chat_flood_"); BADPREFIX("g_ghost_items"); BADPREFIX("g_playerstats_"); - BADPREFIX("g_respawn_ghosts"); BADPREFIX("g_voice_flood_"); BADPREFIX("log_file"); BADPREFIX("rcon_"); @@ -269,7 +267,9 @@ void cvar_changes_init() BADCVAR("g_nexball"); BADCVAR("g_onslaught"); BADCVAR("g_race"); + BADCVAR("g_race_laps_limit"); BADCVAR("g_race_qualifying_timelimit"); + BADCVAR("g_race_qualifying_timelimit_override"); BADCVAR("g_tdm"); BADCVAR("g_tdm_teams"); BADCVAR("leadlimit"); @@ -300,47 +300,53 @@ void cvar_changes_init() // now check if the changes are actually gameplay relevant - // does nothing visible + // does nothing gameplay relevant BADCVAR("captureleadlimit_override"); + BADCVAR("gameversion"); + BADCVAR("g_allow_oldvortexbeam"); BADCVAR("g_balance_kill_delay"); - BADCVAR("g_ca_point_limit"); + BADCVAR("g_campcheck_distance"); BADCVAR("g_ca_point_leadlimit"); + BADCVAR("g_ca_point_limit"); BADCVAR("g_ctf_captimerecord_always"); BADCVAR("g_ctf_flag_glowtrails"); BADCVAR("g_ctf_flag_pickup_verbosename"); BADCVAR("g_domination_point_leadlimit"); BADCVAR("g_forced_respawn"); - BADCVAR("g_freezetag_point_limit"); BADCVAR("g_freezetag_point_leadlimit"); - BADCVAR("g_keyhunt_point_leadlimit"); - BADPREFIX("g_mod_"); + BADCVAR("g_freezetag_point_limit"); + BADCVAR("g_hats"); BADCVAR("g_invasion_point_limit"); + BADCVAR("g_keyhunt_point_leadlimit"); BADCVAR("g_nexball_goalleadlimit"); - BADCVAR("g_tdm_point_limit"); BADCVAR("g_tdm_point_leadlimit"); + BADCVAR("g_tdm_point_limit"); BADCVAR("leadlimit_and_fraglimit"); BADCVAR("leadlimit_override"); BADCVAR("pausable"); BADCVAR("sv_allow_fullbright"); BADCVAR("sv_checkforpacketsduringsleep"); + BADCVAR("sv_intermission_cdtrack"); + BADCVAR("sv_minigames"); + BADCVAR("sv_namechangetimer"); + BADCVAR("sv_precacheplayermodels"); BADCVAR("sv_timeout"); - BADPREFIX("sv_timeout_"); BADPREFIX("crypto_"); + BADPREFIX("gameversion_"); BADPREFIX("g_chat_"); BADPREFIX("g_ctf_captimerecord_"); BADPREFIX("g_maplist_votable_"); + BADPREFIX("g_mod_"); + BADPREFIX("g_respawn_"); BADPREFIX("net_"); BADPREFIX("prvm_"); BADPREFIX("skill_"); BADPREFIX("sv_cullentities_"); BADPREFIX("sv_maxidle_"); + BADPREFIX("sv_minigames_"); + BADPREFIX("sv_timeout_"); BADPREFIX("sv_vote_"); BADPREFIX("timelimit_"); - BADCVAR("gameversion"); - BADPREFIX("gameversion_"); - BADCVAR("sv_minigames"); - BADPREFIX("sv_minigames_"); - BADCVAR("sv_namechangetimer"); // allowed changes to server admins (please sync this to server.cfg) // vi commands: @@ -385,7 +391,9 @@ void cvar_changes_init() BADCVAR("g_mirrordamage"); BADCVAR("g_nexball_goallimit"); BADCVAR("g_powerups"); + BADCVAR("g_spawnshieldtime"); BADCVAR("g_start_delay"); + BADCVAR("g_superspectate"); BADCVAR("g_tdm_teams_override"); BADCVAR("g_warmup"); BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay"); @@ -423,7 +431,6 @@ void cvar_changes_init() BADCVAR("sv_vote_simple_majority_factor"); BADCVAR("teamplay_mode"); BADCVAR("timelimit_override"); - BADCVAR("g_spawnshieldtime"); BADPREFIX("g_warmup_"); BADPREFIX("sv_ready_restart_"); @@ -515,8 +522,7 @@ void RandomSeed_Think() } void RandomSeed_Spawn() {SELFPARAM(); - randomseed = new(randomseed); - make_pure(randomseed); + randomseed = new_pure(randomseed); randomseed.think = RandomSeed_Think; Net_LinkEntity(randomseed, false, 0, RandomSeed_Send); @@ -1290,7 +1296,7 @@ void IntermissionThink() return; if(!mapvote_initialized) - if (time < intermission_exittime + 10 && !(self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE)) + if (time < intermission_exittime + 10 && !(PHYS_INPUT_BUTTON_ATCK(self) || PHYS_INPUT_BUTTON_JUMP(self) || PHYS_INPUT_BUTTON_ATCK2(self) || PHYS_INPUT_BUTTON_HOOK(self) || PHYS_INPUT_BUTTON_USE(self))) return; MapVote_Start(); @@ -1524,7 +1530,7 @@ void NextLevel() PlayerStats_GameReport(true); WeaponStats_Shutdown(); - Kill_Notification(NOTIF_ALL, world, MSG_CENTER, 0); // kill all centerprints now + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_Null); // kill all centerprints now if(autocvar_sv_eventlog) GameLogEcho(":gameover"); diff --git a/qcsrc/server/item_key.qc b/qcsrc/server/item_key.qc index d1e1f32e4..0230a21cb 100644 --- a/qcsrc/server/item_key.qc +++ b/qcsrc/server/item_key.qc @@ -2,7 +2,7 @@ #include "../common/triggers/subs.qh" #include "../common/monsters/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/util.qh" #include "../lib/warpzone/util_server.qh" diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 2a3ef8734..9e40e9d59 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -13,7 +13,7 @@ #include "../common/constants.qh" #include "../common/deathtypes/all.qh" #include "../common/mapinfo.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/playerstats.qh" #include "../common/teams.qh" #include "../common/triggers/subs.qh" @@ -375,6 +375,36 @@ string W_FixWeaponOrder_ForceComplete_AndBuildImpulseList(string wo) return o; } +REPLICATE(autoswitch, bool, "cl_autoswitch"); + +REPLICATE(cvar_cl_allow_uid2name, bool, "cl_allow_uid2name"); + +REPLICATE(cvar_cl_autoscreenshot, int, "cl_autoscreenshot"); + +REPLICATE(cvar_cl_autotaunt, float, "cl_autotaunt"); + +REPLICATE(cvar_cl_clippedspectating, bool, "cl_clippedspectating"); + +REPLICATE(cvar_cl_handicap, float, "cl_handicap"); + +REPLICATE(cvar_cl_jetpack_jump, bool, "cl_jetpack_jump"); + +REPLICATE(cvar_cl_movement_track_canjump, bool, "cl_movement_track_canjump"); + +REPLICATE(cvar_cl_newusekeysupported, bool, "cl_newusekeysupported"); + +REPLICATE(cvar_cl_noantilag, bool, "cl_noantilag"); + +REPLICATE(cvar_cl_physics, string, "cl_physics"); + +REPLICATE(cvar_cl_voice_directional, int, "cl_voice_directional"); + +REPLICATE(cvar_cl_voice_directional_taunt_attenuation, float, "cl_voice_directional_taunt_attenuation"); + +REPLICATE(cvar_cl_weaponimpulsemode, int, "cl_weaponimpulsemode"); + +REPLICATE(cvar_g_xonoticversion, string, "g_xonoticversion"); + /** * @param f -1: cleanup, 0: request, 1: receive */ @@ -393,13 +423,6 @@ void GetCvars(int f) ReplicateVars(this, s, f); - GetCvars_handleFloat(s, f, autoswitch, "cl_autoswitch"); - GetCvars_handleFloat(s, f, cvar_cl_autoscreenshot, "cl_autoscreenshot"); - GetCvars_handleFloat(s, f, cvar_cl_jetpack_jump, "cl_jetpack_jump"); - GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion"); - GetCvars_handleString(s, f, cvar_cl_physics, "cl_physics"); - GetCvars_handleFloat(s, f, cvar_cl_handicap, "cl_handicap"); - GetCvars_handleFloat(s, f, cvar_cl_clippedspectating, "cl_clippedspectating"); GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriority, "cl_weaponpriority", W_FixWeaponOrder_ForceComplete_AndBuildImpulseList); GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[0], "cl_weaponpriority0", W_FixWeaponOrder_AllowIncomplete); GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[1], "cl_weaponpriority1", W_FixWeaponOrder_AllowIncomplete); @@ -411,16 +434,8 @@ void GetCvars(int f) GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[7], "cl_weaponpriority7", W_FixWeaponOrder_AllowIncomplete); GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[8], "cl_weaponpriority8", W_FixWeaponOrder_AllowIncomplete); GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[9], "cl_weaponpriority9", W_FixWeaponOrder_AllowIncomplete); - GetCvars_handleFloat(s, f, cvar_cl_weaponimpulsemode, "cl_weaponimpulsemode"); - GetCvars_handleFloat(s, f, cvar_cl_autotaunt, "cl_autotaunt"); - GetCvars_handleFloat(s, f, cvar_cl_noantilag, "cl_noantilag"); - GetCvars_handleFloat(s, f, cvar_cl_voice_directional, "cl_voice_directional"); - GetCvars_handleFloat(s, f, cvar_cl_voice_directional_taunt_attenuation, "cl_voice_directional_taunt_attenuation"); - GetCvars_handleFloat(s, f, cvar_cl_allow_uid2name, "cl_allow_uid2name"); GetCvars_handleFloat(s, f, cvar_cl_allow_uidtracking, "cl_allow_uidtracking"); - GetCvars_handleFloat(s, f, cvar_cl_movement_track_canjump, "cl_movement_track_canjump"); - GetCvars_handleFloat(s, f, cvar_cl_newusekeysupported, "cl_newusekeysupported"); // fixup of switchweapon (needed for LMS or when spectating is disabled, as PutClientInServer comes too early) if (f > 0) diff --git a/qcsrc/server/mutators/all.qc b/qcsrc/server/mutators/all.qc index 5c6906b7c..2cca71c7c 100644 --- a/qcsrc/server/mutators/all.qc +++ b/qcsrc/server/mutators/all.qc @@ -34,7 +34,7 @@ #include "../autocvars.qh" #include "../constants.qh" #include "../defs.qh" - #include + #include #include #include "all.qh" #include diff --git a/qcsrc/server/mutators/gamemode.qh b/qcsrc/server/mutators/gamemode.qh index 5c17e9a17..b83704650 100644 --- a/qcsrc/server/mutators/gamemode.qh +++ b/qcsrc/server/mutators/gamemode.qh @@ -28,7 +28,7 @@ #include "../weapons/weaponsystem.qh" #include -#include +#include #include #include #include diff --git a/qcsrc/server/mutators/mutator.qh b/qcsrc/server/mutators/mutator.qh index c29e10eb8..485bce298 100644 --- a/qcsrc/server/mutators/mutator.qh +++ b/qcsrc/server/mutators/mutator.qh @@ -28,7 +28,7 @@ #include "../weapons/weaponsystem.qh" #include -#include +#include #include #include #include diff --git a/qcsrc/server/mutators/mutator/gamemode_ca.qc b/qcsrc/server/mutators/mutator/gamemode_ca.qc index c43eb88e0..57e96abf9 100644 --- a/qcsrc/server/mutators/mutator/gamemode_ca.qc +++ b/qcsrc/server/mutators/mutator/gamemode_ca.qc @@ -3,17 +3,45 @@ int autocvar_g_ca_point_limit; int autocvar_g_ca_point_leadlimit; +float autocvar_g_ca_round_timelimit; bool autocvar_g_ca_team_spawns; +int autocvar_g_ca_teams; +int autocvar_g_ca_teams_override; +float autocvar_g_ca_warmup; -void ca_Initialize(); + +int ca_teams; +bool allowed_to_spawn; + +const int ST_CA_ROUNDS = 1; + +bool CA_CheckTeams(); +bool CA_CheckWinner(); +void CA_RoundStart(); +bool ca_isEliminated(entity e); REGISTER_MUTATOR(ca, false) { MUTATOR_ONADD { - if (time > 1) // game loads at time 1 - error("This is a game type and it cannot be added at runtime."); - ca_Initialize(); + // game loads at time 1 + if (time > 1) error("This is a game type and it cannot be added at runtime."); + + allowed_to_spawn = true; + + ca_teams = autocvar_g_ca_teams_override; + if (ca_teams < 2) ca_teams = autocvar_g_ca_teams; + ca_teams = bound(2, ca_teams, 4); + ret_float = ca_teams; + + ScoreRules_basics(ca_teams, SFL_SORT_PRIO_PRIMARY, 0, true); + ScoreInfo_SetLabel_TeamScore(ST_CA_ROUNDS, "rounds", SFL_SORT_PRIO_PRIMARY); + ScoreRules_basics_end(); + + round_handler_Spawn(CA_CheckTeams, CA_CheckWinner, CA_RoundStart); + round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit); + + EliminatedPlayers_Init(ca_isEliminated); ActivateTeamplay(); SetLimits(autocvar_g_ca_point_limit, autocvar_g_ca_point_leadlimit, -1, -1); @@ -37,22 +65,7 @@ REGISTER_MUTATOR(ca, false) #ifdef IMPLEMENTATION float autocvar_g_ca_damage2score_multiplier; -float autocvar_g_ca_round_timelimit; bool autocvar_g_ca_spectate_enemies; -int autocvar_g_ca_teams; -int autocvar_g_ca_teams_override; -float autocvar_g_ca_warmup; - -float ca_teams; -float allowed_to_spawn; - -const float ST_CA_ROUNDS = 1; -void ca_ScoreRules(float teams) -{ - ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true); - ScoreInfo_SetLabel_TeamScore(ST_CA_ROUNDS, "rounds", SFL_SORT_PRIO_PRIMARY); - ScoreRules_basics_end(); -} void CA_count_alive_players() { @@ -120,8 +133,8 @@ float CA_CheckWinner() int winner_team = CA_GetWinnerTeam(); if(winner_team > 0) { - Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_)); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_)); + Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN)); TeamScore_AddToTeam(winner_team, ST_CA_ROUNDS, +1); } else if(winner_team == -1) @@ -140,10 +153,7 @@ float CA_CheckWinner() void CA_RoundStart() { - if(warmup_stage) - allowed_to_spawn = true; - else - allowed_to_spawn = false; + allowed_to_spawn = boolean(warmup_stage); } bool CA_CheckTeams() @@ -154,14 +164,14 @@ bool CA_CheckTeams() if(CA_ALIVE_TEAMS_OK()) { if(prev_missing_teams_mask > 0) - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_MISSING_TEAMS); prev_missing_teams_mask = -1; return true; } if(total_players == 0) { if(prev_missing_teams_mask > 0) - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_MISSING_TEAMS); prev_missing_teams_mask = -1; return false; } @@ -188,7 +198,7 @@ bool ca_isEliminated(entity e) /** Returns next available player to spectate if g_ca_spectate_enemies == 0 */ entity CA_SpectateNext(entity player, entity start) { - if (SAME_TEAM(start, player)) return start; + if (SAME_TEAM(start, player)) return start; // continue from current player for (entity e = start; (e = find(e, classname, STR_PLAYER)); ) { @@ -204,60 +214,57 @@ entity CA_SpectateNext(entity player, entity start) MUTATOR_HOOKFUNCTION(ca, PlayerSpawn) -{SELFPARAM(); - self.caplayer = 1; - if(!warmup_stage) +{ + SELFPARAM(); + this.caplayer = 1; + if (!warmup_stage) eliminatedPlayers.SendFlags |= 1; - return 1; } MUTATOR_HOOKFUNCTION(ca, PutClientInServer) -{SELFPARAM(); - if(!allowed_to_spawn) - if(IS_PLAYER(self)) // this is true even when player is trying to join +{ + SELFPARAM(); + if (!allowed_to_spawn && IS_PLAYER(this)) // this is true even when player is trying to join { - self.classname = STR_OBSERVER; - if(self.jointime != time) //not when connecting - if(!self.caplayer) + this.classname = STR_OBSERVER; + if (this.jointime != time && !this.caplayer) // not when connecting { - self.caplayer = 0.5; - if(IS_REAL_CLIENT(self)) - Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_JOIN_LATE); + this.caplayer = 0.5; + Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CA_JOIN_LATE); } } - return 1; } MUTATOR_HOOKFUNCTION(ca, reset_map_players) -{SELFPARAM(); - FOREACH_CLIENT(true, LAMBDA( - setself(it); - self.killcount = 0; - if(!self.caplayer && IS_BOT_CLIENT(self)) +{ + FOREACH_CLIENT(true, { + it.killcount = 0; + if (!it.caplayer && IS_BOT_CLIENT(it)) { - self.team = -1; - self.caplayer = 1; + it.team = -1; + it.caplayer = 1; } - if(self.caplayer) + if (it.caplayer) { - self.classname = STR_PLAYER; - self.caplayer = 1; - PutClientInServer(); + it.classname = STR_PLAYER; + it.caplayer = 1; + WITH(entity, self, it, PutClientInServer()); } - )); - return 1; + }); + return true; } MUTATOR_HOOKFUNCTION(ca, ClientConnect) -{SELFPARAM(); - self.classname = STR_OBSERVER; - return 1; +{ + SELFPARAM(); + this.classname = STR_OBSERVER; + return true; } MUTATOR_HOOKFUNCTION(ca, reset_map_global) { allowed_to_spawn = true; - return 1; + return true; } MUTATOR_HOOKFUNCTION(ca, GetTeamCount, CBC_ORDER_EXCLUSIVE) @@ -267,26 +274,27 @@ MUTATOR_HOOKFUNCTION(ca, GetTeamCount, CBC_ORDER_EXCLUSIVE) } entity ca_LastPlayerForTeam() -{SELFPARAM(); - entity last_pl = world; - FOREACH_CLIENT(IS_PLAYER(it) && it != self, LAMBDA( - if(!IS_DEAD(it)) - if(SAME_TEAM(self, it)) - if(!last_pl) +{ + SELFPARAM(); + entity last_pl = NULL; + FOREACH_CLIENT(IS_PLAYER(it) && it != this, { + if (!IS_DEAD(it)) + if (SAME_TEAM(this, it)) + if (!last_pl) last_pl = it; else - return world; - )); + return NULL; + }); return last_pl; } void ca_LastPlayerForTeam_Notify() { - if(round_handler_IsActive()) - if(round_handler_IsRoundStarted()) + if (round_handler_IsActive()) + if (round_handler_IsRoundStarted()) { entity pl = ca_LastPlayerForTeam(); - if(pl) + if (pl) Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE); } } @@ -294,16 +302,17 @@ void ca_LastPlayerForTeam_Notify() MUTATOR_HOOKFUNCTION(ca, PlayerDies) { ca_LastPlayerForTeam_Notify(); - if(!allowed_to_spawn) + if (!allowed_to_spawn) frag_target.respawn_flags = RESPAWN_SILENT; - if(!warmup_stage) + if (!warmup_stage) eliminatedPlayers.SendFlags |= 1; return 1; } MUTATOR_HOOKFUNCTION(ca, ClientDisconnect) -{SELFPARAM(); - if(self.caplayer == 1) +{ + SELFPARAM(); + if (this.caplayer == 1) ca_LastPlayerForTeam_Notify(); return 1; } @@ -314,16 +323,17 @@ MUTATOR_HOOKFUNCTION(ca, ForbidPlayerScore_Clear) } MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver) -{SELFPARAM(); - if(self.caplayer == 1) +{ + SELFPARAM(); + if (this.caplayer == 1) ca_LastPlayerForTeam_Notify(); - if(self.killindicator_teamchange == -2) - self.caplayer = 0; - if(self.caplayer) - self.frags = FRAGS_LMS_LOSER; - if(!warmup_stage) + if (this.killindicator_teamchange == -2) + this.caplayer = 0; + if (this.caplayer) + this.frags = FRAGS_LMS_LOSER; + if (!warmup_stage) eliminatedPlayers.SendFlags |= 1; - return true; + return true; // prevent team reset } MUTATOR_HOOKFUNCTION(ca, ForbidThrowCurrentWeapon) @@ -339,7 +349,7 @@ MUTATOR_HOOKFUNCTION(ca, GiveFragsForKill, CBC_ORDER_FIRST) MUTATOR_HOOKFUNCTION(ca, SetStartItems) { - start_items &= ~IT_UNLIMITED_AMMO; + start_items &= ~IT_UNLIMITED_AMMO; start_health = warmup_start_health = cvar("g_lms_start_health"); start_armorvalue = warmup_start_armorvalue = cvar("g_lms_start_armor"); start_ammo_shells = warmup_start_ammo_shells = cvar("g_lms_start_ammo_shells"); @@ -354,9 +364,9 @@ MUTATOR_HOOKFUNCTION(ca, SetStartItems) MUTATOR_HOOKFUNCTION(ca, PlayerDamage_Calculate) { - if(IS_PLAYER(frag_target)) - if(!IS_DEAD(frag_target)) - if(frag_target == frag_attacker || SAME_TEAM(frag_target, frag_attacker) || frag_deathtype == DEATH_FALL.m_id) + if (IS_PLAYER(frag_target)) + if (!IS_DEAD(frag_target)) + if (frag_target == frag_attacker || SAME_TEAM(frag_target, frag_attacker) || frag_deathtype == DEATH_FALL.m_id) frag_damage = 0; frag_mirrordamage = 0; @@ -365,12 +375,13 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDamage_Calculate) } MUTATOR_HOOKFUNCTION(ca, FilterItem) -{SELFPARAM(); - if(autocvar_g_powerups <= 0) - if(self.flags & FL_POWERUP) +{ + SELFPARAM(); + if (autocvar_g_powerups <= 0) + if (this.flags & FL_POWERUP) return true; - if(autocvar_g_pickup_items <= 0) + if (autocvar_g_pickup_items <= 0) return true; return false; @@ -380,7 +391,7 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDamage_SplitHealthArmor) { float excess = max(0, frag_damage - damage_take - damage_save); - if(frag_target != frag_attacker && IS_PLAYER(frag_attacker)) + if (frag_target != frag_attacker && IS_PLAYER(frag_attacker)) PlayerTeamScore_Add(frag_attacker, SP_SCORE, ST_SCORE, (frag_damage - excess) * autocvar_g_ca_damage2score_multiplier); return false; @@ -400,35 +411,37 @@ MUTATOR_HOOKFUNCTION(ca, Scores_CountFragsRemaining) MUTATOR_HOOKFUNCTION(ca, SpectateSet) { - if(!autocvar_g_ca_spectate_enemies && self.caplayer) - if(DIFF_TEAM(spec_player, self)) + SELFPARAM(); + if (!autocvar_g_ca_spectate_enemies && this.caplayer) + if (DIFF_TEAM(spec_player, this)) return true; return false; } MUTATOR_HOOKFUNCTION(ca, SpectateNext) -{SELFPARAM(); - if(!autocvar_g_ca_spectate_enemies && self.caplayer) +{ + SELFPARAM(); + if (!autocvar_g_ca_spectate_enemies && this.caplayer) { - spec_player = CA_SpectateNext(self, spec_player); + spec_player = CA_SpectateNext(this, spec_player); return true; } return false; } MUTATOR_HOOKFUNCTION(ca, SpectatePrev) -{SELFPARAM(); - if(!autocvar_g_ca_spectate_enemies && self.caplayer) +{ + SELFPARAM(); + if (!autocvar_g_ca_spectate_enemies && this.caplayer) { do { spec_player = spec_player.chain; } - while(spec_player && DIFF_TEAM(spec_player, self)); + while(spec_player && DIFF_TEAM(spec_player, this)); if (!spec_player) { - spec_player = spec_first; - while(spec_player && DIFF_TEAM(spec_player, self)) - spec_player = spec_player.chain; - if(spec_player == self.enemy) + for (spec_player = spec_first; spec_player && DIFF_TEAM(spec_player, this); spec_player = spec_player.chain); + + if (spec_player == this.enemy) return MUT_SPECPREV_RETURN; } } @@ -438,22 +451,22 @@ MUTATOR_HOOKFUNCTION(ca, SpectatePrev) MUTATOR_HOOKFUNCTION(ca, Bot_FixCount, CBC_ORDER_EXCLUSIVE) { - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA( - if(IS_PLAYER(it) || it.caplayer == 1) + FOREACH_CLIENT(IS_REAL_CLIENT(it), { + if (IS_PLAYER(it) || it.caplayer == 1) ++bot_activerealplayers; ++bot_realplayers; - )); - + }); return true; } MUTATOR_HOOKFUNCTION(ca, ClientCommand_Spectate) { - if(self.caplayer) + SELFPARAM(); + if (this.caplayer) { // they're going to spec, we can do other checks - if(autocvar_sv_spectate && (IS_SPEC(self) || IS_OBSERVER(self))) - Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_LEAVE); + if (autocvar_sv_spectate && (IS_SPEC(this) || IS_OBSERVER(this))) + Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CA_LEAVE); return MUT_SPECCMD_FORCE; } @@ -468,34 +481,13 @@ MUTATOR_HOOKFUNCTION(ca, WantWeapon) MUTATOR_HOOKFUNCTION(ca, GetPlayerStatus) { - if(set_player.caplayer == 1) - return true; - return false; + return set_player.caplayer == 1; } MUTATOR_HOOKFUNCTION(ca, SetWeaponArena) { // most weapons arena - if(ret_string == "0" || ret_string == "") - ret_string = "most"; - return false; -} - -void ca_Initialize() -{ - allowed_to_spawn = true; - - ca_teams = autocvar_g_ca_teams_override; - if(ca_teams < 2) - ca_teams = autocvar_g_ca_teams; - ca_teams = bound(2, ca_teams, 4); - ret_float = ca_teams; - ca_ScoreRules(ca_teams); - - round_handler_Spawn(CA_CheckTeams, CA_CheckWinner, CA_RoundStart); - round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit); - - EliminatedPlayers_Init(ca_isEliminated); + if (ret_string == "0" || ret_string == "") ret_string = "most"; } #endif diff --git a/qcsrc/server/mutators/mutator/gamemode_ctf.qc b/qcsrc/server/mutators/mutator/gamemode_ctf.qc index a8d2df201..a6d34c0d4 100644 --- a/qcsrc/server/mutators/mutator/gamemode_ctf.qc +++ b/qcsrc/server/mutators/mutator/gamemode_ctf.qc @@ -310,9 +310,9 @@ void ctf_CaptureRecord(entity flag, entity player) // notify about shit if(ctf_oneflag) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_CTF_CAPTURE_NEUTRAL, player.netname); } - else if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_TIME_), player.netname, (cap_time * 100)); } - else if(cap_time < cap_record) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_BROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); } - else { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_UNBROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); } + else if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT(flag, CHOICE_CTF_CAPTURE_TIME), player.netname, (cap_time * 100)); } + else if(cap_time < cap_record) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT(flag, CHOICE_CTF_CAPTURE_BROKEN), player.netname, refername, (cap_time * 100), (cap_record * 100)); } + else { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT(flag, CHOICE_CTF_CAPTURE_UNBROKEN), player.netname, refername, (cap_time * 100), (cap_record * 100)); } // write that shit in the database if(!ctf_oneflag) // but not in 1-flag mode @@ -510,7 +510,7 @@ void ctf_Handle_Drop(entity flag, entity player, int droptype) flag.ctf_status = FLAG_DROPPED; // messages and sounds - Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_LOST_) : INFO_CTF_LOST_NEUTRAL), player.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_LOST) : INFO_CTF_LOST_NEUTRAL), player.netname); _sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE); ctf_EventLog("dropped", player.team, player); @@ -572,11 +572,11 @@ void ctf_Handle_Retrieve(entity flag, entity player) FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA( if(it == sender) - Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_SENT_) : CENTER_CTF_PASS_SENT_NEUTRAL), player.netname); + Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT(flag, CENTER_CTF_PASS_SENT) : CENTER_CTF_PASS_SENT_NEUTRAL), player.netname); else if(it == player) - Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_RECEIVED_) : CENTER_CTF_PASS_RECEIVED_NEUTRAL), sender.netname); + Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT(flag, CENTER_CTF_PASS_RECEIVED) : CENTER_CTF_PASS_RECEIVED_NEUTRAL), sender.netname); else if(SAME_TEAM(it, sender)) - Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_OTHER_) : CENTER_CTF_PASS_OTHER_NEUTRAL), sender.netname, player.netname); + Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT(flag, CENTER_CTF_PASS_OTHER) : CENTER_CTF_PASS_OTHER_NEUTRAL), sender.netname, player.netname); )); // create new waypoint @@ -708,7 +708,7 @@ void ctf_Handle_Capture(entity flag, entity toucher, int capturetype) player.throw_count = 0; // messages and sounds - Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((enemy_flag.team) ? APP_TEAM_ENT_4(enemy_flag, CENTER_CTF_CAPTURE_) : CENTER_CTF_CAPTURE_NEUTRAL)); + Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((enemy_flag.team) ? APP_TEAM_ENT(enemy_flag, CENTER_CTF_CAPTURE) : CENTER_CTF_CAPTURE_NEUTRAL)); ctf_CaptureRecord(enemy_flag, player); _sound(player, CH_TRIGGER, ((ctf_oneflag) ? player_team_flag.snd_flag_capture : ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture)), VOL_BASE, ATTEN_NONE); @@ -752,12 +752,12 @@ void ctf_Handle_Return(entity flag, entity player) // messages and sounds if(IS_MONSTER(player)) { - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_MONSTER_), player.monster_name); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT(flag, INFO_CTF_RETURN_MONSTER), player.monster_name); } else if(flag.team) { - Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_RETURN_)); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_), player.netname); + Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT(flag, CENTER_CTF_RETURN)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT(flag, INFO_CTF_RETURN), player.netname); } _sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTEN_NONE); ctf_EventLog("return", flag.team, player); @@ -823,13 +823,13 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype) } // messages and sounds - Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_PICKUP_) : INFO_CTF_PICKUP_NEUTRAL), player.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_PICKUP) : INFO_CTF_PICKUP_NEUTRAL), player.netname); if(ctf_stalemate) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER); } if(!flag.team) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PICKUP_NEUTRAL); } - else if(CTF_DIFFTEAM(player, flag)) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PICKUP_)); } + else if(CTF_DIFFTEAM(player, flag)) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT(flag, CENTER_CTF_PICKUP)); } else { Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((SAME_TEAM(player, flag)) ? CENTER_CTF_PICKUP_TEAM : CENTER_CTF_PICKUP_TEAM_ENEMY), Team_ColorCode(flag.team)); } - Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, ((flag.team) ? APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_) : CHOICE_CTF_PICKUP_TEAM_NEUTRAL), Team_ColorCode(player.team), player.netname); + Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, ((flag.team) ? APP_TEAM_ENT(flag, CHOICE_CTF_PICKUP_TEAM) : CHOICE_CTF_PICKUP_TEAM_NEUTRAL), Team_ColorCode(player.team), player.netname); if(!flag.team) FOREACH_CLIENT(IS_PLAYER(it) && it != player && DIFF_TEAM(it, player), LAMBDA(Send_Notification(NOTIF_ONE, it, MSG_CHOICE, CHOICE_CTF_PICKUP_ENEMY_NEUTRAL, Team_ColorCode(player.team), player.netname))); @@ -838,7 +838,7 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype) FOREACH_CLIENT(IS_PLAYER(it) && it != player, LAMBDA( if(CTF_SAMETEAM(flag, it)) if(SAME_TEAM(player, it)) - Send_Notification(NOTIF_ONE, it, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_), Team_ColorCode(player.team), player.netname); + Send_Notification(NOTIF_ONE, it, MSG_CHOICE, APP_TEAM_ENT(flag, CHOICE_CTF_PICKUP_TEAM), Team_ColorCode(player.team), player.netname); else Send_Notification(NOTIF_ONE, it, MSG_CHOICE, ((SAME_TEAM(flag, player)) ? CHOICE_CTF_PICKUP_ENEMY_TEAM : CHOICE_CTF_PICKUP_ENEMY), Team_ColorCode(player.team), player.netname); )); @@ -902,14 +902,14 @@ void ctf_CheckFlagReturn(entity flag, int returntype) { switch(returntype) { - case RETURN_DROPPED: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DROPPED_) : INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL)); break; - case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DAMAGED_) : INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL)); break; - case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_) : INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL), ctf_captimerecord); break; - case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_NEEDKILL_) : INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL)); break; + case RETURN_DROPPED: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_DROPPED) : INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL)); break; + case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_DAMAGED) : INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL)); break; + case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_SPEEDRUN) : INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL), ctf_captimerecord); break; + case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_NEEDKILL) : INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL)); break; default: case RETURN_TIMEOUT: - { Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_TIMEOUT_) : INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL)); break; } + { Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_TIMEOUT) : INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL)); break; } } _sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTEN_NONE); ctf_EventLog("returned", flag.team, world); @@ -2437,7 +2437,7 @@ MUTATOR_HOOKFUNCTION(ctf, AbortSpeedrun) {SELFPARAM(); if(self.flagcarried) { - Send_Notification(NOTIF_ALL, world, MSG_INFO, ((self.flagcarried.team) ? APP_TEAM_ENT_4(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_) : INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, ((self.flagcarried.team) ? APP_TEAM_ENT(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN) : INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL)); ctf_RespawnFlag(self.flagcarried); return true; } @@ -2715,7 +2715,7 @@ void ctf_ScoreRules(int teams) // code from here on is just to support maps that don't have flag and team entities void ctf_SpawnTeam (string teamname, int teamcolor) { - entity this = new(ctf_team); + entity this = new_pure(ctf_team); this.netname = teamname; this.cnt = teamcolor; this.spawnfunc_checked = true; diff --git a/qcsrc/server/mutators/mutator/gamemode_domination.qc b/qcsrc/server/mutators/mutator/gamemode_domination.qc index 1259364f0..1c1620414 100644 --- a/qcsrc/server/mutators/mutator/gamemode_domination.qc +++ b/qcsrc/server/mutators/mutator/gamemode_domination.qc @@ -424,8 +424,8 @@ float Domination_CheckWinner() if(winner_team > 0) { - Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_)); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_)); + Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN)); TeamScore_AddToTeam(winner_team, ST_DOM_CAPS, +1); } else if(winner_team == -1) diff --git a/qcsrc/server/mutators/mutator/gamemode_freezetag.qc b/qcsrc/server/mutators/mutator/gamemode_freezetag.qc index abc5d8c5a..236ec2dd8 100644 --- a/qcsrc/server/mutators/mutator/gamemode_freezetag.qc +++ b/qcsrc/server/mutators/mutator/gamemode_freezetag.qc @@ -98,14 +98,14 @@ float freezetag_CheckTeams() if(FREEZETAG_ALIVE_TEAMS_OK()) { if(prev_missing_teams_mask > 0) - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_MISSING_TEAMS); prev_missing_teams_mask = -1; return 1; } if(total_players == 0) { if(prev_missing_teams_mask > 0) - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_MISSING_TEAMS); prev_missing_teams_mask = -1; return 0; } @@ -165,8 +165,8 @@ float freezetag_CheckWinner() int winner_team = freezetag_getWinnerTeam(); if(winner_team > 0) { - Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_)); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_)); + Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN)); TeamScore_AddToTeam(winner_team, ST_SCORE, +1); } else if(winner_team == -1) diff --git a/qcsrc/server/mutators/mutator/gamemode_invasion.qc b/qcsrc/server/mutators/mutator/gamemode_invasion.qc index b7730592c..64b710f22 100644 --- a/qcsrc/server/mutators/mutator/gamemode_invasion.qc +++ b/qcsrc/server/mutators/mutator/gamemode_invasion.qc @@ -279,8 +279,8 @@ float Invasion_CheckWinner() { if(winner_team) { - Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_)); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_)); + Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN)); } } else if(winner) diff --git a/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc b/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc index 6f8ec9551..6720f053a 100644 --- a/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc +++ b/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc @@ -499,7 +499,7 @@ void kh_Key_Collect(entity key, entity player) //a player picks up a dropped ke PlayerScore_Add(player, SP_KH_PICKUPS, 1); } key.kh_dropperteam = 0; - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_PICKUP_), player.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT(key, INFO_KEYHUNT_PICKUP), player.netname); kh_Key_AssignTo(key, player); // this also updates .kh_state } @@ -608,7 +608,7 @@ void kh_WinnerTeam(float teem) // runs when a team wins // Samual: Teem?.... TE first = false; } - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(teem, INFO_KEYHUNT_CAPTURE_), keyowner); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM(teem, INFO_KEYHUNT_CAPTURE), keyowner); first = true; midpoint = '0 0 0'; @@ -717,7 +717,7 @@ void kh_LoserTeam(float teem, entity lostkey) // runs when a player pushes a fl } } - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(lostkey, INFO_KEYHUNT_LOST_), lostkey.kh_previous_owner.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT(lostkey, INFO_KEYHUNT_LOST), lostkey.kh_previous_owner.netname); play2all(SND(KH_DESTROY)); te_tarexplosion(lostkey.origin); @@ -772,7 +772,7 @@ void kh_Key_Think() // runs all the time else Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_KEYHUNT_HELP); else - Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_TEAM_NUM_4(kh_interferemsg_team, CENTER_KEYHUNT_INTERFERE_)); + Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_TEAM_NUM(kh_interferemsg_team, CENTER_KEYHUNT_INTERFERE)); )); } @@ -830,7 +830,7 @@ void kh_Key_Spawn(entity initial_owner, float _angle, float i) // runs every ti key.kh_worldkeynext = kh_worldkeylist; kh_worldkeylist = key; - Send_Notification(NOTIF_ONE, initial_owner, MSG_CENTER, APP_TEAM_NUM_4(initial_owner.team, CENTER_KEYHUNT_START_)); + Send_Notification(NOTIF_ONE, initial_owner, MSG_CENTER, APP_TEAM_NUM(initial_owner.team, CENTER_KEYHUNT_START)); WaypointSprite_Spawn(WP_KeyDropped, 0, 0, key, '0 0 1' * KH_KEY_WP_ZSHIFT, world, key.team, key, waypointsprite_attachedforcarrier, false, RADARICON_FLAG); key.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = kh_Key_waypointsprite_visible_for_player; @@ -873,7 +873,7 @@ void kh_Key_DropOne(entity key) kh_Scores_Event(player, key, "dropkey", 0, 0); PlayerScore_Add(player, SP_KH_LOSSES, 1); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_DROP_), player.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT(key, INFO_KEYHUNT_DROP), player.netname); kh_Key_AssignTo(key, world); makevectors(player.v_angle); @@ -899,7 +899,7 @@ void kh_Key_DropAll(entity player, float suicide) // runs whenever a player dies { kh_Scores_Event(player, key, "losekey", 0, 0); PlayerScore_Add(player, SP_KH_LOSSES, 1); - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_LOST_), player.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT(key, INFO_KEYHUNT_LOST), player.netname); kh_Key_AssignTo(key, world); makevectors('-1 0 0' * (45 + 45 * random()) + '0 360 0' * random()); key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_dropvelocity * v_forward, false); @@ -919,7 +919,7 @@ float kh_CheckPlayers(float num) float t_team = kh_Team_ByID(num); float players = 0; FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( - if(!IS_DEAD(it) && !it.BUTTON_CHAT && it.team == t_team) + if(!IS_DEAD(it) && !PHYS_INPUT_BUTTON_CHAT(it) && it.team == t_team) ++players; )); @@ -943,7 +943,7 @@ void kh_WaitForPlayers() // delay start of the round until enough players are p if(KH_READY_TEAMS_OK()) { if(prev_missing_teams_mask > 0) - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_MISSING_TEAMS); prev_missing_teams_mask = -1; Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_ROUNDSTART, autocvar_g_balance_keyhunt_delay_round); kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, kh_StartRound); @@ -953,7 +953,7 @@ void kh_WaitForPlayers() // delay start of the round until enough players are p if(player_count == 0) { if(prev_missing_teams_mask > 0) - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_MISSING_TEAMS); prev_missing_teams_mask = -1; } else @@ -973,8 +973,8 @@ void kh_WaitForPlayers() // delay start of the round until enough players are p void kh_EnableTrackingDevice() // runs after each round { - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT); - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT_OTHER); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_KEYHUNT); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_KEYHUNT_OTHER); kh_tracking_enabled = true; } @@ -996,8 +996,8 @@ void kh_StartRound() // runs at the start of each round return; } - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT); - Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT_OTHER); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_KEYHUNT); + Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_KEYHUNT_OTHER); for(i = 0; i < kh_teams; ++i) { @@ -1005,7 +1005,7 @@ void kh_StartRound() // runs at the start of each round players = 0; entity my_player = world; FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( - if(!IS_DEAD(it) && !it.BUTTON_CHAT && it.team == teem) + if(!IS_DEAD(it) && !PHYS_INPUT_BUTTON_CHAT(it) && it.team == teem) { ++players; if(random() * players <= 1) diff --git a/qcsrc/server/mutators/mutator/gamemode_lms.qc b/qcsrc/server/mutators/mutator/gamemode_lms.qc index 77f6b6ca8..cbca46300 100644 --- a/qcsrc/server/mutators/mutator/gamemode_lms.qc +++ b/qcsrc/server/mutators/mutator/gamemode_lms.qc @@ -172,8 +172,6 @@ MUTATOR_HOOKFUNCTION(lms, PutClientInServer) self.classname = STR_OBSERVER; Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_NOLIVES); } - - return false; } MUTATOR_HOOKFUNCTION(lms, PlayerDies) @@ -204,9 +202,10 @@ MUTATOR_HOOKFUNCTION(lms, ClientDisconnect) } MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver) -{SELFPARAM(); - lms_RemovePlayer(self); - return false; +{ + SELFPARAM(); + lms_RemovePlayer(this); + return true; // prevent team reset } MUTATOR_HOOKFUNCTION(lms, ClientConnect) diff --git a/qcsrc/server/pathlib/_all.inc b/qcsrc/server/pathlib/_all.inc index 1b15654e4..7a06615bf 100644 --- a/qcsrc/server/pathlib/_all.inc +++ b/qcsrc/server/pathlib/_all.inc @@ -1,4 +1,6 @@ -#define DEBUGPATHING +#ifndef DEBUGPATHING + #define DEBUGPATHING 0 +#endif #include "costs.qc" #include "expandnode.qc" @@ -6,6 +8,6 @@ #include "movenode.qc" #include "path_waypoint.qc" #include "utility.qc" -#ifdef DEBUGPATHING +#if DEBUGPATHING #include "debug.qc" #endif diff --git a/qcsrc/server/pathlib/main.qc b/qcsrc/server/pathlib/main.qc index c78fc9320..f25348057 100644 --- a/qcsrc/server/pathlib/main.qc +++ b/qcsrc/server/pathlib/main.qc @@ -26,13 +26,12 @@ void dumpnode(entity n) n.nextthink = time; } -#ifdef DEBUGPATHING +#if DEBUGPATHING void pathlib_showpath(entity start); void pathlib_showpath2(entity path); +void pathlib_showsquare(vector where,float goodsquare,float _lifetime); #endif -void pathlib_showsquare(vector where,float goodsquare,float _lifetime); -void pathlib_showsquare2(entity node ,vector ncolor,float align); entity pathlib_mknode(vector where,entity parent) { @@ -60,8 +59,9 @@ entity pathlib_mknode(vector where,entity parent) setorigin(node, where); node.medium = pointcontents(where); +#if DEBUGPATHING pathlib_showsquare(where, 1 ,15); - +#endif ++pathlib_made_cnt; ++pathlib_open_cnt; @@ -157,7 +157,9 @@ float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector go if (!tile_check(where)) { LOG_TRACE("tile_check fail\n"); +#if DEBUGPATHING pathlib_showsquare(where, 0 ,30); +#endif return 0; } @@ -545,7 +547,7 @@ entity pathlib_astar(vector from,vector to) ctime = gettime(GETTIME_REALTIME) - ctime; -#ifdef DEBUGPATHING +#if DEBUGPATHING pathlib_showpath2(start); LOG_TRACE("Time used - pathfinding: ", ftos(ptime),"\n"); diff --git a/qcsrc/server/pathlib/pathlib.qh b/qcsrc/server/pathlib/pathlib.qh index 765fe2a7f..5c331d4b4 100644 --- a/qcsrc/server/pathlib/pathlib.qh +++ b/qcsrc/server/pathlib/pathlib.qh @@ -13,7 +13,7 @@ const vector PLIB_FORWARD = '0 1 0'; const vector PLIB_RIGHT = '1 0 0'; //#define PLIB_LEFT '-1 0 0' -#ifdef DEBUGPATHING +#if DEBUGPATHING void pathlib_showpath(entity start); void pathlib_showpath2(entity path); #endif diff --git a/qcsrc/server/playerdemo.qc b/qcsrc/server/playerdemo.qc index 6f263ae44..69ad7d0c6 100644 --- a/qcsrc/server/playerdemo.qc +++ b/qcsrc/server/playerdemo.qc @@ -59,11 +59,11 @@ void playerdemo_open_write(string f) PLAYERDEMO_FIELD(func,float,frame) \ PLAYERDEMO_FIELD(func,float,effects) \ /* PLAYERDEMO_FIELD(func,float,switchweapon) */ \ - PLAYERDEMO_FIELD(func,float,BUTTON_ATCK) \ - PLAYERDEMO_FIELD(func,float,BUTTON_ATCK2) \ - PLAYERDEMO_FIELD(func,float,BUTTON_CROUCH) \ - PLAYERDEMO_FIELD(func,float,BUTTON_HOOK) \ - PLAYERDEMO_FIELD(func,float,BUTTON_USE) \ + PLAYERDEMO_FIELD(func,float,button0) /* TODO: PHYS_INPUT_BUTTON_ATCK */ \ + PLAYERDEMO_FIELD(func,float,button3) /* TODO: PHYS_INPUT_BUTTON_ATCK2 */ \ + PLAYERDEMO_FIELD(func,float,button5) /* TODO: PHYS_INPUT_BUTTON_CROUCH */ \ + PLAYERDEMO_FIELD(func,float,button6) /* TODO: PHYS_INPUT_BUTTON_HOOK */ \ + PLAYERDEMO_FIELD(func,float,buttonuse) /* TODO: PHYS_INPUT_BUTTON_USE */ \ PLAYERDEMO_FIELD(func,float,flags) \ // end of list diff --git a/qcsrc/server/portals.qc b/qcsrc/server/portals.qc index 361abcd11..e3cba9383 100644 --- a/qcsrc/server/portals.qc +++ b/qcsrc/server/portals.qc @@ -4,7 +4,7 @@ #include "mutators/all.qh" #include "../common/constants.qh" #include "../common/deathtypes/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/triggers/teleporters.qh" #include "../common/triggers/subs.qh" #include "../common/util.qh" diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc index 0cac389aa..dd3a11cc0 100644 --- a/qcsrc/server/race.qc +++ b/qcsrc/server/race.qc @@ -8,7 +8,7 @@ #include "bot/navigation.qh" #include "command/getreplies.qh" #include "../common/deathtypes/all.qh" -#include "../common/notifications.qh" +#include "../common/notifications/all.qh" #include "../common/mapinfo.qh" #include "../common/triggers/subs.qh" #include "../lib/warpzone/util_server.qh" diff --git a/qcsrc/server/scores.qc b/qcsrc/server/scores.qc index e01a9904f..b7c994598 100644 --- a/qcsrc/server/scores.qc +++ b/qcsrc/server/scores.qc @@ -89,8 +89,7 @@ bool TeamScore_SendEntity(entity this, entity to, float sendflags) void TeamScore_Spawn(float t, string name) { - entity ts = new(csqc_score_team); - make_pure(ts); + entity ts = new_pure(csqc_score_team); ts.netname = name; // not used yet, FIXME ts.team = t; Net_LinkEntity(ts, false, 0, TeamScore_SendEntity); @@ -212,8 +211,7 @@ void ScoreInfo_Init(float teams) } else { - scores_initialized = new(ent_client_scoreinfo); - make_pure(scores_initialized); + scores_initialized = new_pure(ent_client_scoreinfo); Net_LinkEntity(scores_initialized, false, 0, ScoreInfo_SendEntity); } if(teams >= 1) @@ -319,8 +317,7 @@ void PlayerScore_Attach(entity player) { if(player.scorekeeper) error("player already has a scorekeeper"); - entity sk = new(scorekeeper); - make_pure(sk); + entity sk = new_pure(scorekeeper); sk.owner = player; Net_LinkEntity(sk, false, 0, PlayerScore_SendEntity); player.scorekeeper = sk; @@ -349,7 +346,7 @@ float PlayerScore_Add(entity player, float scorefield, float score) { if(gameover) return 0; - backtrace("Adding score to unknown player!"); + LOG_WARNING("Adding score to unknown player!"); return 0; } if(score) diff --git a/qcsrc/server/spawnpoints.qc b/qcsrc/server/spawnpoints.qc index 022e27608..0692d9088 100644 --- a/qcsrc/server/spawnpoints.qc +++ b/qcsrc/server/spawnpoints.qc @@ -15,9 +15,9 @@ bool SpawnPoint_Send(entity this, entity to, int sf) WriteHeader(MSG_ENTITY, ENT_CLIENT_SPAWNPOINT); WriteByte(MSG_ENTITY, self.team); - WriteShort(MSG_ENTITY, self.origin.x); - WriteShort(MSG_ENTITY, self.origin.y); - WriteShort(MSG_ENTITY, self.origin.z); + WriteCoord(MSG_ENTITY, self.origin.x); + WriteCoord(MSG_ENTITY, self.origin.y); + WriteCoord(MSG_ENTITY, self.origin.z); return true; } @@ -31,9 +31,9 @@ bool SpawnEvent_Send(entity this, entity to, int sf) if(autocvar_g_spawn_alloweffects) { WriteByte(MSG_ENTITY, etof(self.owner)); - WriteShort(MSG_ENTITY, self.owner.origin.x); - WriteShort(MSG_ENTITY, self.owner.origin.y); - WriteShort(MSG_ENTITY, self.owner.origin.z); + WriteCoord(MSG_ENTITY, self.owner.origin.x); + WriteCoord(MSG_ENTITY, self.owner.origin.y); + WriteCoord(MSG_ENTITY, self.owner.origin.z); send = true; } else if((to == self.owner) || (IS_SPEC(to) && (to.enemy == self.owner)) ) diff --git a/qcsrc/server/sys-post.qh b/qcsrc/server/sys-post.qh index 5b8dfd498..aca5969ba 100644 --- a/qcsrc/server/sys-post.qh +++ b/qcsrc/server/sys-post.qh @@ -14,6 +14,30 @@ var string(string name) cvar_string; var void(string name, string value) cvar_set; var void remove(entity e); +#undef IT_SHOTGUN +#undef IT_SUPER_SHOTGUN +#undef IT_NAILGUN +#undef IT_SUPER_NAILGUN +#undef IT_GRENADE_LAUNCHER +#undef IT_ROCKET_LAUNCHER +#undef IT_LIGHTNING +#undef IT_EXTRA_WEAPON +#undef IT_SHELLS +#undef IT_NAILS +#undef IT_ROCKETS +#undef IT_CELLS +#undef IT_AXE +#undef IT_ARMOR1 +#undef IT_ARMOR2 +#undef IT_ARMOR3 +#undef IT_SUPERHEALTH +#undef IT_KEY1 +#undef IT_KEY2 +#undef IT_INVISIBILITY +#undef IT_INVULNERABILITY +#undef IT_SUIT +#undef IT_QUAD + #pragma noref 0 #endif diff --git a/qcsrc/server/sys-pre.qh b/qcsrc/server/sys-pre.qh index 067e01409..be17b6923 100644 --- a/qcsrc/server/sys-pre.qh +++ b/qcsrc/server/sys-pre.qh @@ -8,6 +8,31 @@ #define cvar_string builtin_cvar_string #define cvar builtin_cvar +#define IT_SHOTGUN _IT_SHOTGUN /* BIT(0) */ +#define IT_SUPER_SHOTGUN _IT_SUPER_SHOTGUN /* BIT(1) */ +#define IT_NAILGUN _IT_NAILGUN /* BIT(2) */ +#define IT_SUPER_NAILGUN _IT_SUPER_NAILGUN /* BIT(3) */ +#define IT_GRENADE_LAUNCHER _IT_GRENADE_LAUNCHER /* BIT(4) */ +#define IT_ROCKET_LAUNCHER _IT_ROCKET_LAUNCHER /* BIT(5) */ +#define IT_LIGHTNING _IT_LIGHTNING /* BIT(6) */ +#define IT_EXTRA_WEAPON _IT_EXTRA_WEAPON /* BIT(7) */ +#define IT_SHELLS _IT_SHELLS /* BIT(8) */ +#define IT_NAILS _IT_NAILS /* BIT(9) */ +#define IT_ROCKETS _IT_ROCKETS /* BIT(10) */ +#define IT_CELLS _IT_CELLS /* BIT(11) */ +#define IT_AXE _IT_AXE /* BIT(12) */ +#define IT_ARMOR1 _IT_ARMOR1 /* BIT(13) */ +#define IT_ARMOR2 _IT_ARMOR2 /* BIT(14) */ +#define IT_ARMOR3 _IT_ARMOR3 /* BIT(15) */ +#define IT_SUPERHEALTH _IT_SUPERHEALTH /* BIT(16) */ +#define IT_KEY1 _IT_KEY1 /* BIT(17) */ +#define IT_KEY2 _IT_KEY2 /* BIT(18) */ +// FIXME: special meaning when used in client items stat +#define IT_INVISIBILITY _IT_INVISIBILITY /* BIT(19) */ +#define IT_INVULNERABILITY _IT_INVULNERABILITY /* BIT(20) */ +#define IT_SUIT _IT_SUIT /* BIT(21) */ +#define IT_QUAD _IT_QUAD /* BIT(22) */ + #pragma noref 1 #endif diff --git a/qcsrc/server/weapons/accuracy.qc b/qcsrc/server/weapons/accuracy.qc index 944811029..abb41ad06 100644 --- a/qcsrc/server/weapons/accuracy.qc +++ b/qcsrc/server/weapons/accuracy.qc @@ -39,8 +39,7 @@ bool accuracy_send(entity this, entity to, int sf) // init/free void accuracy_init(entity e) { - entity a = e.accuracy = new(accuracy); - make_pure(a); + entity a = e.accuracy = new_pure(accuracy); a.owner = e; a.drawonlytoclient = e; Net_LinkEntity(a, false, 0, accuracy_send); diff --git a/qcsrc/server/weapons/common.qc b/qcsrc/server/weapons/common.qc index c4a0daba4..85e8820f3 100644 --- a/qcsrc/server/weapons/common.qc +++ b/qcsrc/server/weapons/common.qc @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/qcsrc/server/weapons/spawning.qc b/qcsrc/server/weapons/spawning.qc index 578c941f7..579e6fdff 100644 --- a/qcsrc/server/weapons/spawning.qc +++ b/qcsrc/server/weapons/spawning.qc @@ -29,7 +29,7 @@ void weapon_defaultspawnfunc(entity this, Weapon e) { if (e.spawnflags & WEP_FLAG_MUTATORBLOCKED) { - objerror("Attempted to spawn a mutator-blocked weapon rejected"); + LOG_MAPWARNF("Attempted to spawn a mutator-blocked weapon rejected: prvm_edict server %i", this); startitem_failed = true; return; } diff --git a/qcsrc/server/weapons/throwing.qc b/qcsrc/server/weapons/throwing.qc index 14da0f14e..7ffc68105 100644 --- a/qcsrc/server/weapons/throwing.qc +++ b/qcsrc/server/weapons/throwing.qc @@ -6,7 +6,7 @@ #include "../g_damage.qh" #include #include -#include +#include #include #include #include diff --git a/qcsrc/server/weapons/tracing.qc b/qcsrc/server/weapons/tracing.qc index facf13f20..e924805fd 100644 --- a/qcsrc/server/weapons/tracing.qc +++ b/qcsrc/server/weapons/tracing.qc @@ -69,8 +69,8 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m // now move the shotorg forward as much as requested if possible if(antilag) { - if(ent.antilag_debug) - tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + v_forward * (vecs.x + nudge), MOVE_NORMAL, ent, ent.antilag_debug); + if(CS(ent).antilag_debug) + tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + v_forward * (vecs.x + nudge), MOVE_NORMAL, ent, CS(ent).antilag_debug); else tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + v_forward * (vecs.x + nudge), MOVE_NORMAL, ent, ANTILAG_LATENCY(ent)); } @@ -227,8 +227,8 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f o = self; while (1) { - if(self.antilag_debug) - WarpZone_traceline_antilag (self, start, end, false, o, self.antilag_debug); + if(CS(self).antilag_debug) + WarpZone_traceline_antilag (self, start, end, false, o, CS(self).antilag_debug); else WarpZone_traceline_antilag (self, start, end, false, o, ANTILAG_LATENCY(self)); if(o && WarpZone_trace_firstzone) @@ -382,6 +382,11 @@ void fireBullet(vector start, vector dir, float spread, float max_solid_penetrat )); } + // change shooter to SOLID_BBOX so the shot can hit corpses + int oldsolid = self.dphitcontentsmask; + if(self) + self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; + WarpZone_trace_forent = self; for (;;) @@ -397,8 +402,9 @@ void fireBullet(vector start, vector dir, float spread, float max_solid_penetrat if (pointcontents(start) == CONTENT_SKY) break; - if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) - break; + // can't use noimpact, as we need to pass through walls + //if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) + //break; // if we hit "weapclip", bail out // @@ -412,11 +418,11 @@ void fireBullet(vector start, vector dir, float spread, float max_solid_penetrat // matching shaders: // common/weapclip (intended) // common/noimpact (is supposed to eat projectiles, but is erased anyway) - float is_weapclip = 0; + bool is_weapclip = false; if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODRAW) if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID)) if (!(trace_dphitcontents & DPCONTENTS_OPAQUE)) - is_weapclip = 1; + is_weapclip = true; if(!hit || hit.solid == SOLID_BSP || hit.solid == SOLID_SLIDEBOX) Damage_DamageInfo(start, damage * solid_penetration_left, 0, 0, max(1, force) * dir * solid_penetration_left, dtype, hit.species, self); @@ -490,4 +496,8 @@ void fireBullet(vector start, vector dir, float spread, float max_solid_penetrat antilag_restore(it); )); } + + // restore shooter solid type + if(self) + self.dphitcontentsmask = oldsolid; } diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index 4972d818f..3fd9e896f 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -126,7 +126,11 @@ void CL_ExteriorWeaponentity_Think() this.weaponname = this.owner.weaponname; this.dmg = this.owner.modelindex; this.deadflag = this.owner.deadflag; - if (this.owner.weaponname != "") _setmodel(this, W_Model(strcat("v_", this.owner.weaponname, ".md3"))); + if (this.owner.weaponname != "") + { + _setmodel(this, W_Model(strcat("v_", this.owner.weaponname, ".md3"))); + setsize(this, '0 0 0', '0 0 0'); + } else this.model = ""; int tag_found; @@ -157,7 +161,6 @@ void CL_ExteriorWeaponentity_Think() void CL_SpawnWeaponentity(entity actor, .entity weaponentity) { entity view = actor.(weaponentity) = new(weaponentity); - make_pure(view); view.solid = SOLID_NOT; view.owner = actor; setmodel(view, MDL_Null); // precision set when changed @@ -171,7 +174,6 @@ void CL_SpawnWeaponentity(entity actor, .entity weaponentity) if (weaponentity == weaponentities[0]) { entity exterior = actor.exteriorweaponentity = new(exteriorweaponentity); - make_pure(exterior); exterior.solid = SOLID_NOT; exterior.owner = actor; setorigin(exterior, '0 0 0'); @@ -423,7 +425,7 @@ void W_WeaponFrame(entity actor) if (actor.(weaponentity).state != WS_CLEAR) { Weapon wpn = PS(actor).m_weapon; - w_ready(wpn, actor, weaponentity, (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0)); + w_ready(wpn, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); return; } } @@ -529,7 +531,7 @@ void W_WeaponFrame(entity actor) bool block_weapon = false; { - bool key_pressed = actor.BUTTON_HOOK && !actor.vehicle; + bool key_pressed = PHYS_INPUT_BUTTON_HOOK(actor) && !actor.vehicle; Weapon off = actor.offhand; if (off && !(actor.weapons & WEPSET(HOOK))) { @@ -541,7 +543,7 @@ void W_WeaponFrame(entity actor) W_SwitchWeapon(WEP_HOOK); actor.hook_switchweapon = key_pressed; Weapon h = WEP_HOOK; - block_weapon = (PS(actor).m_weapon == h && (actor.BUTTON_ATCK || key_pressed)); + block_weapon = (PS(actor).m_weapon == h && (PHYS_INPUT_BUTTON_ATCK(actor) || key_pressed)); h.wr_think(h, actor, weaponentity, block_weapon ? 1 : 0); } } @@ -555,7 +557,7 @@ void W_WeaponFrame(entity actor) if (w) { Weapon e = PS(actor).m_weapon; - e.wr_think(e, actor, weaponentity, (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0)); + e.wr_think(e, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); } else { @@ -573,7 +575,7 @@ void W_WeaponFrame(entity actor) v_up = up; Weapon wpn = PS(actor).m_weapon; this.weapon_think(wpn, actor, weaponentity, - (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0)); + PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); } else { @@ -677,7 +679,7 @@ void W_ReloadedAndReady(Weapon thiswep, entity actor, .entity weaponentity, int // ATTACK_FINISHED(actor, slot) -= actor.reload_time - 1; Weapon wpn = Weapons_from(PS(actor).m_weapon.m_id); - w_ready(wpn, actor, weaponentity, (actor.BUTTON_ATCK ? 1 : 0) | (actor.BUTTON_ATCK2 ? 2 : 0)); + w_ready(wpn, actor, weaponentity, PHYS_INPUT_BUTTON_ATCK(actor) | (PHYS_INPUT_BUTTON_ATCK2(actor) << 1)); } void W_Reload(entity actor, float sent_ammo_min, string sent_sound) diff --git a/scripts/weapons.shader b/scripts/weapons.shader index c5c673fbf..bef318392 100644 --- a/scripts/weapons.shader +++ b/scripts/weapons.shader @@ -31,11 +31,11 @@ glauncher rgbgen lightingDiffuse } } -hagar2 +hagar { dpreflectcube cubemaps/default/sky { - map textures/hagar2.tga + map textures/hagar.tga rgbgen lightingDiffuse } } @@ -111,3 +111,11 @@ shotgun rgbgen lightingDiffuse } } +SniperRifle +{ + dpreflectcube cubemaps/default/sky + { + map textures/sniperrifle.tga + rgbgen lightingDiffuse + } +} diff --git a/textures/campingrifle.tga b/textures/campingrifle.tga deleted file mode 100644 index 6189b51e9..000000000 Binary files a/textures/campingrifle.tga and /dev/null differ diff --git a/textures/campingrifle_bump.tga b/textures/campingrifle_bump.tga deleted file mode 100644 index 28bd453d6..000000000 Binary files a/textures/campingrifle_bump.tga and /dev/null differ diff --git a/textures/campingrifle_gloss.tga b/textures/campingrifle_gloss.tga deleted file mode 100644 index 7f4b0326d..000000000 Binary files a/textures/campingrifle_gloss.tga and /dev/null differ diff --git a/textures/campingrifle_glow.tga b/textures/campingrifle_glow.tga deleted file mode 100644 index f42532995..000000000 Binary files a/textures/campingrifle_glow.tga and /dev/null differ diff --git a/textures/campingrifle_screen.tga b/textures/campingrifle_screen.tga deleted file mode 100644 index 5ffda6faf..000000000 Binary files a/textures/campingrifle_screen.tga and /dev/null differ diff --git a/textures/hagar.tga b/textures/hagar.tga new file mode 100644 index 000000000..1e2d5cfdd Binary files /dev/null and b/textures/hagar.tga differ diff --git a/textures/hagar2.tga b/textures/hagar2.tga deleted file mode 100644 index f05fef985..000000000 Binary files a/textures/hagar2.tga and /dev/null differ diff --git a/textures/hagar2_gloss.tga b/textures/hagar2_gloss.tga deleted file mode 100644 index f4f597a4a..000000000 Binary files a/textures/hagar2_gloss.tga and /dev/null differ diff --git a/textures/hagar2_glow.tga b/textures/hagar2_glow.tga deleted file mode 100644 index cd4b35312..000000000 Binary files a/textures/hagar2_glow.tga and /dev/null differ diff --git a/textures/hagar2_norm.tga b/textures/hagar2_norm.tga deleted file mode 100644 index 145509deb..000000000 Binary files a/textures/hagar2_norm.tga and /dev/null differ diff --git a/textures/hagar2_reflect.tga b/textures/hagar2_reflect.tga deleted file mode 100644 index 1381edcd6..000000000 Binary files a/textures/hagar2_reflect.tga and /dev/null differ diff --git a/textures/hagar2_shirt.tga b/textures/hagar2_shirt.tga deleted file mode 100644 index 4527f7e31..000000000 Binary files a/textures/hagar2_shirt.tga and /dev/null differ diff --git a/textures/hagar_glow.tga b/textures/hagar_glow.tga new file mode 100644 index 000000000..e1d9548f7 Binary files /dev/null and b/textures/hagar_glow.tga differ diff --git a/textures/hagar_norm.tga b/textures/hagar_norm.tga new file mode 100644 index 000000000..b758791e3 Binary files /dev/null and b/textures/hagar_norm.tga differ diff --git a/textures/hagar_reflect.tga b/textures/hagar_reflect.tga new file mode 100644 index 000000000..f784c2db5 Binary files /dev/null and b/textures/hagar_reflect.tga differ diff --git a/textures/hagar_shirt.tga b/textures/hagar_shirt.tga new file mode 100644 index 000000000..270d4464a Binary files /dev/null and b/textures/hagar_shirt.tga differ diff --git a/textures/hagar_spec.tga b/textures/hagar_spec.tga new file mode 100644 index 000000000..e44d88ba0 Binary files /dev/null and b/textures/hagar_spec.tga differ diff --git a/textures/sniperrifle.tga b/textures/sniperrifle.tga new file mode 100644 index 000000000..0448be7f6 Binary files /dev/null and b/textures/sniperrifle.tga differ diff --git a/textures/sniperrifle_bump.tga b/textures/sniperrifle_bump.tga new file mode 100644 index 000000000..2496bcbce Binary files /dev/null and b/textures/sniperrifle_bump.tga differ diff --git a/textures/sniperrifle_glow.tga b/textures/sniperrifle_glow.tga new file mode 100644 index 000000000..776771371 Binary files /dev/null and b/textures/sniperrifle_glow.tga differ diff --git a/textures/sniperrifle_reflect.tga b/textures/sniperrifle_reflect.tga new file mode 100644 index 000000000..ecd89a973 Binary files /dev/null and b/textures/sniperrifle_reflect.tga differ