-csprogs.dat
-menu.dat
-progs.dat
-*.lno
+/*.dat
+/*.lno
+
.DS_Store
.idea/
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 '^:'
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 ""
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
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
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
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
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 ""
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
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
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
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
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
-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
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
// }}}
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
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.)"
// ===========
// 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"
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"
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"
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"
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"
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"
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"
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"
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"
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)"
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)"
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)"
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)"
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)"
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)"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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
-html/
-qccversion*
-*.d
+/html/
+/qccversion*
+/*.pk3
-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 ?= \
-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
#include "mutators/events.qh"
-#include <common/notifications.qh>
+#include <common/notifications/all.qh>
#include <common/stats.qh>
bool announcer_1min;
{
if(announcer_countdown)
{
- centerprint_kill(CPID_ROUND);
+ centerprint_kill(ORDINAL(CPID_ROUND));
if(announcer_countdown)
{
remove(announcer_countdown);
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;
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;
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;
}
}
-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)
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));
}
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
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 )
}
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();
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);
// 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;
registercvar("cl_jumpspeedcap_min", "");
registercvar("cl_jumpspeedcap_max", "");
- registercvar("cl_multijump", "0");
+ registercvar("cl_multijump", "1");
registercvar("cl_spawn_near_teammate", "1");
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))
// 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;
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;
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;
__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)
//{
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;
}
//}
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)
{
#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)
{
// 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);
return false;
}
-/** TODO somehow thwart prvm_globalset client ... */
string forcefog;
void Fog_Force()
{
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);
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;
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;
pos.y += height;
}
++column;
- ));
+ });
if (weapons_with_stats)
average_accuracy = floor((average_accuracy * 100 / weapons_with_stats) + 0.5);
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);
}
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;
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)
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)
{
if (!it.csqcmodel_isdead) setorigin(it, entcs.origin);
it.csqcmodel_isdead = dead;
Draw_ShowNames(it);
- ));
+ });
}
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 \
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;
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
{
// 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;
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;
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;
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()
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
{
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;
}
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
}
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);
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();
} else */
// draw 2D entities
- FOREACH_ENTITY(it.draw2d, LAMBDA(it.draw2d(it)));
+ FOREACH_ENTITY(it.draw2d, it.draw2d(it));
Draw_ShowNames_All();
Debug_Draw();
#include "mapinfo.qc"
#include "playerstats.qc"
+#ifdef SVQC
+ #include "state.qc"
+#endif
#include "util.qc"
#ifndef CSQC
#include "deathtypes/all.qc"
#include "effects/all.qc"
#include "impulses/all.qc"
-#include "notifications.qc"
+#include "notifications/all.qc"
#include "t_items.qc"
#endif
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; }
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"
#include "../mapinfo.qh"
#ifndef MENUQC
- #include "../notifications.qh"
+ #include "../notifications/all.qh"
#endif
#ifdef CSQC
// 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)
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... ",
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));
}
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)
#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)
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)
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() \
-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")
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, "")
#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)
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);
-#ifndef DEBUG_H
-#define DEBUG_H
+#pragma once
#ifndef MENUQC
.bool 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;
#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
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
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;
}
{
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;
}
}
+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;
+ }
+ }
+}
{
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;
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);
}
deathtype |= 0x8000;
e = new(damageinfo);
- make_pure(e);
setorigin(e, org);
e.projectiledeathtype = deathtype;
e.dmg = coredamage;
}
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;
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)
if(self.isplayermodel)
hitplayer = true; // this impact damaged a player
- }
+ });
setself(this);
if(DEATH_ISVEHICLE(w_deathtype))
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);
}
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
{
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);
{
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);
}
#endif
- string GlobalSound_sample(string pair, float r);
-
#ifdef CSQC
NET_HANDLE(globalsound, bool isnew)
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));
}
fclose(fh);
}
- #ifdef CSQC
+ //#ifdef CSQC
.string GetPlayerSoundSampleField(string type)
{
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)
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;
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;
? 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); \
} \
}
else
{
- FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA(
+ FOREACH_CLIENT(IS_REAL_CLIENT(it), {
msg_entity = it;
X();
- ));
+ });
}
#undef X
break;
}
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);
}
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)
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")
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
NET_HANDLE(ENT_CLIENT_MODELEFFECT, bool isnew)
{
- make_pure(self);
+ make_pure(this);
int f = ReadByte();
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)
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)
{
{
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);
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))
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);
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);
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));
}
}
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;
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));
+ });
}
}
}
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)
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;
}
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;
// 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;
// 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;
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;
}
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)
void Dump_Items()
{
- FOREACH(Items, true, LAMBDA(
- ITEM_HANDLE(Show, it);
- ));
+ FOREACH(Items, true, ITEM_HANDLE(Show, it));
}
string Item_Model(string item_mdl)
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();
{
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
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
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);
#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 */
#include "ammo.qh"
#include "powerup.qh"
+#ifndef SVQC
+.int m_itemid;
+#endif
+
#ifndef MENUQC
MODEL(Jetpack_ITEM, Item_Model("g_jetpack.md3"));
#endif
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";
this.m_waypointblink = 2;
#ifdef SVQC
this.m_botvalue = BOT_PICKUP_RATING_LOW;
- this.m_itemid = IT_JETPACK;
this.m_pickupevalfunc = commodity_pickupevalfunc;
#endif
}
#include "powerup.qh"
-#ifndef SVQC
-.int m_itemid;
-#endif
-
#ifndef MENUQC
MODEL(Strength_ITEM, Item_Model("g_strength.md3"));
SOUND(Strength, "misc/powerup");
#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;
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;
}
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;
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);
}
Gametype MapInfo_Type(int t)
{
- FOREACH(Gametypes, it.items == t, LAMBDA(return it));
+ FOREACH(Gametypes, it.items == t, return it);
return NULL;
}
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 "";
}
{
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");
}
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;
}
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)
#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)
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; \
{
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;
- }));
+ });
}
}
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()
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
}
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" )
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; \
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");
#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
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
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
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
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
|| (!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)
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;
bool mutator_log = false;
#ifndef MENUQC
+/** server mutators activate corresponding client mutators for all clients */
REGISTER_NET_LINKED(Mutator)
#ifdef SVQC
{
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)
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);
}
}
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)
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)
{
// 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);
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)
{
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;
}
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;
#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");
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);
}
}
) {
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);
#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)
{
{
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()
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);
}
}
.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)
#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)
{
#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)
{
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;
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;
{
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);
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;
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;
default:
case NADE_TYPE_NORMAL:
- expef = EFFECT_NADE_EXPLODE(self.realowner.team);
+ expef = EFFECT_NADE_EXPLODE(self.team);
break;
}
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)
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))
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));
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;
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)
//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;
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;
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;
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)
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;
void nades_CheckThrow()
{SELFPARAM();
- if(!CanThrowNade())
+ if(!CanThrowNade(self))
return;
entity held_nade = self.nade;
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);
}
}
}
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;
}
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) {
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);
}
}
}
{
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);
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;
}
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)
{
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;
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;
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
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);
}
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)
{
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;
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;
}
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;
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
e.angles_y = self.v_angle.y;
}
- WITH(entity, self, e, CSQCMODEL_AUTOINIT(e));
+ CSQCMODEL_AUTOINIT(e);
object_count += 1;
return e;
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;
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))
{
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))
{
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)
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
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);
)
{
entity wp = new(sprite_waypoint);
- make_pure(wp);
wp.teleport_time = time + _lifetime;
wp.fade_time = _lifetime;
wp.exteriormodeltoclient = ref;
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
}
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();
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;
#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
}
+++ /dev/null
-// ====================================
-// 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_)
+++ /dev/null
-#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 <server/mutators/all.qh>
-#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
+++ /dev/null
-#ifndef NOTIFICATIONS_H
-#define NOTIFICATIONS_H
-
-#include <common/command/all.qh>
-
-#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
--- /dev/null
+// ====================================
+// 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)
--- /dev/null
+#if defined(CSQC)
+ #include <client/announcer.qh>
+#elif defined(MENUQC)
+#elif defined(SVQC)
+ #include <common/constants.qh>
+ #include <common/teams.qh>
+ #include <server/autocvars.qh>
+ #include <server/constants.qh>
+ #include <server/defs.qh>
+ #include "all.qh"
+ #include <server/mutators/all.qh>
+#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
--- /dev/null
+#ifndef NOTIFICATIONS_H
+#define NOTIFICATIONS_H
+
+#include <common/command/all.qh>
+
+#include <common/constants.qh>
+#include <common/teams.qh>
+#include <common/util.qh>
+
+/** 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
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;
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;
}
_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;
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);
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);
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:
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;
}
// 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));
{
// 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!
{
// 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...
return true;
}
+#ifdef CSQC
+float autocvar_slowmo;
+#endif
+
void PM_Main(entity this)
{
int buttons = PHYS_INPUT_BUTTON_MASK(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
#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)
#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)
{
#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
}
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);
// collect final player information
PlayerStats_GameReport_FinalizePlayer(it);
- ));
+ });
if(autocvar_g_playerstats_gamereport_uri != "")
{
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);
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);
}
}
}
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)
#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");
auto = true; \
__chan = fabs(__chan); \
entity tmp = __e = new(csqc_autochannel); \
- make_pure(tmp); \
tmp.think = SUB_Remove_self; \
tmp.nextthink = time + soundlength(__samp); \
} \
--- /dev/null
+#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);
+}
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
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);
#include "constants.qh"
#include <common/deathtypes/all.qh>
- #include <common/notifications.qh>
+ #include <common/notifications/all.qh>
#include "triggers/subs.qh"
#include "util.qh"
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);
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);
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)
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))
{
}
// Savage: used for item garbage-collection
-// TODO: perhaps nice special effect?
void RemoveItem()
{SELFPARAM();
if(wasfreed(self) || !self) { return; }
c = 0;
// Detect needed ammo
- FOREACH(Weapons, it != WEP_Null, LAMBDA(
+ FOREACH(Weapons, it != WEP_Null, {
if(!(player.weapons & (it.m_wepset)))
continue;
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...
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;
}
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)
{
it.wr_init(it);
break;
}
- ));
+ });
}
}
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");
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;
+ });
}
}
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);
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;
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);
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);
#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
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
}
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;
}
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)
{
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)
{
_sound(it, CH_BGM_SINGLE, "", vol, ATTEN_NONE);
it.lastvol = vol;
}
- ));
+ });
music_trigger = world;
bgmtime = (best) ? getsoundtime(best, CH_BGM_SINGLE) : gettime(GETTIME_CDTRACK);
}
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)
{
player.pusher = teleporter.owner;
player.pushltime = time + autocvar_g_maxpushtime;
- player.istypefrag = player.BUTTON_CHAT;
+ player.istypefrag = PHYS_INPUT_BUTTON_CHAT(player);
}
else
{
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)
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)
NET_HANDLE(ENT_CLIENT_TARGET_PUSH, bool isnew)
{
- make_pure(this);
self.classname = "push_target";
self.cnt = ReadByte();
self.targetname = strzone(ReadString());
void trigger_teleport_link(entity this)
{
- trigger_link(this, trigger_teleport_send);
+ //trigger_link(this, trigger_teleport_send);
}
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);
{
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)
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)
// 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;
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");
}
}
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
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
#include "constants.qh"
#include "../client/mutators/events.qh"
#include "mapinfo.qh"
- #include "notifications.qh"
+ #include "notifications/all.qh"
#include <common/deathtypes/all.qh>
#elif defined(MENUQC)
#elif defined(SVQC)
#include "../server/autocvars.qh"
#include "../server/defs.qh"
#include "../server/mutators/events.qh"
- #include "notifications.qh"
+ #include "notifications/all.qh"
#include <common/deathtypes/all.qh>
#include "mapinfo.qh"
#endif
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;
#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:
{
break;
}
}
- return NOTIF_ABORT; // abort sending if none of these numbers were right
}
#endif
#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);
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
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);
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);
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();
_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)
{
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);
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;
}
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;
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;
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;
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
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
{
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;
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);
#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)
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;
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');
#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
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);
//{
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;
}
}
//}
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;
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];
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);
{
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);
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;
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');
}
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;
}
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
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;
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");
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;
}
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
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)
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
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
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)
}
if(self.wait != -10)
- if(!self.owner.BUTTON_ATCK2)
+ if(!PHYS_INPUT_BUTTON_ATCK2(self.owner))
return;
if(forbidWeaponUse(self.owner))
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:
//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)
{
#include <server/autocvars.qh>
#include <server/constants.qh>
#include <server/defs.qh>
- #include "../notifications.qh"
+ #include "../notifications/all.qh"
#include "../deathtypes/all.qh"
#include <server/mutators/all.qh>
#include "../mapinfo.qh"
{
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)
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);
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
this.weaponchild = NULL;
}
+ setsize(this, '0 0 0', '0 0 0');
setorigin(this, '0 0 0');
this.angles = '0 0 0';
this.frame = 0;
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)
#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)
{
}
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
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;
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)
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)
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;
/** (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 */
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;
||
gameover
||
- (!self.owner.BUTTON_ATCK && !burst )
+ (!PHYS_INPUT_BUTTON_ATCK(self.owner) && !burst )
||
STAT(FROZEN, self.owner)
||
{
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 )
}
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)
{
}
}
- 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
}
}
- 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
{
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))
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
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);
.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
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
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)
{
}
// 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);
}
}
- 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
return;
}
- if(actor.BUTTON_ATCK)
+ if(PHYS_INPUT_BUTTON_ATCK(actor))
{
if(!thiswep.wr_checkammo1(thiswep))
if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
}
}
- 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
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
#include <lib/csqcmodel/interpolate.qh>
#include <lib/warpzone/common.qh>
+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);
{
default:
case NET_ENT_CLIENT_HOOK:
- intensity = 1;
+ intensity = autocvar_cl_grapplehook_alpha;
offset = 0;
switch(t)
{
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))
}
- 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
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
.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
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()
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
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;
.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
// 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
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();
}
}
- 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
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
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();
.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
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;
}
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);
self.SendFlags |= 2;
break;
}
- ));
+ });
}
void W_Tuba_NoteOn(float hittype)
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;
}
}
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;
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;
}
}
- 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
.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
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
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
*/
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;
// 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
} 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)
#define LL_DELETE_2(this, dtor) \
MACRO_BEGIN \
{ \
- LL_CLEAR(this, dtor); \
+ LL_CLEAR_2(this, dtor); \
remove(this); \
this = NULL; \
} MACRO_END
#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
#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__))
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);
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()
{
.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 \
{ \
#define SPAWN_PURE 0
#endif
+// pure entities: need no .origin
#if SPAWN_PURE
entity spawn_pure() = #600;
#else
#ifdef CSQC
setorigin(this, '0 0 10000');
#endif
+ #ifdef SVQC
+ setorigin(this, '0 0 -10000');
+ #endif
}
return this;
}
STATIC_INIT(clearentity)
{
_clearentity_ent = new_pure(clearentity);
- make_pure(_clearentity_ent);
}
void clearentity(entity e)
{
* 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 */
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 { \
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); \
#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__
entity Sort_Spawn()
{
- entity sort = new(sortlist);
- make_pure(sort);
+ entity sort = new_pure(sortlist);
sort.sort_next = NULL;
sort.chain = sort;
return sort;
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) \
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(); }
}
#endif
-// TODO: macro
string seconds_tostring(float sec)
{
float minutes = floor(sec / 60);
// 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();
// 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;
{
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;
}
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;
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;
} 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)
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)
{
{
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);
}
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
.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),
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;
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
#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 { \
#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 <common/effects/all.qh>
#include <common/models/all.qh>
#include "defs.qh"
#include "miscfunctions.qh"
-
-
#include "command/common.qh"
+#include <common/state.qh>
.float anticheat_jointime;
// 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
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)
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;
}
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;
}
void anticheat_init(entity this);
void anticheat_report();
-void anticheat_shutdown();
void anticheat_physics(entity this);
void anticheat_spectatecopy(entity spectatee);
void anticheat_startframe();
void anticheat_endframe();
-void anticheat_fixangle();
+void anticheat_fixangle(entity this);
#endif
#if defined(CSQC)
#elif defined(MENUQC)
#elif defined(SVQC)
- #include "../common/vehicles/all.qh"
+ #include <common/state.qh>
+ #include <common/vehicles/all.qh>
#include "antilag.qh"
#endif
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
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;
}
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)
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)
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)
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
}
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;
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;
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;
// 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)
{
{
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;
}
}
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;
}
}
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
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;
{
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;
}
}
}
if((IS_ONGROUND(self)) == 0)
{
if(self.velocity.z < 0 || vlen(self.velocity)<maxspeed)
- self.BUTTON_JUMP = false;
+ PHYS_INPUT_BUTTON_JUMP(self) = false;
// Strafe
if(self.aistatus & AI_STATUS_RUNNING)
}
// Flying
- self.BUTTON_HOOK = true;
+ PHYS_INPUT_BUTTON_HOOK(self) = true;
if(self.navigation_jetpack_point.z - STAT(PL_MAX, NULL).z + STAT(PL_MIN, NULL).z < self.origin.z)
{
self.movement_x = dir * v_forward * maxspeed;
{
if(self.velocity.z<0)
{
- self.BUTTON_HOOK = true;
+ PHYS_INPUT_BUTTON_HOOK(self) = true;
}
}
else
- self.BUTTON_HOOK = true;
+ PHYS_INPUT_BUTTON_HOOK(self) = true;
// If there is no goal try to move forward
{
if(time > self.rocketjumptime)
{
- self.BUTTON_ATCK2 = true;
+ PHYS_INPUT_BUTTON_ATCK2(self) = true;
self.rocketjumptime = 0;
}
return;
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;
}
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;
{
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');
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;
}
}
// 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;
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);
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)
//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;
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);
}
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;
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;
}
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;
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;
}
}
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);
#include "../common/deathtypes/all.qh"
#include "../common/util.qh"
+#include <common/physics/player.qh>
+
#include "../common/monsters/all.qh"
#include "../common/weapons/all.qh"
float CheatFrame() { return 0; }
void CheatInit() { cheatcount_total = world.cheatcount; }
void CheatShutdown() { }
-void CheatShutdownClient() { }
void Drag_MoveDrag(entity from, entity to) { }
#else
{
}
-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
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)
{
else
{
if(Drag_CanDrag(self))
- if(self.BUTTON_DRAG)
+ if(PHYS_INPUT_BUTTON_DRAG(self))
{
crosshair_trace_plusvisibletriggers(self);
entity e = trace_ent;
.float cheatcount;
void CheatInit();
void CheatShutdown();
-void CheatShutdownClient();
float CheatImpulse(int imp);
float CheatCommand(float argc);
float CheatFrame();
#include "bot/navigation.qh"
#include "../common/ent_cs.qh"
-#include "../common/state.qh"
+#include <common/state.qh>
#include "../common/triggers/teleporters.qh"
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;
}
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)
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);
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);
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);
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);
}
}
#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)
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)
{
*/
.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);
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;
{
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";
}
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);
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);*/
}
}
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");
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());
}
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);
}
}
}
}
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)
{
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;
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();
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)
{
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))
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)
{
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)
// 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;
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
#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)
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; \
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)
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);
}
{
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)
{
{
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);
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)
#include <common/constants.qh>
#include <common/deathtypes/all.qh>
#include <common/mapinfo.qh>
-#include <common/notifications.qh>
+#include <common/notifications/all.qh>
#include <common/physics/player.qh>
#include <common/teams.qh>
#include <common/util.qh>
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
#include "../scores.qh"
#include <common/monsters/all.qh>
-#include <common/notifications.qh>
+#include <common/notifications/all.qh>
#include <lib/warpzone/common.qh>
#include <common/constants.qh>
#include <common/mapinfo.qh>
-#include <common/notifications.qh>
+#include <common/notifications/all.qh>
#include <common/teams.qh>
#include <common/util.qh>
}
}
-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)
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); }
#include <common/constants.qh>
#include <common/mapinfo.qh>
-#include <common/notifications.qh>
+#include <common/notifications/all.qh>
#include <common/playerstats.qh>
#include <common/util.qh>
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()
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)
// 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;
}
void reset_map(float dorespawn);
void ReadyCount();
void ReadyRestart_force();
+void VoteCount(float first_count);
#endif
#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;
.float scheduledrespawntime;
.float respawntime;
.float respawntimejitter;
+.float respawntimestart;
//.float chasecam;
.float damageforcescale;
#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"
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");
NOTIF_ONE,
notif_target,
MSG_MULTI,
- deathent.death_msgmurder.nent_id,
+ deathent.death_msgmurder,
s1, s2, s3, "",
f1, f2, f3, 0
);
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
);
NOTIF_ONE,
notif_target,
MSG_MULTI,
- deathent.death_msgself.nent_id,
+ deathent.death_msgself,
s1, s2, s3, "",
f1, f2, f3, 0
);
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
);
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)
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
);
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...
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,
kill_count_to_target,
attacker.health,
attacker.armorvalue,
- (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping)
+ (IS_BOT_CLIENT(attacker) ? -1 : attacker.ping)
);
}
else
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,
kill_count_to_target,
attacker.health,
attacker.armorvalue,
- (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping)
+ (IS_BOT_CLIENT(attacker) ? -1 : attacker.ping)
);
}
{
if(deathtype != DEATH_FIRE.m_id)
{
- if(victim.BUTTON_CHAT)
+ if(PHYS_INPUT_BUTTON_CHAT(victim))
attacker.typehitsound += 1;
else
attacker.damage_dealt += damage;
#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"
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);
}
}
{
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);
}
#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"
}
void PingPLReport_Spawn()
{
- pingplreport = new(pingplreport);
- make_pure(pingplreport);
+ pingplreport = new_pure(pingplreport);
pingplreport.think = PingPLReport_Think;
pingplreport.nextthink = time;
}
BADPREFIX("g_chat_flood_");
BADPREFIX("g_ghost_items");
BADPREFIX("g_playerstats_");
- BADPREFIX("g_respawn_ghosts");
BADPREFIX("g_voice_flood_");
BADPREFIX("log_file");
BADPREFIX("rcon_");
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");
// 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:
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");
BADCVAR("sv_vote_simple_majority_factor");
BADCVAR("teamplay_mode");
BADCVAR("timelimit_override");
- BADCVAR("g_spawnshieldtime");
BADPREFIX("g_warmup_");
BADPREFIX("sv_ready_restart_");
}
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);
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();
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");
#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"
#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"
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
*/
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);
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)
#include "../autocvars.qh"
#include "../constants.qh"
#include "../defs.qh"
- #include <common/notifications.qh>
+ #include <common/notifications/all.qh>
#include <common/deathtypes/all.qh>
#include "all.qh"
#include <common/turrets/sv_turrets.qh>
#include "../weapons/weaponsystem.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/stats.qh>
#include "../weapons/weaponsystem.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/stats.qh>
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);
#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()
{
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)
void CA_RoundStart()
{
- if(warmup_stage)
- allowed_to_spawn = true;
- else
- allowed_to_spawn = false;
+ allowed_to_spawn = boolean(warmup_stage);
}
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;
}
/** 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)); )
{
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)
}
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);
}
}
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;
}
}
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)
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");
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;
}
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;
{
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;
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;
}
}
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;
}
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
// 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
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);
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
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);
// 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);
}
// 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)));
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);
));
{
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);
{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;
}
// 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;
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)
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;
}
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)
{
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)
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
}
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';
}
}
- 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);
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));
));
}
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;
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);
{
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);
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;
));
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);
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
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;
}
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)
{
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)
self.classname = STR_OBSERVER;
Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_NOLIVES);
}
-
- return false;
}
MUTATOR_HOOKFUNCTION(lms, PlayerDies)
}
MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver)
-{SELFPARAM();
- lms_RemovePlayer(self);
- return false;
+{
+ SELFPARAM();
+ lms_RemovePlayer(this);
+ return true; // prevent team reset
}
MUTATOR_HOOKFUNCTION(lms, ClientConnect)
-#define DEBUGPATHING
+#ifndef DEBUGPATHING
+ #define DEBUGPATHING 0
+#endif
#include "costs.qc"
#include "expandnode.qc"
#include "movenode.qc"
#include "path_waypoint.qc"
#include "utility.qc"
-#ifdef DEBUGPATHING
+#if DEBUGPATHING
#include "debug.qc"
#endif
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)
{
setorigin(node, where);
node.medium = pointcontents(where);
+#if DEBUGPATHING
pathlib_showsquare(where, 1 ,15);
-
+#endif
++pathlib_made_cnt;
++pathlib_open_cnt;
if (!tile_check(where))
{
LOG_TRACE("tile_check fail\n");
+#if DEBUGPATHING
pathlib_showsquare(where, 0 ,30);
+#endif
return 0;
}
ctime = gettime(GETTIME_REALTIME) - ctime;
-#ifdef DEBUGPATHING
+#if DEBUGPATHING
pathlib_showpath2(start);
LOG_TRACE("Time used - pathfinding: ", ftos(ptime),"\n");
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
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
#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"
#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"
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);
}
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)
{
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;
{
if(gameover)
return 0;
- backtrace("Adding score to unknown player!");
+ LOG_WARNING("Adding score to unknown player!");
return 0;
}
if(score)
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;
}
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)) )
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
#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
// 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);
#include <common/t_items.qh>
#include <common/constants.qh>
#include <common/deathtypes/all.qh>
-#include <common/notifications.qh>
+#include <common/notifications/all.qh>
#include <common/util.qh>
#include <common/weapons/all.qh>
#include <common/items/all.qc>
{
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;
}
#include "../g_damage.qh"
#include <common/items/item.qh>
#include <common/mapinfo.qh>
-#include <common/notifications.qh>
+#include <common/notifications/all.qh>
#include <common/triggers/subs.qh>
#include <common/util.qh>
#include <common/weapons/all.qh>
// 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));
}
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)
));
}
+ // 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 (;;)
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
//
// 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);
antilag_restore(it);
));
}
+
+ // restore shooter solid type
+ if(self)
+ self.dphitcontentsmask = oldsolid;
}
#include <common/animdecide.qh>
#include <common/constants.qh>
#include <common/monsters/all.qh>
-#include <common/notifications.qh>
+#include <common/notifications/all.qh>
#include <common/util.qh>
#include <common/weapons/all.qh>
#include <lib/csqcmodel/sv_model.qh>
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;
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
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');
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;
}
}
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)))
{
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);
}
}
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
{
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
{
// 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)
rgbgen lightingDiffuse
}
}
-hagar2
+hagar
{
dpreflectcube cubemaps/default/sky
{
- map textures/hagar2.tga
+ map textures/hagar.tga
rgbgen lightingDiffuse
}
}
rgbgen lightingDiffuse
}
}
+SniperRifle
+{
+ dpreflectcube cubemaps/default/sky
+ {
+ map textures/sniperrifle.tga
+ rgbgen lightingDiffuse
+ }
+}