From: Samual Date: Mon, 2 Apr 2012 06:58:00 +0000 (-0400) Subject: Merge remote branch 'origin/master' into samual/mutator_ctf X-Git-Tag: xonotic-v0.7.0~240^2~99 X-Git-Url: http://git.xonotic.org/?a=commitdiff_plain;h=05fb311552c975dd88c475fdba312c361c95bacf;hp=bb1c51447c3620b193974956bc39f3f532d21ce9;p=xonotic%2Fxonotic-data.pk3dir.git Merge remote branch 'origin/master' into samual/mutator_ctf Conflicts: qcsrc/server/mutators/base.qh --- diff --git a/balance25.cfg b/balance25.cfg index 51bb152dd..9783f5e8b 100644 --- a/balance25.cfg +++ b/balance25.cfg @@ -5,7 +5,6 @@ set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide th set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" @@ -14,11 +13,8 @@ set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always p set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_rifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_balance_health_start 150 set g_balance_armor_start 0 set g_start_ammo_shells 40 @@ -162,7 +158,7 @@ set g_throughfloor_force 1 set g_projectiles_damage 2 // possible values: // -2: absolutely no damage to projectiles (no exceptions) -// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines) +// -1: no damage other than the exceptions (electro combo, hagar join explode, ML mines) // 0: only damage from contents (lava/slime) or exceptions // 1: only self damage or damage from contents or exceptions // 2: allow all damage to projectiles normally @@ -374,31 +370,6 @@ set g_balance_grenadelauncher_bouncestop 0.075 set g_balance_grenadelauncher_reload_ammo 0 //default: 12 set g_balance_grenadelauncher_reload_time 2 // }}} -// {{{ minelayer -set g_balance_minelayer_damage 35 -set g_balance_minelayer_edgedamage 30 -set g_balance_minelayer_force 250 -set g_balance_minelayer_radius 175 -set g_balance_minelayer_proximityradius 150 -set g_balance_minelayer_speed 750 -set g_balance_minelayer_lifetime 60 -set g_balance_minelayer_lifetime_countdown 0 -set g_balance_minelayer_refire 1.5 -set g_balance_minelayer_animtime 0.4 -set g_balance_minelayer_ammo 5 -set g_balance_minelayer_health 15 -set g_balance_minelayer_limit 4 // 0 disables the limit -set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate -set g_balance_minelayer_damageforcescale 0 -set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time -set g_balance_minelayer_time 0.5 -set g_balance_minelayer_remote_damage 45 -set g_balance_minelayer_remote_edgedamage 40 -set g_balance_minelayer_remote_radius 200 -set g_balance_minelayer_remote_force 300 -set g_balance_minelayer_reload_ammo 0 //default: 15 -set g_balance_minelayer_reload_time 2 -// }}} // {{{ electro set g_balance_electro_lightning 0 set g_balance_electro_primary_damage 65 @@ -659,77 +630,6 @@ set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds set g_balance_hook_secondary_health 0 set g_balance_hook_secondary_damageforcescale 0 // }}} -// {{{ hlac -set g_balance_hlac_primary_spread_min 0.01 -set g_balance_hlac_primary_spread_max 0.25 -set g_balance_hlac_primary_spread_add 0.0045 -set g_balance_hlac_primary_spread_crouchmod 0.25 - -set g_balance_hlac_primary_damage 23 -set g_balance_hlac_primary_edgedamage 10 -set g_balance_hlac_primary_force 100 -set g_balance_hlac_primary_radius 70 -set g_balance_hlac_primary_speed 9000 -set g_balance_hlac_primary_lifetime 5 - -set g_balance_hlac_primary_refire 0.1 -set g_balance_hlac_primary_animtime 0.4 -set g_balance_hlac_primary_ammo 1 - -set g_balance_hlac_secondary 1 -set g_balance_hlac_secondary_spread 0.15 -set g_balance_hlac_secondary_spread_crouchmod 0.5 - -set g_balance_hlac_secondary_damage 23 -set g_balance_hlac_secondary_edgedamage 10 -set g_balance_hlac_secondary_force 100 -set g_balance_hlac_secondary_radius 70 -set g_balance_hlac_secondary_speed 9000 -set g_balance_hlac_secondary_lifetime 5 - -set g_balance_hlac_secondary_refire 1 -set g_balance_hlac_secondary_animtime 0.3 -set g_balance_hlac_secondary_ammo 10 -set g_balance_hlac_secondary_shots 6 - -set g_balance_hlac_reload_ammo 0 //default: 20 -set g_balance_hlac_reload_time 2 -// }}} -// {{{ rifle -set g_balance_rifle_bursttime 0 -set g_balance_rifle_primary_tracer 0 -set g_balance_rifle_primary_shots 1 -set g_balance_rifle_primary_damage 60 -set g_balance_rifle_primary_headshotaddeddamage 100 -set g_balance_rifle_primary_spread 0 -set g_balance_rifle_primary_force 2 -set g_balance_rifle_primary_speed 35000 -set g_balance_rifle_primary_lifetime 5 -set g_balance_rifle_primary_refire 0.8 -set g_balance_rifle_primary_animtime 0.3 -set g_balance_rifle_primary_ammo 10 -set g_balance_rifle_primary_bulletconstant 130 // 56.3qu -set g_balance_rifle_primary_burstcost 0 -set g_balance_rifle_primary_bullethail 0 // empty magazine on shot -set g_balance_rifle_secondary 1 -set g_balance_rifle_secondary_reload 0 -set g_balance_rifle_secondary_tracer 0 -set g_balance_rifle_secondary_shots 1 -set g_balance_rifle_secondary_damage 35 -set g_balance_rifle_secondary_headshotaddeddamage 15 // 50 damage only on head -set g_balance_rifle_secondary_spread 0.008 -set g_balance_rifle_secondary_force 1 -set g_balance_rifle_secondary_speed 20000 -set g_balance_rifle_secondary_lifetime 5 -set g_balance_rifle_secondary_refire 0.15 -set g_balance_rifle_secondary_animtime 0.1 -set g_balance_rifle_secondary_ammo 10 -set g_balance_rifle_secondary_bulletconstant 130 // 18.3qu -set g_balance_rifle_secondary_burstcost 0 -set g_balance_rifle_secondary_bullethail 0 // empty magazine on shot -set g_balance_rifle_reload_ammo 80 //default: 80 -set g_balance_rifle_reload_time 2 -// }}} // {{{ tuba set g_balance_tuba_refire 0.05 set g_balance_tuba_animtime 0.05 @@ -778,57 +678,3 @@ set g_balance_fireball_secondary_speed_up 100 set g_balance_fireball_secondary_speed_z 0 set g_balance_fireball_secondary_spread 0 // }}} -// {{{ seeker -set g_balance_seeker_type 0 // 0 = old seeker, 1 = new seeker. THIS IS A TEMPORARY CVAR FOR TESTING, will be removed later. -set g_balance_seeker_flac_ammo 0.5 -set g_balance_seeker_flac_animtime 0.1 -set g_balance_seeker_flac_damage 15 -set g_balance_seeker_flac_edgedamage 10 -set g_balance_seeker_flac_force 50 -set g_balance_seeker_flac_lifetime 0.1 -set g_balance_seeker_flac_lifetime_rand 0.05 -set g_balance_seeker_flac_radius 100 -set g_balance_seeker_flac_refire 0.1 -set g_balance_seeker_flac_speed 3000 -set g_balance_seeker_flac_speed_up 1000 -set g_balance_seeker_flac_speed_z 0 -set g_balance_seeker_flac_spread 0.4 -set g_balance_seeker_missile_accel 3000 -set g_balance_seeker_missile_ammo 2 -set g_balance_seeker_missile_animtime 0.3 -set g_balance_seeker_missile_count 4 -set g_balance_seeker_missile_damage 40 -set g_balance_seeker_missile_damageforcescale 4 -set g_balance_seeker_missile_decel 6000 -set g_balance_seeker_missile_delay 0.25 -set g_balance_seeker_missile_edgedamage 10 -set g_balance_seeker_missile_force 250 -set g_balance_seeker_missile_health 5 -set g_balance_seeker_missile_lifetime 15 -set g_balance_seeker_missile_proxy 0 -set g_balance_seeker_missile_proxy_delay 0.2 -set g_balance_seeker_missile_proxy_maxrange 45 -set g_balance_seeker_missile_radius 80 -set g_balance_seeker_missile_refire 0.5 -set g_balance_seeker_missile_smart 1 -set g_balance_seeker_missile_smart_mindist 800 -set g_balance_seeker_missile_smart_trace_max 2500 -set g_balance_seeker_missile_smart_trace_min 1000 -set g_balance_seeker_missile_speed 700 -set g_balance_seeker_missile_speed_up 300 -set g_balance_seeker_missile_speed_z 0 -set g_balance_seeker_missile_speed_max 1250 -set g_balance_seeker_missile_spread 0 -set g_balance_seeker_missile_turnrate 0.65 -set g_balance_seeker_tag_ammo 1 -set g_balance_seeker_tag_animtime 0.3 -set g_balance_seeker_tag_damageforcescale 4 -set g_balance_seeker_tag_health 5 -set g_balance_seeker_tag_lifetime 15 -set g_balance_seeker_tag_refire 0.7 -set g_balance_seeker_tag_speed 9000 -set g_balance_seeker_tag_spread 0 -set g_balance_seeker_tag_tracker_lifetime 10 -set g_balance_seeker_reload_ammo 0 //default: 15 -set g_balance_seeker_reload_time 2 -// End new seeker diff --git a/balanceFruitieX.cfg b/balanceFruitieX.cfg index ced09e7d1..54e232dc4 100644 --- a/balanceFruitieX.cfg +++ b/balanceFruitieX.cfg @@ -5,7 +5,6 @@ set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide th set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" @@ -14,11 +13,8 @@ set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always p set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_rifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_balance_health_start 125 set g_balance_armor_start 0 set g_start_ammo_shells 20 @@ -162,7 +158,7 @@ set g_throughfloor_force 0.8 set g_projectiles_damage 2 // possible values: // -2: absolutely no damage to projectiles (no exceptions) -// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines) +// -1: no damage other than the exceptions (electro combo, hagar join explode, ML mines) // 0: only damage from contents (lava/slime) or exceptions // 1: only self damage or damage from contents or exceptions // 2: allow all damage to projectiles normally @@ -374,31 +370,6 @@ set g_balance_grenadelauncher_bouncestop 0.12 set g_balance_grenadelauncher_reload_ammo 0 //default: 12 set g_balance_grenadelauncher_reload_time 2 // }}} -// {{{ minelayer -set g_balance_minelayer_damage 42 -set g_balance_minelayer_edgedamage 30 -set g_balance_minelayer_force 250 -set g_balance_minelayer_radius 175 -set g_balance_minelayer_proximityradius 150 -set g_balance_minelayer_speed 750 -set g_balance_minelayer_lifetime 60 -set g_balance_minelayer_lifetime_countdown 0 -set g_balance_minelayer_refire 1.5 -set g_balance_minelayer_animtime 0.3 -set g_balance_minelayer_ammo 5 -set g_balance_minelayer_health 15 -set g_balance_minelayer_limit 3 // 0 disables the limit // LOG: 4 -> 3 -set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate -set g_balance_minelayer_damageforcescale 0 -set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time -set g_balance_minelayer_time 0.5 -set g_balance_minelayer_remote_damage 45 -set g_balance_minelayer_remote_edgedamage 40 -set g_balance_minelayer_remote_radius 200 -set g_balance_minelayer_remote_force 300 -set g_balance_minelayer_reload_ammo 0 //default: 15 -set g_balance_minelayer_reload_time 2 -// }}} // {{{ electro set g_balance_electro_lightning 1 set g_balance_electro_primary_damage 100 @@ -659,77 +630,6 @@ set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds set g_balance_hook_secondary_health 0 set g_balance_hook_secondary_damageforcescale 0 // }}} -// {{{ hlac -set g_balance_hlac_primary_spread_min 0.01 -set g_balance_hlac_primary_spread_max 0.075 -set g_balance_hlac_primary_spread_add 0.001 -set g_balance_hlac_primary_spread_crouchmod 0.25 - -set g_balance_hlac_primary_damage 15 -set g_balance_hlac_primary_edgedamage 10 -set g_balance_hlac_primary_force 70 -set g_balance_hlac_primary_radius 40 -set g_balance_hlac_primary_speed 9000 -set g_balance_hlac_primary_lifetime 5 - -set g_balance_hlac_primary_refire 0.1 -set g_balance_hlac_primary_animtime 0.2 -set g_balance_hlac_primary_ammo 1 - -set g_balance_hlac_secondary 1 -set g_balance_hlac_secondary_spread 0.15 -set g_balance_hlac_secondary_spread_crouchmod 0.5 - -set g_balance_hlac_secondary_damage 20 -set g_balance_hlac_secondary_edgedamage 13 -set g_balance_hlac_secondary_force 100 -set g_balance_hlac_secondary_radius 45 -set g_balance_hlac_secondary_speed 9000 -set g_balance_hlac_secondary_lifetime 5 - -set g_balance_hlac_secondary_refire 0.8 -set g_balance_hlac_secondary_animtime 0.4 -set g_balance_hlac_secondary_ammo 4 -set g_balance_hlac_secondary_shots 6 - -set g_balance_hlac_reload_ammo 0 //default: 20 -set g_balance_hlac_reload_time 2 -// }}} -// {{{ rifle -set g_balance_rifle_bursttime 0 -set g_balance_rifle_primary_tracer 1 -set g_balance_rifle_primary_shots 1 -set g_balance_rifle_primary_damage 60 -set g_balance_rifle_primary_headshotaddeddamage 60 -set g_balance_rifle_primary_spread 0 -set g_balance_rifle_primary_force 2 -set g_balance_rifle_primary_speed 40000 -set g_balance_rifle_primary_lifetime 5 -set g_balance_rifle_primary_refire 1.5 -set g_balance_rifle_primary_animtime 1.4 -set g_balance_rifle_primary_ammo 10 -set g_balance_rifle_primary_bulletconstant 110 // 62.2qu -set g_balance_rifle_primary_burstcost 0 -set g_balance_rifle_primary_bullethail 0 // empty magazine on shot -set g_balance_rifle_secondary 1 -set g_balance_rifle_secondary_reload 1 -set g_balance_rifle_secondary_tracer 0 -set g_balance_rifle_secondary_shots 1 -set g_balance_rifle_secondary_damage 42 -set g_balance_rifle_secondary_headshotaddeddamage 42 -set g_balance_rifle_secondary_spread 0 -set g_balance_rifle_secondary_force 2 -set g_balance_rifle_secondary_speed 20000 -set g_balance_rifle_secondary_lifetime 5 -set g_balance_rifle_secondary_refire 1.5 -set g_balance_rifle_secondary_animtime 1.4 -set g_balance_rifle_secondary_ammo 10 -set g_balance_rifle_secondary_bulletconstant 110 // 15.5qu -set g_balance_rifle_secondary_burstcost 0 -set g_balance_rifle_secondary_bullethail 0 // empty magazine on shot -set g_balance_rifle_reload_ammo 80 //default: 80 -set g_balance_rifle_reload_time 2 -// }}} // {{{ tuba set g_balance_tuba_refire 0.05 set g_balance_tuba_animtime 0.05 @@ -778,57 +678,3 @@ set g_balance_fireball_secondary_speed_up 100 set g_balance_fireball_secondary_speed_z 0 set g_balance_fireball_secondary_spread 0 // }}} -// {{{ seeker -set g_balance_seeker_type 0 // 0 = old seeker, 1 = new seeker. THIS IS A TEMPORARY CVAR FOR TESTING, will be removed later. -set g_balance_seeker_flac_ammo 0.5 -set g_balance_seeker_flac_animtime 0.1 -set g_balance_seeker_flac_damage 15 -set g_balance_seeker_flac_edgedamage 10 -set g_balance_seeker_flac_force 50 -set g_balance_seeker_flac_lifetime 0.1 -set g_balance_seeker_flac_lifetime_rand 0.05 -set g_balance_seeker_flac_radius 100 -set g_balance_seeker_flac_refire 0.1 -set g_balance_seeker_flac_speed 3000 -set g_balance_seeker_flac_speed_up 1000 -set g_balance_seeker_flac_speed_z 0 -set g_balance_seeker_flac_spread 0.4 -set g_balance_seeker_missile_accel 1400 -set g_balance_seeker_missile_ammo 2 -set g_balance_seeker_missile_animtime 0.2 -set g_balance_seeker_missile_count 3 // LOG: 8 -> 3 -set g_balance_seeker_missile_damage 30 // LOG: 15 -> 30 -set g_balance_seeker_missile_damageforcescale 4 -set g_balance_seeker_missile_decel 1400 -set g_balance_seeker_missile_delay 0.25 -set g_balance_seeker_missile_edgedamage 10 -set g_balance_seeker_missile_force 150 // LOG: 100 -> 150 -set g_balance_seeker_missile_health 5 -set g_balance_seeker_missile_lifetime 15 -set g_balance_seeker_missile_proxy 0 -set g_balance_seeker_missile_proxy_delay 0.2 -set g_balance_seeker_missile_proxy_maxrange 45 -set g_balance_seeker_missile_radius 80 -set g_balance_seeker_missile_refire 0.5 -set g_balance_seeker_missile_smart 1 -set g_balance_seeker_missile_smart_mindist 800 -set g_balance_seeker_missile_smart_trace_max 2500 -set g_balance_seeker_missile_smart_trace_min 1000 -set g_balance_seeker_missile_speed 700 -set g_balance_seeker_missile_speed_up 300 -set g_balance_seeker_missile_speed_z 0 -set g_balance_seeker_missile_speed_max 1300 // LOG: 1400 -> 1300 -set g_balance_seeker_missile_spread 0 -set g_balance_seeker_missile_turnrate 0.65 -set g_balance_seeker_tag_ammo 1 -set g_balance_seeker_tag_animtime 0.2 -set g_balance_seeker_tag_damageforcescale 4 -set g_balance_seeker_tag_health 5 -set g_balance_seeker_tag_lifetime 15 -set g_balance_seeker_tag_refire 0.75 // LOG: 0.7 -> 0.75 -set g_balance_seeker_tag_speed 5000 -set g_balance_seeker_tag_spread 0 -set g_balance_seeker_tag_tracker_lifetime 10 -set g_balance_seeker_reload_ammo 0 //default: 15 -set g_balance_seeker_reload_time 2 -// End new seeker diff --git a/balanceXPM.cfg b/balanceXPM.cfg index 2da131c96..ea933d272 100644 --- a/balanceXPM.cfg +++ b/balanceXPM.cfg @@ -5,7 +5,6 @@ set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide th set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" @@ -14,11 +13,8 @@ set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always p set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" // UNTIL IT CAN BE REMOVED FROM CODE -set g_start_weapon_rifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" // UNTIL IT CAN BE REMOVED FROM CODE set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" set g_balance_health_start 100 set g_balance_armor_start 0 set g_start_ammo_shells 15 @@ -162,7 +158,7 @@ set g_throughfloor_force 0.75 set g_projectiles_damage 1 // possible values: // -2: absolutely no damage to projectiles (no exceptions) -// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines) +// -1: no damage other than the exceptions (electro combo, hagar join explode, ML mines) // 0: only damage from contents (lava/slime) or exceptions // 1: only self damage or damage from contents or exceptions // 2: allow all damage to projectiles normally @@ -374,31 +370,6 @@ set g_balance_grenadelauncher_bouncestop 0.075 set g_balance_grenadelauncher_reload_ammo 0 //default: 12 set g_balance_grenadelauncher_reload_time 2 // }}} -// {{{ minelayer -set g_balance_minelayer_damage 40 -set g_balance_minelayer_edgedamage 20 -set g_balance_minelayer_force 250 -set g_balance_minelayer_radius 175 -set g_balance_minelayer_proximityradius 150 -set g_balance_minelayer_speed 1000 -set g_balance_minelayer_lifetime 10 -set g_balance_minelayer_lifetime_countdown 0.5 -set g_balance_minelayer_refire 1.5 -set g_balance_minelayer_animtime 0.4 -set g_balance_minelayer_ammo 4 -set g_balance_minelayer_health 15 -set g_balance_minelayer_limit 3 // 0 disables the limit -set g_balance_minelayer_protection 0 // don't explode if the mine would hurt the owner or a team mate -set g_balance_minelayer_damageforcescale 0 -set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time -set g_balance_minelayer_time 0.5 -set g_balance_minelayer_remote_damage 45 -set g_balance_minelayer_remote_edgedamage 40 -set g_balance_minelayer_remote_radius 200 -set g_balance_minelayer_remote_force 300 -set g_balance_minelayer_reload_ammo 0 //default: 15 -set g_balance_minelayer_reload_time 2 -// }}} // {{{ electro set g_balance_electro_lightning 0 set g_balance_electro_primary_damage 40 @@ -659,77 +630,6 @@ set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds set g_balance_hook_secondary_health 15 set g_balance_hook_secondary_damageforcescale 0 // }}} -// {{{ hlac // TO BE REMOVED -set g_balance_hlac_primary_spread_min 0.01 -set g_balance_hlac_primary_spread_max 0.25 -set g_balance_hlac_primary_spread_add 0.0045 -set g_balance_hlac_primary_spread_crouchmod 0.25 - -set g_balance_hlac_primary_damage 18 -set g_balance_hlac_primary_edgedamage 9 -set g_balance_hlac_primary_force 90 -set g_balance_hlac_primary_radius 70 -set g_balance_hlac_primary_speed 9000 -set g_balance_hlac_primary_lifetime 5 - -set g_balance_hlac_primary_refire 0.15 -set g_balance_hlac_primary_animtime 0.4 -set g_balance_hlac_primary_ammo 1 - -set g_balance_hlac_secondary 1 -set g_balance_hlac_secondary_spread 0.15 -set g_balance_hlac_secondary_spread_crouchmod 0.5 - -set g_balance_hlac_secondary_damage 15 -set g_balance_hlac_secondary_edgedamage 7.5 -set g_balance_hlac_secondary_force 90 -set g_balance_hlac_secondary_radius 70 -set g_balance_hlac_secondary_speed 9000 -set g_balance_hlac_secondary_lifetime 5 - -set g_balance_hlac_secondary_refire 1 -set g_balance_hlac_secondary_animtime 0.3 -set g_balance_hlac_secondary_ammo 10 -set g_balance_hlac_secondary_shots 6 - -set g_balance_hlac_reload_ammo 0 //default: 20 -set g_balance_hlac_reload_time 2 -// }}} -// {{{ rifle -set g_balance_rifle_bursttime 0 -set g_balance_rifle_primary_tracer 1 -set g_balance_rifle_primary_shots 1 -set g_balance_rifle_primary_damage 40 -set g_balance_rifle_primary_headshotaddeddamage 40 -set g_balance_rifle_primary_spread 0 -set g_balance_rifle_primary_force 100 -set g_balance_rifle_primary_speed 40000 -set g_balance_rifle_primary_lifetime 5 -set g_balance_rifle_primary_refire 1.2 -set g_balance_rifle_primary_animtime 0.4 -set g_balance_rifle_primary_ammo 10 -set g_balance_rifle_primary_bulletconstant 110 // 62.2qu -set g_balance_rifle_primary_burstcost 0 -set g_balance_rifle_primary_bullethail 0 // empty magazine on shot -set g_balance_rifle_secondary 1 -set g_balance_rifle_secondary_reload 0 -set g_balance_rifle_secondary_tracer 0 -set g_balance_rifle_secondary_shots 4 -set g_balance_rifle_secondary_damage 10 -set g_balance_rifle_secondary_headshotaddeddamage 20 -set g_balance_rifle_secondary_spread 0.04 -set g_balance_rifle_secondary_force 50 -set g_balance_rifle_secondary_speed 20000 -set g_balance_rifle_secondary_lifetime 5 -set g_balance_rifle_secondary_refire 0.9 -set g_balance_rifle_secondary_animtime 0.3 -set g_balance_rifle_secondary_ammo 10 -set g_balance_rifle_secondary_bulletconstant 110 // 15.5qu -set g_balance_rifle_secondary_burstcost 0 -set g_balance_rifle_secondary_bullethail 0 // empty magazine on shot -set g_balance_rifle_reload_ammo 80 //default: 80 -set g_balance_rifle_reload_time 2 -// }}} // {{{ tuba set g_balance_tuba_refire 0.05 set g_balance_tuba_animtime 0.05 @@ -778,57 +678,3 @@ set g_balance_fireball_secondary_speed_up 100 set g_balance_fireball_secondary_speed_z 0 set g_balance_fireball_secondary_spread 0 // }}} -// {{{ seeker -set g_balance_seeker_type 1 // 0 = old seeker, 1 = new seeker. THIS IS A TEMPORARY CVAR FOR TESTING, will be removed later. -set g_balance_seeker_flac_ammo 0.5 -set g_balance_seeker_flac_animtime 0.1 -set g_balance_seeker_flac_damage 15 -set g_balance_seeker_flac_edgedamage 10 -set g_balance_seeker_flac_force 50 -set g_balance_seeker_flac_lifetime 0.1 -set g_balance_seeker_flac_lifetime_rand 0.05 -set g_balance_seeker_flac_radius 100 -set g_balance_seeker_flac_refire 0.1 -set g_balance_seeker_flac_speed 3000 -set g_balance_seeker_flac_speed_up 1000 -set g_balance_seeker_flac_speed_z 0 -set g_balance_seeker_flac_spread 0.4 -set g_balance_seeker_tag_ammo 1 -set g_balance_seeker_tag_animtime 0.2 -set g_balance_seeker_tag_damageforcescale 0 -set g_balance_seeker_tag_health 0 -set g_balance_seeker_tag_lifetime 15 -set g_balance_seeker_tag_refire 0.75 // LOG: 0.7 -> 0.75 -set g_balance_seeker_tag_speed 5000 -set g_balance_seeker_tag_spread 0 -set g_balance_seeker_tag_tracker_lifetime 10 -set g_balance_seeker_missile_accel 1500 -set g_balance_seeker_missile_ammo 2 -set g_balance_seeker_missile_animtime 0.2 -set g_balance_seeker_missile_count 3 // LOG: 8 -> 3 -set g_balance_seeker_missile_damage 16 // LOG: 15 -> 30 -set g_balance_seeker_missile_damageforcescale 4 -set g_balance_seeker_missile_decel 6000 -set g_balance_seeker_missile_delay 0.25 -set g_balance_seeker_missile_edgedamage 8 -set g_balance_seeker_missile_force 50 // LOG: 100 -> 150 -set g_balance_seeker_missile_health 1 -set g_balance_seeker_missile_lifetime 15 -set g_balance_seeker_missile_proxy 0 -set g_balance_seeker_missile_proxy_delay 0.2 -set g_balance_seeker_missile_proxy_maxrange 45 -set g_balance_seeker_missile_radius 70 -set g_balance_seeker_missile_refire 0.25 -set g_balance_seeker_missile_smart 0 -set g_balance_seeker_missile_smart_mindist 800 -set g_balance_seeker_missile_smart_trace_max 2500 -set g_balance_seeker_missile_smart_trace_min 1000 -set g_balance_seeker_missile_speed 1500 -set g_balance_seeker_missile_speed_up 0 -set g_balance_seeker_missile_speed_z 0 -set g_balance_seeker_missile_speed_max 2000 // LOG: 1400 -> 1300 -set g_balance_seeker_missile_spread 0 -set g_balance_seeker_missile_turnrate 0.15 -set g_balance_seeker_reload_ammo 0 //default: 15 -set g_balance_seeker_reload_time 2 -// End new seeker diff --git a/balanceXonotic.cfg b/balanceXonotic.cfg index 2a4c36989..2f1d16d82 100644 --- a/balanceXonotic.cfg +++ b/balanceXonotic.cfg @@ -1,24 +1,20 @@ g_mod_balance Xonotic // {{{ starting gear -set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" // UNTIL IT CAN BE REMOVED FROM CODE -set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" // UNTIL IT CAN BE REMOVED FROM CODE -set g_start_weapon_rifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" // UNTIL IT CAN BE REMOVED FROM CODE -set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" -set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" // UNTIL IT CAN BE REMOVED FROM CODE +set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" +set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" set g_balance_health_start 100 set g_balance_armor_start 0 set g_start_ammo_shells 15 @@ -162,7 +158,7 @@ set g_throughfloor_force 0.75 set g_projectiles_damage 2 // possible values: // -2: absolutely no damage to projectiles (no exceptions) -// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines) +// -1: no damage other than the exceptions (electro combo, hagar join explode, ML mines) // 0: only damage from contents (lava/slime) or exceptions // 1: only self damage or damage from contents or exceptions // 2: allow all damage to projectiles normally @@ -374,31 +370,6 @@ set g_balance_grenadelauncher_bouncestop 0.075 set g_balance_grenadelauncher_reload_ammo 0 //default: 12 set g_balance_grenadelauncher_reload_time 2 // }}} -// {{{ minelayer -set g_balance_minelayer_damage 40 -set g_balance_minelayer_edgedamage 20 -set g_balance_minelayer_force 250 -set g_balance_minelayer_radius 175 -set g_balance_minelayer_proximityradius 150 -set g_balance_minelayer_speed 1000 -set g_balance_minelayer_lifetime 10 -set g_balance_minelayer_lifetime_countdown 0.5 -set g_balance_minelayer_refire 1.5 -set g_balance_minelayer_animtime 0.4 -set g_balance_minelayer_ammo 4 -set g_balance_minelayer_health 15 -set g_balance_minelayer_limit 3 // 0 disables the limit -set g_balance_minelayer_protection 0 // don't explode if the mine would hurt the owner or a team mate -set g_balance_minelayer_damageforcescale 0 -set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time -set g_balance_minelayer_time 0.5 -set g_balance_minelayer_remote_damage 45 -set g_balance_minelayer_remote_edgedamage 40 -set g_balance_minelayer_remote_radius 200 -set g_balance_minelayer_remote_force 300 -set g_balance_minelayer_reload_ammo 0 //default: 15 -set g_balance_minelayer_reload_time 2 -// }}} // {{{ electro set g_balance_electro_lightning 0 set g_balance_electro_primary_damage 40 @@ -659,77 +630,6 @@ set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds set g_balance_hook_secondary_health 15 set g_balance_hook_secondary_damageforcescale 0 // }}} -// {{{ hlac // TO BE REMOVED -set g_balance_hlac_primary_spread_min 0.01 -set g_balance_hlac_primary_spread_max 0.25 -set g_balance_hlac_primary_spread_add 0.0045 -set g_balance_hlac_primary_spread_crouchmod 0.25 - -set g_balance_hlac_primary_damage 18 -set g_balance_hlac_primary_edgedamage 9 -set g_balance_hlac_primary_force 90 -set g_balance_hlac_primary_radius 70 -set g_balance_hlac_primary_speed 9000 -set g_balance_hlac_primary_lifetime 5 - -set g_balance_hlac_primary_refire 0.15 -set g_balance_hlac_primary_animtime 0.4 -set g_balance_hlac_primary_ammo 1 - -set g_balance_hlac_secondary 1 -set g_balance_hlac_secondary_spread 0.15 -set g_balance_hlac_secondary_spread_crouchmod 0.5 - -set g_balance_hlac_secondary_damage 15 -set g_balance_hlac_secondary_edgedamage 7.5 -set g_balance_hlac_secondary_force 90 -set g_balance_hlac_secondary_radius 70 -set g_balance_hlac_secondary_speed 9000 -set g_balance_hlac_secondary_lifetime 5 - -set g_balance_hlac_secondary_refire 1 -set g_balance_hlac_secondary_animtime 0.3 -set g_balance_hlac_secondary_ammo 10 -set g_balance_hlac_secondary_shots 6 - -set g_balance_hlac_reload_ammo 0 //default: 20 -set g_balance_hlac_reload_time 2 -// }}} -// {{{ rifle -set g_balance_rifle_bursttime 0 -set g_balance_rifle_primary_tracer 1 -set g_balance_rifle_primary_shots 1 -set g_balance_rifle_primary_damage 40 -set g_balance_rifle_primary_headshotaddeddamage 40 -set g_balance_rifle_primary_spread 0 -set g_balance_rifle_primary_force 100 -set g_balance_rifle_primary_speed 40000 -set g_balance_rifle_primary_lifetime 5 -set g_balance_rifle_primary_refire 1.2 -set g_balance_rifle_primary_animtime 0.4 -set g_balance_rifle_primary_ammo 10 -set g_balance_rifle_primary_bulletconstant 110 // 62.2qu -set g_balance_rifle_primary_burstcost 0 -set g_balance_rifle_primary_bullethail 0 // empty magazine on shot -set g_balance_rifle_secondary 1 -set g_balance_rifle_secondary_reload 0 -set g_balance_rifle_secondary_tracer 0 -set g_balance_rifle_secondary_shots 4 -set g_balance_rifle_secondary_damage 10 -set g_balance_rifle_secondary_headshotaddeddamage 20 -set g_balance_rifle_secondary_spread 0.04 -set g_balance_rifle_secondary_force 50 -set g_balance_rifle_secondary_speed 20000 -set g_balance_rifle_secondary_lifetime 5 -set g_balance_rifle_secondary_refire 0.9 -set g_balance_rifle_secondary_animtime 0.3 -set g_balance_rifle_secondary_ammo 10 -set g_balance_rifle_secondary_bulletconstant 110 // 15.5qu -set g_balance_rifle_secondary_burstcost 0 -set g_balance_rifle_secondary_bullethail 0 // empty magazine on shot -set g_balance_rifle_reload_ammo 80 //default: 80 -set g_balance_rifle_reload_time 2 -// }}} // {{{ tuba set g_balance_tuba_refire 0.05 set g_balance_tuba_animtime 0.05 @@ -778,57 +678,3 @@ set g_balance_fireball_secondary_speed_up 100 set g_balance_fireball_secondary_speed_z 0 set g_balance_fireball_secondary_spread 0 // }}} -// {{{ seeker -set g_balance_seeker_type 1 // 0 = old seeker, 1 = new seeker. THIS IS A TEMPORARY CVAR FOR TESTING, will be removed later. -set g_balance_seeker_flac_ammo 0.5 -set g_balance_seeker_flac_animtime 0.1 -set g_balance_seeker_flac_damage 15 -set g_balance_seeker_flac_edgedamage 10 -set g_balance_seeker_flac_force 50 -set g_balance_seeker_flac_lifetime 0.1 -set g_balance_seeker_flac_lifetime_rand 0.05 -set g_balance_seeker_flac_radius 100 -set g_balance_seeker_flac_refire 0.1 -set g_balance_seeker_flac_speed 3000 -set g_balance_seeker_flac_speed_up 1000 -set g_balance_seeker_flac_speed_z 0 -set g_balance_seeker_flac_spread 0.4 -set g_balance_seeker_tag_ammo 1 -set g_balance_seeker_tag_animtime 0.2 -set g_balance_seeker_tag_damageforcescale 0 -set g_balance_seeker_tag_health 0 -set g_balance_seeker_tag_lifetime 15 -set g_balance_seeker_tag_refire 0.75 // LOG: 0.7 -> 0.75 -set g_balance_seeker_tag_speed 5000 -set g_balance_seeker_tag_spread 0 -set g_balance_seeker_tag_tracker_lifetime 10 -set g_balance_seeker_missile_accel 1500 -set g_balance_seeker_missile_ammo 2 -set g_balance_seeker_missile_animtime 0.2 -set g_balance_seeker_missile_count 3 // LOG: 8 -> 3 -set g_balance_seeker_missile_damage 16 // LOG: 15 -> 30 -set g_balance_seeker_missile_damageforcescale 4 -set g_balance_seeker_missile_decel 6000 -set g_balance_seeker_missile_delay 0.25 -set g_balance_seeker_missile_edgedamage 8 -set g_balance_seeker_missile_force 50 // LOG: 100 -> 150 -set g_balance_seeker_missile_health 1 -set g_balance_seeker_missile_lifetime 15 -set g_balance_seeker_missile_proxy 0 -set g_balance_seeker_missile_proxy_delay 0.2 -set g_balance_seeker_missile_proxy_maxrange 45 -set g_balance_seeker_missile_radius 70 -set g_balance_seeker_missile_refire 0.25 -set g_balance_seeker_missile_smart 0 -set g_balance_seeker_missile_smart_mindist 800 -set g_balance_seeker_missile_smart_trace_max 2500 -set g_balance_seeker_missile_smart_trace_min 1000 -set g_balance_seeker_missile_speed 1500 -set g_balance_seeker_missile_speed_up 0 -set g_balance_seeker_missile_speed_z 0 -set g_balance_seeker_missile_speed_max 2000 // LOG: 1400 -> 1300 -set g_balance_seeker_missile_spread 0 -set g_balance_seeker_missile_turnrate 0.15 -set g_balance_seeker_reload_ammo 0 //default: 15 -set g_balance_seeker_reload_time 2 -// End new seeker diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg index 3732547b3..5107c7db9 100644 --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@ -1766,7 +1766,6 @@ cl_decals_newsystem 1 set g_weaponreplace_laser "" set g_weaponreplace_shotgun "" set g_weaponreplace_uzi "" -set g_weaponreplace_minelayer "" set g_weaponreplace_grenadelauncher "" set g_weaponreplace_electro "" set g_weaponreplace_crylink "" @@ -1776,11 +1775,8 @@ set g_weaponreplace_rocketlauncher "" set g_weaponreplace_porto "" set g_weaponreplace_minstanex "" set g_weaponreplace_hook "" -set g_weaponreplace_hlac "" -set g_weaponreplace_rifle "" set g_weaponreplace_tuba "" set g_weaponreplace_fireball "" -set g_weaponreplace_seeker "" set sv_q3acompat_machineshotgunswap 0 "shorthand for swapping uzi and shotgun (for Q3A map compatibility in mapinfo files)" set g_movement_highspeed 1 "movement speed modification factor (only changes movement when above maxspeed)" @@ -1932,6 +1928,7 @@ scr_loadingscreen_scale_base 1 scr_loadingscreen_scale_limit 2 // other config files +exec mutator_new_toys.cfg // run BEFORE balance to make sure balance wins exec balanceXonotic.cfg exec ctfscoring-ai.cfg exec effects-normal.cfg diff --git a/mutator_new_toys.cfg b/mutator_new_toys.cfg new file mode 100644 index 000000000..c4f20995a --- /dev/null +++ b/mutator_new_toys.cfg @@ -0,0 +1,163 @@ +set g_new_toys 0 "Mutator 'New Toys': enable extra fun guns" +set g_new_toys_autoreplace 2 "0: never replace, 1: always auto replace guns by available new toys, 2: randomly auto replace guns by available new toys" + +set g_weaponreplace_hlac "" +set g_weaponreplace_minelayer "" +set g_weaponreplace_rifle "" +set g_weaponreplace_seeker "" + +set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" // UNTIL IT CAN BE REMOVED FROM CODE +set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_rifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" // UNTIL IT CAN BE REMOVED FROM CODE +set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" + +// {{{ hlac +set g_balance_hlac_primary_spread_min 0.01 +set g_balance_hlac_primary_spread_max 0.25 +set g_balance_hlac_primary_spread_add 0.0045 +set g_balance_hlac_primary_spread_crouchmod 0.25 + +set g_balance_hlac_primary_damage 18 +set g_balance_hlac_primary_edgedamage 9 +set g_balance_hlac_primary_force 90 +set g_balance_hlac_primary_radius 70 +set g_balance_hlac_primary_speed 9000 +set g_balance_hlac_primary_lifetime 5 + +set g_balance_hlac_primary_refire 0.15 +set g_balance_hlac_primary_animtime 0.4 +set g_balance_hlac_primary_ammo 1 + +set g_balance_hlac_secondary 1 +set g_balance_hlac_secondary_spread 0.15 +set g_balance_hlac_secondary_spread_crouchmod 0.5 + +set g_balance_hlac_secondary_damage 15 +set g_balance_hlac_secondary_edgedamage 7.5 +set g_balance_hlac_secondary_force 90 +set g_balance_hlac_secondary_radius 70 +set g_balance_hlac_secondary_speed 9000 +set g_balance_hlac_secondary_lifetime 5 + +set g_balance_hlac_secondary_refire 1 +set g_balance_hlac_secondary_animtime 0.3 +set g_balance_hlac_secondary_ammo 10 +set g_balance_hlac_secondary_shots 6 + +set g_balance_hlac_reload_ammo 0 //default: 20 +set g_balance_hlac_reload_time 2 +// }}} +// {{{ minelayer +set g_balance_minelayer_damage 40 +set g_balance_minelayer_edgedamage 20 +set g_balance_minelayer_force 250 +set g_balance_minelayer_radius 175 +set g_balance_minelayer_proximityradius 150 +set g_balance_minelayer_speed 1000 +set g_balance_minelayer_lifetime 10 +set g_balance_minelayer_lifetime_countdown 0.5 +set g_balance_minelayer_refire 1.5 +set g_balance_minelayer_animtime 0.4 +set g_balance_minelayer_ammo 4 +set g_balance_minelayer_health 15 +set g_balance_minelayer_limit 3 // 0 disables the limit +set g_balance_minelayer_protection 0 // don't explode if the mine would hurt the owner or a team mate +set g_balance_minelayer_damageforcescale 0 +set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time +set g_balance_minelayer_time 0.5 +set g_balance_minelayer_remote_damage 45 +set g_balance_minelayer_remote_edgedamage 40 +set g_balance_minelayer_remote_radius 200 +set g_balance_minelayer_remote_force 300 +set g_balance_minelayer_reload_ammo 0 //default: 15 +set g_balance_minelayer_reload_time 2 +// }}} +// {{{ rifle +set g_balance_rifle_bursttime 0 +set g_balance_rifle_primary_tracer 1 +set g_balance_rifle_primary_shots 1 +set g_balance_rifle_primary_damage 40 +set g_balance_rifle_primary_headshotaddeddamage 40 +set g_balance_rifle_primary_spread 0 +set g_balance_rifle_primary_force 100 +set g_balance_rifle_primary_speed 40000 +set g_balance_rifle_primary_lifetime 5 +set g_balance_rifle_primary_refire 1.2 +set g_balance_rifle_primary_animtime 0.4 +set g_balance_rifle_primary_ammo 10 +set g_balance_rifle_primary_bulletconstant 110 // 62.2qu +set g_balance_rifle_primary_burstcost 0 +set g_balance_rifle_primary_bullethail 0 // empty magazine on shot +set g_balance_rifle_secondary 1 +set g_balance_rifle_secondary_reload 0 +set g_balance_rifle_secondary_tracer 0 +set g_balance_rifle_secondary_shots 4 +set g_balance_rifle_secondary_damage 10 +set g_balance_rifle_secondary_headshotaddeddamage 20 +set g_balance_rifle_secondary_spread 0.04 +set g_balance_rifle_secondary_force 50 +set g_balance_rifle_secondary_speed 20000 +set g_balance_rifle_secondary_lifetime 5 +set g_balance_rifle_secondary_refire 0.9 +set g_balance_rifle_secondary_animtime 0.3 +set g_balance_rifle_secondary_ammo 10 +set g_balance_rifle_secondary_bulletconstant 110 // 15.5qu +set g_balance_rifle_secondary_burstcost 0 +set g_balance_rifle_secondary_bullethail 0 // empty magazine on shot +set g_balance_rifle_reload_ammo 80 //default: 80 +set g_balance_rifle_reload_time 2 +// }}} +// {{{ seeker +set g_balance_seeker_type 0 // 0 = old seeker, 1 = new seeker +set g_balance_seeker_flac_ammo 0.5 +set g_balance_seeker_flac_animtime 0.1 +set g_balance_seeker_flac_damage 15 +set g_balance_seeker_flac_edgedamage 10 +set g_balance_seeker_flac_force 50 +set g_balance_seeker_flac_lifetime 0.1 +set g_balance_seeker_flac_lifetime_rand 0.05 +set g_balance_seeker_flac_radius 100 +set g_balance_seeker_flac_refire 0.1 +set g_balance_seeker_flac_speed 3000 +set g_balance_seeker_flac_speed_up 1000 +set g_balance_seeker_flac_speed_z 0 +set g_balance_seeker_flac_spread 0.4 +set g_balance_seeker_tag_ammo 1 +set g_balance_seeker_tag_animtime 0.2 +set g_balance_seeker_tag_damageforcescale 4 +set g_balance_seeker_tag_health 5 +set g_balance_seeker_tag_lifetime 15 +set g_balance_seeker_tag_refire 0.75 // LOG: 0.7 -> 0.75 +set g_balance_seeker_tag_speed 5000 +set g_balance_seeker_tag_spread 0 +set g_balance_seeker_tag_tracker_lifetime 10 +set g_balance_seeker_missile_accel 1400 +set g_balance_seeker_missile_ammo 2 +set g_balance_seeker_missile_animtime 0.2 +set g_balance_seeker_missile_count 3 // LOG: 8 -> 3 +set g_balance_seeker_missile_damage 30 // LOG: 15 -> 30 +set g_balance_seeker_missile_damageforcescale 4 +set g_balance_seeker_missile_decel 1400 +set g_balance_seeker_missile_delay 0.25 +set g_balance_seeker_missile_edgedamage 10 +set g_balance_seeker_missile_force 150 // LOG: 100 -> 150 +set g_balance_seeker_missile_health 5 +set g_balance_seeker_missile_lifetime 15 +set g_balance_seeker_missile_proxy 0 +set g_balance_seeker_missile_proxy_delay 0.2 +set g_balance_seeker_missile_proxy_maxrange 45 +set g_balance_seeker_missile_radius 80 +set g_balance_seeker_missile_refire 0.5 +set g_balance_seeker_missile_smart 1 +set g_balance_seeker_missile_smart_mindist 800 +set g_balance_seeker_missile_smart_trace_max 2500 +set g_balance_seeker_missile_smart_trace_min 1000 +set g_balance_seeker_missile_speed 700 +set g_balance_seeker_missile_speed_up 300 +set g_balance_seeker_missile_speed_z 0 +set g_balance_seeker_missile_speed_max 1300 // LOG: 1400 -> 1300 +set g_balance_seeker_missile_spread 0 +set g_balance_seeker_missile_turnrate 0.65 +set g_balance_seeker_reload_ammo 0 //default: 15 +set g_balance_seeker_reload_time 2 +// End new seeker diff --git a/qcsrc/client/hud.qc b/qcsrc/client/hud.qc index a0872b618..ffd95f4fe 100644 --- a/qcsrc/client/hud.qc +++ b/qcsrc/client/hud.qc @@ -432,7 +432,8 @@ float GetAmmoTypeForWep(float i) void HUD_Weapons(void) { // declarations - float weapons_stat = getstati(STAT_WEAPONS); + WEPSET_DECLARE_A(weapons_stat); + WEPSET_COPY_AS(weapons_stat); float i, f, a, j, factor; float screen_ar, center_x, center_y; float weapon_count, weapon_id, weapon_alpha; @@ -519,9 +520,9 @@ void HUD_Weapons(void) { if(autocvar__hud_configure) { - if (weapons_stat == 0) // create some fake weapons anyway - for(i = 0; i <= WEP_LAST-WEP_FIRST; i += floor((WEP_LAST-WEP_FIRST)/5)) - weapons_stat |= power2of(i); + if (WEPSET_EMPTY_A(weapons_stat)) + for(i = WEP_FIRST; i <= WEP_LAST; i += floor((WEP_LAST-WEP_FIRST)/5)) + WEPSET_OR_AW(weapons_stat, i); if(menu_enabled != 2) HUD_Panel_DrawBg(1); // also draw the bg of the entire panel @@ -529,7 +530,7 @@ void HUD_Weapons(void) // do we own this weapon? for(i = 0; i <= WEP_LAST-WEP_FIRST; ++i) - if(weapons_stat & weaponorder[i].weapons) + if(WEPSET_CONTAINS_AW(weapons_stat, weaponorder[i].weapon)) ++weapon_count; // add it anyway if weaponcomplain is shown @@ -678,7 +679,7 @@ void HUD_Weapons(void) // skip this weapon if we don't own it (and onlyowned is enabled)-- or if weapons_complainbubble is showing for this weapon if (autocvar_hud_panel_weapons_onlyowned - && !((weapons_stat & self.weapons) + && !(WEPSET_CONTAINS_AW(weapons_stat, self.weapon) || (self.weapon == complain_weapon && time - complain_weapon_time < when + fadetime && autocvar_hud_panel_weapons_complainbubble))) @@ -714,7 +715,7 @@ void HUD_Weapons(void) } // drawing all the weapon items - if(weapons_stat & self.weapons) + if(WEPSET_CONTAINS_AW(weapons_stat, self.weapon)) { // draw the weapon image drawpic_aspect_skin(weapon_pos, strcat("weapon", self.netname), weapon_size, '1 1 1', weapon_alpha, DRAWFLAG_NORMAL); diff --git a/qcsrc/client/scoreboard.qc b/qcsrc/client/scoreboard.qc index e828a17d5..935a0277a 100644 --- a/qcsrc/client/scoreboard.qc +++ b/qcsrc/client/scoreboard.qc @@ -992,7 +992,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size) for(i = WEP_FIRST; i <= WEP_LAST; ++i) { self = get_weaponinfo(i); - if not(self.weapons) + if not(self.weapon) continue; if ((i == WEP_NEX && g_minstagib) || i == WEP_PORTO || (i == WEP_MINSTANEX && !g_minstagib) || i == WEP_TUBA) // skip port-o-launch, nex || minstanex and tuba continue; diff --git a/qcsrc/common/items.qc b/qcsrc/common/items.qc index 3ddf8099f..1282d428a 100644 --- a/qcsrc/common/items.qc +++ b/qcsrc/common/items.qc @@ -8,7 +8,7 @@ void register_weapon(float id, float(float) func, float ammotype, float i, float weapon_info[id - 1] = e = spawn(); e.classname = "weapon_info"; e.weapon = id; - e.weapons = power2of(id - WEP_FIRST); + WEPSET_COPY_EW(e, id); e.netname = shortname; e.message = wname; e.items = ammotype; @@ -41,7 +41,7 @@ void register_weapons_done() dummy_weapon_info = spawn(); dummy_weapon_info.classname = "weapon_info"; dummy_weapon_info.weapon = 0; // you can recognize dummies by this - dummy_weapon_info.weapons = 0; // you can recognize dummies by this too + WEPSET_CLEAR_E(dummy_weapon_info); dummy_weapon_info.netname = ""; dummy_weapon_info.message = "@!#%'n Tuba"; dummy_weapon_info.items = 0; @@ -154,3 +154,21 @@ string W_FixWeaponOrder_ForceComplete(string order) return W_FixWeaponOrder(order, 1); } +void W_RandomWeapons(entity e, float n) +{ + float i, j; + WEPSET_DECLARE_A(remaining); + WEPSET_DECLARE_A(result); + WEPSET_COPY_AE(remaining, e); + WEPSET_CLEAR_A(result); + for(i = 0; i < n; ++i) + { + RandomSelection_Init(); + for(j = WEP_FIRST; j <= WEP_LAST; ++j) + if(WEPSET_CONTAINS_AW(remaining, j)) + RandomSelection_Add(world, j, string_null, 1, 1); + WEPSET_OR_AW(result, RandomSelection_chosen_float); + WEPSET_ANDNOT_AW(remaining, RandomSelection_chosen_float); + } + WEPSET_COPY_EA(e, result); +} diff --git a/qcsrc/common/items.qh b/qcsrc/common/items.qh index 21c115fa3..611352f69 100644 --- a/qcsrc/common/items.qh +++ b/qcsrc/common/items.qh @@ -2,15 +2,16 @@ float BOT_PICKUP_RATING_LOW = 2500; float BOT_PICKUP_RATING_MID = 5000; float BOT_PICKUP_RATING_HIGH = 10000; -float WEP_TYPE_OTHER = 0x00; // e.g: Hook, Port-o-launch, etc -float WEP_TYPE_SPLASH = 0x01; -float WEP_TYPE_HITSCAN = 0x02; -float WEP_TYPEMASK = 0x0F; -float WEP_FLAG_CANCLIMB = 0x10; -float WEP_FLAG_NORMAL = 0x20; -float WEP_FLAG_HIDDEN = 0x40; -float WEP_FLAG_RELOADABLE = 0x80; -float WEP_FLAG_SUPERWEAPON = 0x100; +float WEP_TYPE_OTHER = 0x00; // not for damaging people +float WEP_TYPE_SPLASH = 0x01; // splash damage +float WEP_TYPE_HITSCAN = 0x02; // hitscan +float WEP_TYPEMASK = 0x0F; +float WEP_FLAG_CANCLIMB = 0x10; // can be used for movement +float WEP_FLAG_NORMAL = 0x20; // in "most weapons" set +float WEP_FLAG_HIDDEN = 0x40; // hides from menu +float WEP_FLAG_RELOADABLE = 0x80; // can has reload +float WEP_FLAG_SUPERWEAPON = 0x100; // powerup timer +float WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag) float IT_UNLIMITED_WEAPON_AMMO = 1; // when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup. @@ -71,7 +72,6 @@ string W_NumberWeaponOrder(string order); // entity properties of weaponinfo: .float weapon; // WEP_... -.float weapons; // WEPBIT_... .string netname; // short name .string message; // human readable name .float items; // IT_... @@ -83,37 +83,139 @@ string W_NumberWeaponOrder(string order); .float bot_pickupbasevalue; // bot weapon priority .string model2; // wpn- sprite name ..float ammo_field; // main ammo field +// also, weaponinfo ents can act as a WEPSET // dynamic weapon adding float w_null(float dummy); void register_weapon(float id, float(float) func, float ammotype, float i, float weapontype, float pickupbasevalue, string modelname, string shortname, string wname); void register_weapons_done(); +#define WEP_FIRST 1 float WEP_COUNT; -float WEP_FIRST = 1; float WEP_LAST; -#define WEP_MAXCOUNT 24 -float WEPBIT_ALL; -float WEPBIT_SUPERWEAPONS; -#define REGISTER_WEAPON_2(id,bit,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \ + +#if 1 +# define WEP_MAXCOUNT 24 +// default storage +.float _WS_weapons; +# define WEPSET_BIT(a) power2of((a) - WEP_FIRST) +# define WEPSET_DECLARE_A(a) float _WS_##a +# define WEPSET_CLEAR_E(e) ((e)._WS_weapons = 0) +# define WEPSET_CLEAR_A(a) ((_WS_##a) = 0) +# define WEPSET_EMPTY_E(e) ((e)._WS_weapons == 0) +# define WEPSET_EMPTY_A(a) ((_WS_##a) == 0) +# define WEPSET_COPY_AS(a) ((_WS_##a) = getstati(STAT_WEAPONS)) +# define WEPSET_ADDSTAT() addstat(STAT_WEAPONS, AS_INT, _WS_weapons) +# define WEPSET_OP1_EE(a,b,mergeop,x) ((a)._WS_weapons x (b)._WS_weapons) +# define WEPSET_OP2_EE(a,b,mergeop,x,y) ((a)._WS_weapons x (b)._WS_weapons y (a)._WS_weapons) +# define WEPSET_OP1_EA(a,b,mergeop,x) ((a)._WS_weapons x _WS_##b) +# define WEPSET_OP2_EA(a,b,mergeop,x,y) ((a)._WS_weapons x _WS_##b y (a)._WS_weapons) +# define WEPSET_OP1_EW(a,b,mergeop,x) ((a)._WS_weapons x WEPSET_BIT(b)) +# define WEPSET_OP2_EW(a,b,mergeop,x,y) ((a)._WS_weapons x WEPSET_BIT(b) y (a)._WS_weapons) +# define WEPSET_OP1_AE(a,b,mergeop,x) (_WS_##a x (b)._WS_weapons) +# define WEPSET_OP2_AE(a,b,mergeop,x,y) (_WS_##a x (b)._WS_weapons y _WS_##a) +# define WEPSET_OP1_AA(a,b,mergeop,x) (_WS_##a x _WS_##b) +# define WEPSET_OP2_AA(a,b,mergeop,x,y) (_WS_##a x _WS_##b y _WS_##a) +# define WEPSET_OP1_AW(a,b,mergeop,x) (_WS_##a x WEPSET_BIT(b)) +# define WEPSET_OP2_AW(a,b,mergeop,x,y) (_WS_##a x WEPSET_BIT(b) y _WS_##a) +#else +# define WEP_MAXCOUNT 48 +# define WEP_FIRST2 25 +.float _WS1_weapons; +.float _WS2_weapons; +# define WEPSET_BIT1(a) (((a) < WEP_FIRST2) ? power2of((a) - WEP_FIRST) : 0) +# define WEPSET_BIT2(a) (((a) >= WEP_FIRST2) ? power2of((a) - WEP_FIRST2) : 0) +# define WEPSET_DECLARE_A(a) float _WS1_##a, _WS2_##a +# define WEPSET_CLEAR_E(e) ((e)._WS1_weapons = (e)._WS2_weapons = 0) +# define WEPSET_CLEAR_A(a) ((_WS1_##a) = (_WS2_##a) = 0) +# define WEPSET_EMPTY_E(e) ((e)._WS1_weapons == 0 && (e)._WS2_weapons == 0) +# define WEPSET_EMPTY_A(a) ((_WS1_##a) == 0 && (_WS2_##a) == 0) +# define WEPSET_COPY_AS(a) ((_WS1_##a) = getstati(STAT_WEAPONS), (_WS2_##a) = getstati(STAT_WEAPONS2)) +# define WEPSET_ADDSTAT() addstat(STAT_WEAPONS, AS_INT, _WS1_weapons); addstat(STAT_WEAPONS2, AS_INT, _WS2_weapons) +# define WEPSET_OP1_EE(a,b,mergeop,x) (((a)._WS1_weapons x (b)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons)) +# define WEPSET_OP2_EE(a,b,mergeop,x,y) (((a)._WS1_weapons x (b)._WS1_weapons y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons y (a)._WS2_weapons)) +# define WEPSET_OP1_EA(a,b,mergeop,x) (((a)._WS1_weapons x _WS1_##b) mergeop ((a)._WS2_weapons x _WS2_##b)) +# define WEPSET_OP2_EA(a,b,mergeop,x,y) (((a)._WS1_weapons x _WS1_##b y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x _WS2_##b y (a)._WS2_weapons)) +# define WEPSET_OP1_EW(a,b,mergeop,x) (((a)._WS1_weapons x WEPSET_BIT1(b)) mergeop ((a)._WS2_weapons x WEPSET_BIT2(b))) +# define WEPSET_OP2_EW(a,b,mergeop,x,y) (((a)._WS1_weapons x WEPSET_BIT1(b) y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x WEPSET_BIT2(b) y (a)._WS2_weapons)) +# define WEPSET_OP1_AE(a,b,mergeop,x) ((_WS1_##a x (b)._WS1_weapons) mergeop (_WS2_##a x (b)._WS2_weapons)) +# define WEPSET_OP2_AE(a,b,mergeop,x,y) ((_WS1_##a x (b)._WS1_weapons y _WS1_##a) mergeop (_WS2_##a x (b)._WS2_weapons y _WS2_##a)) +# define WEPSET_OP1_AA(a,b,mergeop,x) ((_WS1_##a x _WS1_##b) mergeop (_WS2_##a x _WS2_##b)) +# define WEPSET_OP2_AA(a,b,mergeop,x,y) ((_WS1_##a x _WS1_##b y _WS1_##a) mergeop (_WS2_##a x _WS2_##b y _WS2_##a)) +# define WEPSET_OP1_AW(a,b,mergeop,x) ((_WS1_##a x WEPSET_BIT1(b)) mergeop (_WS2_##a x WEPSET_BIT2(b))) +# define WEPSET_OP2_AW(a,b,mergeop,x,y) ((_WS1_##a x WEPSET_BIT1(b) y _WS1_##a) mergeop (_WS2_##a x WEPSET_BIT2(b) y _WS2_##a)) +#endif + +#define XX , + +#define WEPSET_COPY_EE(a,b) WEPSET_OP1_EE(a,b,XX,=) +#define WEPSET_EQ_EE(a,b) WEPSET_OP1_EE(a,b,&&,==) +#define WEPSET_OR_EE(a,b) WEPSET_OP1_EE(a,b,XX,|=) +#define WEPSET_AND_EE(a,b) WEPSET_OP2_EE(a,b,XX,=,&) +#define WEPSET_ANDNOT_EE(a,b) WEPSET_OP1_EE(a,b,XX,&~=) +#define WEPSET_CONTAINS_ANY_EE(a,b) !!(WEPSET_OP1_EE(a,b,||,&)) +#define WEPSET_CONTAINS_ALL_EE(a,b) WEPSET_OP2_EE(b,a,&&,==,&) + +#define WEPSET_COPY_EA(a,b) WEPSET_OP1_EA(a,b,XX,=) +#define WEPSET_EQ_EA(a,b) WEPSET_OP1_EA(a,b,&&,==) +#define WEPSET_OR_EA(a,b) WEPSET_OP1_EA(a,b,XX,|=) +#define WEPSET_AND_EA(a,b) WEPSET_OP2_EA(a,b,XX,=,&) +#define WEPSET_ANDNOT_EA(a,b) WEPSET_OP1_EA(a,b,XX,&~=) +#define WEPSET_CONTAINS_ANY_EA(a,b) !!(WEPSET_OP1_EA(a,b,||,&)) +#define WEPSET_CONTAINS_ALL_EA(a,b) WEPSET_OP2_EA(b,a,&&,==,&) + +#define WEPSET_COPY_EW(a,b) WEPSET_OP1_EW(a,b,XX,=) +#define WEPSET_EQ_EW(a,b) WEPSET_OP1_EW(a,b,&&,==) +#define WEPSET_OR_EW(a,b) WEPSET_OP1_EW(a,b,XX,|=) +#define WEPSET_AND_EW(a,b) WEPSET_OP2_EW(a,b,XX,=,&) +#define WEPSET_ANDNOT_EW(a,b) WEPSET_OP1_EW(a,b,XX,&~=) +#define WEPSET_CONTAINS_EW(a,b) !!(WEPSET_OP1_EW(a,b,||,&)) + +#define WEPSET_COPY_AE(a,b) WEPSET_OP1_AE(a,b,XX,=) +#define WEPSET_EQ_AE(a,b) WEPSET_OP1_AE(a,b,&&,==) +#define WEPSET_OR_AE(a,b) WEPSET_OP1_AE(a,b,XX,|=) +#define WEPSET_AND_AE(a,b) WEPSET_OP2_AE(a,b,XX,=,&) +#define WEPSET_ANDNOT_AE(a,b) WEPSET_OP1_AE(a,b,XX,&~=) +#define WEPSET_CONTAINS_ANY_AE(a,b) !!(WEPSET_OP1_AE(a,b,||,&)) +#define WEPSET_CONTAINS_ALL_AE(a,b) WEPSET_OP2_AE(b,a,&&,==,&) + +#define WEPSET_COPY_AA(a,b) WEPSET_OP1_AA(a,b,XX,=) +#define WEPSET_EQ_AA(a,b) WEPSET_OP1_AA(a,b,&&,==) +#define WEPSET_OR_AA(a,b) WEPSET_OP1_AA(a,b,XX,|=) +#define WEPSET_AND_AA(a,b) WEPSET_OP2_AA(a,b,XX,=,&) +#define WEPSET_ANDNOT_AA(a,b) WEPSET_OP1_AA(a,b,XX,&~=) +#define WEPSET_CONTAINS_ANY_AA(a,b) !!(WEPSET_OP1_AA(a,b,||,&)) +#define WEPSET_CONTAINS_ALL_AA(a,b) WEPSET_OP2_AA(b,a,&&,==,&) + +#define WEPSET_COPY_AW(a,b) WEPSET_OP1_AW(a,b,XX,=) +#define WEPSET_EQ_AW(a,b) WEPSET_OP1_AW(a,b,&&,==) +#define WEPSET_OR_AW(a,b) WEPSET_OP1_AW(a,b,XX,|=) +#define WEPSET_AND_AW(a,b) WEPSET_OP2_AW(a,b,XX,=,&) +#define WEPSET_ANDNOT_AW(a,b) WEPSET_OP1_AW(a,b,XX,&~=) +#define WEPSET_CONTAINS_AW(a,b) !!(WEPSET_OP1_AW(a,b,||,&)) + +WEPSET_DECLARE_A(WEPBIT_ALL); +WEPSET_DECLARE_A(WEPBIT_SUPERWEAPONS); +// note: the fabs call is just there to hide "if result is constant" warning +#define REGISTER_WEAPON_2(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \ float id; \ - float bit; \ float func(float); \ void RegisterWeapons_##id() \ { \ WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \ - WEPBIT_ALL |= (bit = power2of(WEP_COUNT)); \ - WEPBIT_SUPERWEAPONS |= (bit = power2of(WEP_COUNT)) * !!(weapontype & WEP_FLAG_SUPERWEAPON); \ + WEPSET_OR_AW(WEPBIT_ALL, id); \ + if(fabs(weapontype & WEP_FLAG_SUPERWEAPON)) \ + WEPSET_OR_AW(WEPBIT_SUPERWEAPONS, id); \ ++WEP_COUNT; \ register_weapon(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname); \ } \ ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id) #ifdef MENUQC #define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \ - REGISTER_WEAPON_2(WEP_##id,WEPBIT_##id,w_null,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) + REGISTER_WEAPON_2(WEP_##id,w_null,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) #else #define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \ - REGISTER_WEAPON_2(WEP_##id,WEPBIT_##id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) + REGISTER_WEAPON_2(WEP_##id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) #endif #include "../server/w_all.qc" @@ -128,3 +230,5 @@ string W_NameWeaponOrder(string order); string W_FixWeaponOrder_BuildImpulseList(string o); string W_FixWeaponOrder_AllowIncomplete(string order); string W_FixWeaponOrder_ForceComplete(string order); + +void W_RandomWeapons(entity e, float n); diff --git a/qcsrc/common/mapinfo.qc b/qcsrc/common/mapinfo.qc index 9dd02ca4c..166acac67 100644 --- a/qcsrc/common/mapinfo.qc +++ b/qcsrc/common/mapinfo.qc @@ -536,7 +536,7 @@ string _MapInfo_GetDefaultEx(float t) { entity e; for(e = MapInfo_Type_first; e; e = e.enemy) - if(t == e.weapons) + if(t == e.items) return e.model2; return ""; } @@ -659,7 +659,7 @@ float MapInfo_Type_FromString(string t) return MAPINFO_TYPE_ALL; for(e = MapInfo_Type_first; e; e = e.enemy) if(t == e.mdl) - return e.weapons; + return e.items; return 0; } @@ -669,7 +669,7 @@ string MapInfo_Type_ToString(float t) if(t == MAPINFO_TYPE_ALL) return "all"; for(e = MapInfo_Type_first; e; e = e.enemy) - if(t == e.weapons) + if(t == e.items) return e.mdl; return ""; } @@ -678,7 +678,7 @@ string MapInfo_Type_ToText(float t) { entity e; for(e = MapInfo_Type_first; e; e = e.enemy) - if(t == e.weapons) + if(t == e.items) return e.message; return _("@!#%'n Tuba Throwing"); } @@ -1175,8 +1175,8 @@ float MapInfo_CurrentGametype() prev = cvar("gamecfg"); for(e = MapInfo_Type_first; e; e = e.enemy) if(cvar(e.netname)) - if(prev != e.weapons) - return e.weapons; + if(prev != e.items) + return e.items; if(prev) return prev; return MAPINFO_TYPE_DEATHMATCH; @@ -1205,7 +1205,7 @@ void MapInfo_SwitchGameType(float t) { entity e; for(e = MapInfo_Type_first; e; e = e.enemy) - cvar_set(e.netname, (t == e.weapons) ? "1" : "0"); + cvar_set(e.netname, (t == e.items) ? "1" : "0"); } void MapInfo_LoadMap(string s, float reinit) diff --git a/qcsrc/common/mapinfo.qh b/qcsrc/common/mapinfo.qh index a3bb4efbf..698bd7e40 100644 --- a/qcsrc/common/mapinfo.qh +++ b/qcsrc/common/mapinfo.qh @@ -3,7 +3,7 @@ entity MapInfo_Type_first; entity MapInfo_Type_last; .entity enemy; // internal next pointer -.float weapons; // game type ID +.float items; // game type ID .string netname; // game type name as in cvar (with g_ prefix) .string mdl; // game type short name .string message; // human readable name @@ -17,7 +17,7 @@ entity MapInfo_Type_last; MAPINFO_TYPE_##NAME = MAPINFO_TYPE_ALL + 1; \ MAPINFO_TYPE_ALL |= MAPINFO_TYPE_##NAME; \ MapInfo_Type##g_name = spawn(); \ - MapInfo_Type##g_name.weapons = MAPINFO_TYPE_##NAME; \ + MapInfo_Type##g_name.items = MAPINFO_TYPE_##NAME; \ MapInfo_Type##g_name.netname = #g_name; \ MapInfo_Type##g_name.mdl = #sname; \ MapInfo_Type##g_name.message = hname; \ diff --git a/qcsrc/common/util.qh b/qcsrc/common/util.qh index 76b2f28d1..64830ca1d 100644 --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@ -1,6 +1,11 @@ // a dummy macro that prevents the "hanging ;" warning #define ENDS_WITH_CURLY_BRACE +// TODO make ascii art pic of xzibit +// YO DAWG! +// I HERD YO LIEK MACROS +// SO I PUT A MACRO DEFINITION IN YO MACRO DEFINITION +// SO YO CAN EXPAND MACROS WHILE YO EXPAND MACROS #define ACCUMULATE_FUNCTION(func,otherfunc) \ #ifdef func \ void __merge__##otherfunc() { func(); otherfunc(); } \ diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c index 328e3d79e..a2d7bc29d 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c @@ -68,6 +68,8 @@ string XonoticMutatorsDialog_toString(entity me) s = strcat(s, ", ", _("Dodging")); if(cvar("g_minstagib")) s = strcat(s, ", ", _("MinstaGib")); + if(cvar("g_new_toys")) + s = strcat(s, ", ", _("New Toys")); if(cvar("g_nix")) s = strcat(s, ", ", _("NIX")); if(cvar("g_rocket_flying")) @@ -161,7 +163,6 @@ void preDrawLaserWeaponArenaLaserButton(entity me) float checkCompatibility_pinata(entity me) { - string s; if(cvar("g_minstagib")) return 0; if(cvar("g_nix")) @@ -174,6 +175,18 @@ float checkCompatibility_weaponstay(entity me) { return checkCompatibility_pinata(me); } +float checkCompatibility_newtoys(entity me) +{ + if(cvar("g_minstagib")) + return 0; + if(cvar_string("g_weaponarena") == "most") + return 1; + if(cvar_string("g_weaponarena") == "all") + return 1; + if(cvar_string("g_weaponarena") != "") + return 0; + return 1; +} void XonoticMutatorsDialog_fill(entity me) { @@ -223,6 +236,10 @@ void XonoticMutatorsDialog_fill(entity me) me.TR(me); me.TDempty(me, 0.2); me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "g_invincible_projectiles", _("Invincible Projectiles"))); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "g_new_toys", _("New Toys"))); + setDependentWeird(e, checkCompatibility_newtoys); me.TR(me); me.TDempty(me, 0.2); me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "g_rocket_flying", _("Rocket Flying"))); diff --git a/qcsrc/menu/xonotic/serverlist.c b/qcsrc/menu/xonotic/serverlist.c index fbf64c98b..f1d45ab5b 100644 --- a/qcsrc/menu/xonotic/serverlist.c +++ b/qcsrc/menu/xonotic/serverlist.c @@ -649,6 +649,7 @@ void XonoticServerList_drawListBoxItem(entity me, float i, vector absSize, float if(modname != "Xonotic") if(modname != "MinstaGib") if(modname != "CTS") + if(modname != "NIX") if(modname != "NewToys") pure = 0; diff --git a/qcsrc/menu/xonotic/weaponslist.c b/qcsrc/menu/xonotic/weaponslist.c index 1f06b9d88..6790befe1 100644 --- a/qcsrc/menu/xonotic/weaponslist.c +++ b/qcsrc/menu/xonotic/weaponslist.c @@ -97,7 +97,10 @@ void XonoticWeaponsList_drawListBoxItem(entity me, float i, vector absSize, floa if(isSelected) draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); e = get_weaponinfo(stof(argv(i))); - draw_Text(me.realUpperMargin * eY, e.message, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); + string msg = e.message; + if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED) + msg = sprintf(_("%s (mutator weapon)"), msg); + draw_Text(me.realUpperMargin * eY, msg, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0); } float XonoticWeaponsList_keyDown(entity me, float scan, float ascii, float shift) diff --git a/qcsrc/server/bot/havocbot/havocbot.qc b/qcsrc/server/bot/havocbot/havocbot.qc index 3aefc45a7..18e434171 100644 --- a/qcsrc/server/bot/havocbot/havocbot.qc +++ b/qcsrc/server/bot/havocbot/havocbot.qc @@ -94,7 +94,7 @@ void havocbot_ai() self.aistatus |= AI_STATUS_ATTACKING; self.aistatus &~= AI_STATUS_ROAMING; - if(self.weapons) + if(!WEPSET_EMPTY_E(self)) { weapon_action(self.weapon, WR_AIM); if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self)) @@ -168,7 +168,7 @@ void havocbot_ai() for(i = WEP_FIRST; i <= WEP_LAST; ++i) { e = get_weaponinfo(i); - if ((self.weapons & W_WeaponBit(i)) && (e.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[i] < cvar(strcat("g_balance_", e.netname, "_reload_ammo")))) + if (WEPSET_CONTAINS_EW(self, i) && (e.spawnflags & WEP_FLAG_RELOADABLE) && (self.weapon_load[i] < cvar(strcat("g_balance_", e.netname, "_reload_ammo")))) self.switchweapon = i; } } @@ -930,7 +930,7 @@ void havocbot_chooseenemy() // I want to do a second scan if no enemy was found or I don't have weapons // TODO: Perform the scan when using the rifle (requires changes on the rifle code) - if(best || self.weapons) // || self.weapon == WEP_RIFLE + if(best || !WEPSET_EMPTY_E(self)) // || self.weapon == WEP_RIFLE break; if(i) break; @@ -979,7 +979,7 @@ void havocbot_chooseweapon() float i; // ;) - if(g_weaponarena == WEPBIT_TUBA) + if(WEPSET_EQ_AW(g_weaponarena_weapons, WEP_TUBA)) { self.switchweapon = WEP_TUBA; return; diff --git a/qcsrc/server/bot/havocbot/role_onslaught.qc b/qcsrc/server/bot/havocbot/role_onslaught.qc index 3ae7379be..90150e2ab 100644 --- a/qcsrc/server/bot/havocbot/role_onslaught.qc +++ b/qcsrc/server/bot/havocbot/role_onslaught.qc @@ -38,7 +38,7 @@ void havocbot_goalrating_ons_offenseitems(float ratingscale, vector org, float s for(i = WEP_FIRST; i <= WEP_LAST ; ++i) { // Find weapon - if(power2of(i-1) & self.weapons) + if(WEPSET_CONTAINS_EW(self, i)) if(++c>=4) break; } @@ -58,7 +58,7 @@ void havocbot_goalrating_ons_offenseitems(float ratingscale, vector org, float s { // gather health and armor only if (head.solid) - if ( ((head.health || head.armorvalue) && needarmor) || (head.weapons && needweapons ) ) + if ( ((head.health || head.armorvalue) && needarmor) || (!WEPSET_EMPTY_E(head) && needweapons ) ) if (vlen(head.origin - org) < sradius) { t = head.bot_pickupevalfunc(self, head); diff --git a/qcsrc/server/bot/havocbot/roles.qc b/qcsrc/server/bot/havocbot/roles.qc index 91eb2ec1a..ac8ddd161 100644 --- a/qcsrc/server/bot/havocbot/roles.qc +++ b/qcsrc/server/bot/havocbot/roles.qc @@ -85,8 +85,8 @@ void havocbot_goalrating_items(float ratingscale, vector org, float sradius) if( head.armorvalue && player.armorvalue > self.armorvalue) continue; - if( head.weapons ) - if( (player.weapons & head.weapons) != head.weapons) + if( !WEPSET_EMPTY_E(head) ) + if( !WEPSET_CONTAINS_ALL_EE(player, head) ) continue; if (head.ammo_shells && player.ammo_shells > self.ammo_shells) diff --git a/qcsrc/server/cheats.qc b/qcsrc/server/cheats.qc index d52e33b0c..70297f0c5 100644 --- a/qcsrc/server/cheats.qc +++ b/qcsrc/server/cheats.qc @@ -145,7 +145,7 @@ float CheatImpulse(float i) self.personal.ammo_fuel = self.ammo_fuel; self.personal.health = self.health; self.personal.armorvalue = self.armorvalue; - self.personal.weapons = self.weapons; + WEPSET_COPY_EE(self.personal, self); self.personal.items = self.items; self.personal.pauserotarmor_finished = self.pauserotarmor_finished; self.personal.pauserothealth_finished = self.pauserothealth_finished; @@ -206,7 +206,7 @@ float CheatImpulse(float i) self.ammo_fuel = 999; self.health = start_health; self.armorvalue = start_armorvalue; - self.weapons |= weaponsInMap; + WEPSET_OR_EA(self.personal, weaponsInMap); self.pauserotarmor_finished = time + autocvar_g_balance_pause_armor_rot_spawn; self.pauserothealth_finished = time + autocvar_g_balance_pause_health_rot_spawn; self.pauserotfuel_finished = time + autocvar_g_balance_pause_fuel_rot_spawn; @@ -223,7 +223,7 @@ float CheatImpulse(float i) self.ammo_fuel = self.personal.ammo_fuel; self.health = self.personal.health; self.armorvalue = self.personal.armorvalue; - self.weapons = self.personal.weapons; + WEPSET_COPY_EE(self, self.personal); self.items = self.personal.items; self.pauserotarmor_finished = time + self.personal.pauserotarmor_finished - self.personal.teleport_time; self.pauserothealth_finished = time + self.personal.pauserothealth_finished - self.personal.teleport_time; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index d80770f97..7a0210e42 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -482,7 +482,7 @@ void PutObserverInServer (void) setorigin (self, (spot.origin + PL_VIEW_OFS)); // 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; + WEPSET_CLEAR_E(self); self.model = ""; FixPlayermodel(); setmodel(self, "null"); @@ -732,7 +732,7 @@ void PutClientInServer (void) self.ammo_fuel = warmup_start_ammo_fuel; self.health = warmup_start_health; self.armorvalue = warmup_start_armorvalue; - self.weapons = warmup_start_weapons; + WEPSET_COPY_EA(self, warmup_start_weapons); } else { @@ -743,10 +743,10 @@ void PutClientInServer (void) self.ammo_fuel = start_ammo_fuel; self.health = start_health; self.armorvalue = start_armorvalue; - self.weapons = start_weapons; + WEPSET_COPY_EA(self, start_weapons); } - if(self.weapons & WEPBIT_SUPERWEAPONS) // exception for minstagib, as minstanex is a superweapon + if(WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS)) // exception for minstagib, as minstanex is a superweapon self.superweapons_finished = time + autocvar_g_balance_superweapons_time; else self.superweapons_finished = 0; @@ -754,10 +754,10 @@ void PutClientInServer (void) if(g_weaponarena_random) { if(g_weaponarena_random_with_laser) - self.weapons &~= WEPBIT_LASER; - self.weapons = randombits(self.weapons, g_weaponarena_random, FALSE); + WEPSET_ANDNOT_EW(self, WEP_LASER); + W_RandomWeapons(self, g_weaponarena_random); if(g_weaponarena_random_with_laser) - self.weapons |= WEPBIT_LASER; + WEPSET_OR_EW(self, WEP_LASER); } self.items = start_items; @@ -1529,7 +1529,7 @@ void ClientConnect (void) if(clienttype(self) == CLIENTTYPE_REAL) { - if(autocvar_g_bugrigs || g_weaponarena == WEPBIT_TUBA) + if(autocvar_g_bugrigs || WEPSET_EQ_AW(g_weaponarena_weapons, WEP_TUBA)) stuffcmd(self, "cl_cmd settemp chase_active 1\n"); } @@ -1890,9 +1890,7 @@ void player_powerups (void) } if (self.items & IT_SUPERWEAPON) { - //if(W_WeaponBit(self.weapon) & WEPBIT_SUPERWEAPONS) - // self.effects = self.effects | EF_RED; - if (!(self.weapons & WEPBIT_SUPERWEAPONS)) + if (!WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS)) { self.superweapons_finished = 0; self.items = self.items - (self.items & IT_SUPERWEAPON); @@ -1908,12 +1906,12 @@ void player_powerups (void) if (time > self.superweapons_finished) { self.items = self.items - (self.items & IT_SUPERWEAPON); - self.weapons &~= WEPBIT_SUPERWEAPONS; + WEPSET_ANDNOT_EA(self, WEPBIT_SUPERWEAPONS); sprint(self, "^3Superweapons have broken down\n"); } } } - else if(self.weapons & WEPBIT_SUPERWEAPONS) + else if(WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS)) { if (time < self.superweapons_finished || (self.items & IT_UNLIMITED_SUPERWEAPONS)) { @@ -1923,7 +1921,7 @@ void player_powerups (void) else { self.superweapons_finished = 0; - self.weapons &~= WEPBIT_SUPERWEAPONS; // just in case + WEPSET_ANDNOT_EA(self, WEPBIT_SUPERWEAPONS); } } else @@ -2150,7 +2148,7 @@ void SpectateCopy(entity spectatee) { self.strength_finished = spectatee.strength_finished; self.invincible_finished = spectatee.invincible_finished; self.pressedkeys = spectatee.pressedkeys; - self.weapons = spectatee.weapons; + WEPSET_COPY_EE(self, spectatee); self.switchweapon = spectatee.switchweapon; self.switchingweapon = spectatee.switchingweapon; self.weapon = spectatee.weapon; diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 475171161..80f818e1f 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -360,7 +360,7 @@ void SpawnThrownWeapon (vector org, float w) float j; for(j = WEP_FIRST; j <= WEP_LAST; ++j) { - if(self.weapons & W_WeaponBit(j)) + if(WEPSET_CONTAINS_EW(self, j)) if(W_IsWeaponThrowable(j)) W_ThrowNewWeapon(self, j, FALSE, org, randomvec() * 175 + '0 0 325'); } diff --git a/qcsrc/server/cl_weapons.qc b/qcsrc/server/cl_weapons.qc index 94eaccd2d..59efb74d5 100644 --- a/qcsrc/server/cl_weapons.qc +++ b/qcsrc/server/cl_weapons.qc @@ -163,11 +163,6 @@ string W_Name(float weaponid) return (get_weaponinfo(weaponid)).message; } -float W_WeaponBit(float wpn) -{ - return (get_weaponinfo(wpn)).weapons; -} - float W_AmmoItemCode(float wpn) { return (get_weaponinfo(wpn)).items & IT_AMMO; @@ -203,7 +198,7 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto wep.flags |= FL_TOSSED; wep.colormap = own.colormap; - if(W_WeaponBit(wpn) & WEPBIT_SUPERWEAPONS) + if(WEPSET_CONTAINS_AW(WEPBIT_SUPERWEAPONS, wpn)) { if(own.items & IT_UNLIMITED_SUPERWEAPONS) { @@ -213,8 +208,9 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto { float superweapons = 1; for(i = WEP_FIRST; i <= WEP_LAST; ++i) - if(own.weapons & WEPBIT_SUPERWEAPONS & W_WeaponBit(i)) - ++superweapons; + if(WEPSET_CONTAINS_AW(WEPBIT_SUPERWEAPONS, i)) + if(WEPSET_CONTAINS_EW(own, i)) + ++superweapons; if(superweapons <= 1) { wep.superweapons_finished = own.superweapons_finished; @@ -308,7 +304,7 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto float W_IsWeaponThrowable(float w) { - float wb, wa; + float wa; if (!autocvar_g_pickup_items) return 0; @@ -323,11 +319,8 @@ float W_IsWeaponThrowable(float w) if (g_nexball && w == WEP_GRENADE_LAUNCHER) return 0; - wb = W_WeaponBit(w); - if(!wb) - return 0; wa = W_AmmoItemCode(w); - if(start_weapons & wb) + if(WEPSET_CONTAINS_AW(start_weapons, w)) { // start weapons that take no ammo can't be dropped (this prevents dropping the laser, as long as it continues to use no ammo) if(start_items & IT_UNLIMITED_WEAPON_AMMO) @@ -342,7 +335,7 @@ float W_IsWeaponThrowable(float w) // toss current weapon void W_ThrowWeapon(vector velo, vector delta, float doreduce) { - float w, wb; + float w; string a; w = self.weapon; @@ -357,11 +350,10 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce) if(!W_IsWeaponThrowable(w)) return; - wb = W_WeaponBit(w); - if(self.weapons & wb != wb) + if(!WEPSET_CONTAINS_EW(self, w)) return; + WEPSET_ANDNOT_EW(self, w); - self.weapons &~= wb; W_SwitchWeapon_Force(self, w_getbestweapon(self)); a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo); if not(a) @@ -461,8 +453,8 @@ void W_WeaponFrame() //if (self.button0) // print(ftos(frametime), " ", ftos(time), " >= ", ftos(ATTACK_FINISHED(self)), " >= ", ftos(self.weapon_nextthink), "\n"); - float wb; - wb = W_WeaponBit(self.weapon); + float w; + w = self.weapon; // call the think code which may fire the weapon // and do so multiple times to resolve framerate dependency issues if the @@ -472,18 +464,18 @@ void W_WeaponFrame() while (c < W_TICSPERFRAME) { c = c + 1; - if(wb && ((self.weapons & wb) == 0)) + if(w && !WEPSET_CONTAINS_EW(self, w)) { if(self.weapon == self.switchweapon) W_SwitchWeapon_Force(self, w_getbestweapon(self)); - wb = 0; + w = 0; } v_forward = fo; v_right = ri; v_up = up; - if(wb) + if(w) weapon_action(self.weapon, WR_THINK); else weapon_action(self.weapon, WR_GONETHINK); @@ -523,3 +515,20 @@ void W_WeaponFrame() self.currentammo = 1; #endif } + +string W_Apply_Weaponreplace(string in) +{ + float n = tokenize_console(in); + string out = ""; + float i; + for(i = 0; i < n; ++i) + { + string s = argv(i); + string r = cvar_string(strcat("g_weaponreplace_", s)); + if(r == "") + out = strcat(out, " ", s); + else if(r != "0") + out = strcat(out, " ", r); + } + return substring(out, 1, -1); +} diff --git a/qcsrc/server/cl_weaponsystem.qc b/qcsrc/server/cl_weaponsystem.qc index 4f496e56e..d2c2546d2 100644 --- a/qcsrc/server/cl_weaponsystem.qc +++ b/qcsrc/server/cl_weaponsystem.qc @@ -727,7 +727,7 @@ void Send_WeaponComplain (entity e, float wpn, string wpnname, float type) float client_hasweapon(entity cl, float wpn, float andammo, float complain) { - float weaponbit, f; + float f; entity oldself; if(time < self.hasweapon_complain_spam) @@ -741,8 +741,7 @@ float client_hasweapon(entity cl, float wpn, float andammo, float complain) sprint(self, "Invalid weapon\n"); return FALSE; } - weaponbit = W_WeaponBit(wpn); - if (cl.weapons & weaponbit) + if (WEPSET_CONTAINS_EW(cl, wpn)) { if (andammo) { @@ -783,7 +782,7 @@ float client_hasweapon(entity cl, float wpn, float andammo, float complain) { // DRESK - 3/16/07 // Report Proper Weapon Status / Modified Weapon Ownership Message - if(weaponsInMap & weaponbit) + if (WEPSET_CONTAINS_AW(weaponsInMap, wpn)) { sprint(cl, strcat("You do not have the ^2", W_Name(wpn), "\n") ); Send_WeaponComplain (cl, wpn, W_Name(wpn), 1); @@ -796,7 +795,7 @@ float client_hasweapon(entity cl, float wpn, float andammo, float complain) e = get_weaponinfo(wpn); s = e.model2; - for(e = world; (e = findfloat(e, weapons, weaponbit)); ) + for(e = world; (e = findfloat(e, weapon, wpn)); ) { if(e.classname == "droppedweapon") continue; @@ -867,10 +866,15 @@ void W_SwitchToOtherWeapon(entity pl) { // hack to ensure it switches to an OTHER weapon (in case the other fire mode still has ammo, we want that anyway) float w, ww; - w = W_WeaponBit(pl.weapon); - pl.weapons &~= w; - ww = w_getbestweapon(pl); - pl.weapons |= w; + w = pl.weapon; + if(WEPSET_CONTAINS_EW(pl, w)) + { + WEPSET_ANDNOT_EW(pl, w); + ww = w_getbestweapon(pl); + WEPSET_OR_EW(pl, w); + } + else + ww = w_getbestweapon(pl); if(ww) W_SwitchWeapon_Force(pl, ww); } diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index 8ba6659c8..56e704303 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -346,13 +346,13 @@ typedef .float floatfield; floatfield Item_CounterField(float it); float W_AmmoItemCode(float wpn); -float W_WeaponBit(float wpn); string W_Name(float weaponid); +string W_Apply_Weaponreplace(string in); void FixIntermissionClient(entity e); void FixClientCvars(entity e); -float weaponsInMap; +WEPSET_DECLARE_A(weaponsInMap); .float respawn_countdown; // next number to count @@ -487,7 +487,6 @@ float independent_players; string clientstuff; .float phase; -.float weapons; .float pressedkeys; .float porto_forbidden; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 94ceb25c7..962482ef5 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -101,10 +101,9 @@ void UpdateFrags(entity player, float f) // NOTE: f=0 means still count as a (positive) kill, but count no frags for it void W_SwitchWeapon_Force(entity e, float w); +entity GiveFrags_randomweapons; void GiveFrags (entity attacker, entity targ, float f, float deathtype) { - float w; - // TODO route through PlayerScores instead if(gameover) return; @@ -141,34 +140,42 @@ void GiveFrags (entity attacker, entity targ, float f, float deathtype) // after a frag, exchange the current weapon (or the culprit, if detectable) by a new random weapon float culprit; culprit = DEATH_WEAPONOF(deathtype); - if(!culprit || !(attacker.weapons & W_WeaponBit(culprit))) + if(!culprit || !WEPSET_CONTAINS_EW(attacker, culprit)) culprit = attacker.weapon; - if(g_weaponarena_random_with_laser && culprit == WEPBIT_LASER) + if(g_weaponarena_random_with_laser && culprit == WEP_LASER) { // no exchange } else { + if(!GiveFrags_randomweapons) + { + GiveFrags_randomweapons = spawn(); + GiveFrags_randomweapons.classname = "GiveFrags_randomweapons"; + } + if(inWarmupStage) - w = warmup_start_weapons; + WEPSET_COPY_EA(GiveFrags_randomweapons, warmup_start_weapons); else - w = start_weapons; + WEPSET_COPY_EA(GiveFrags_randomweapons, start_weapons); // all others (including the culprit): remove - w &~= attacker.weapons; + WEPSET_ANDNOT_EE(GiveFrags_randomweapons, attacker); + WEPSET_ANDNOT_EW(GiveFrags_randomweapons, culprit); // among the remaining ones, choose one by random - w = randombits(w, 1, FALSE); - if(w) + W_RandomWeapons(GiveFrags_randomweapons, 1); + + if(!WEPSET_EMPTY_E(GiveFrags_randomweapons)) { - attacker.weapons |= w; - attacker.weapons &~= W_WeaponBit(culprit); + WEPSET_OR_EE(attacker, GiveFrags_randomweapons); + WEPSET_ANDNOT_EW(attacker, culprit); } } // after a frag, choose another random weapon set - if not(attacker.weapons & W_WeaponBit(attacker.weapon)) + if not(WEPSET_CONTAINS_EW(attacker, attacker.weapon)) W_SwitchWeapon_Force(attacker, w_getbestweapon(attacker)); } diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index f8697ddcf..c2f895c48 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -368,7 +368,6 @@ void cvar_changes_init() BADCVAR("g_maplist_votable_nodetail"); BADCVAR("g_maplist_votable_suggestions"); BADCVAR("g_maxplayers"); - BADCVAR("g_minstagib"); BADCVAR("g_mirrordamage"); BADCVAR("g_nexball_goallimit"); BADCVAR("g_powerups"); @@ -415,6 +414,11 @@ void cvar_changes_init() BADPREFIX("g_warmup_"); BADPREFIX("sv_ready_restart_"); + // mutators that announce themselves properly to the server browser + BADCVAR("g_minstagib"); + BADCVAR("g_new_toys"); + BADCVAR("g_nix"); + if(autocvar_g_minstagib) { BADCVAR("g_grappling_hook"); @@ -764,7 +768,7 @@ void spawnfunc_worldspawn (void) WeaponStats_Init(); - addstat(STAT_WEAPONS, AS_INT, weapons); + WEPSET_ADDSTAT(); addstat(STAT_SWITCHWEAPON, AS_INT, switchweapon); addstat(STAT_SWITCHINGWEAPON, AS_INT, switchingweapon); addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime); diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 00849718e..487caa26d 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -740,6 +740,7 @@ float g_pickup_healthmega_anyway; float g_pickup_ammo_anyway; float g_pickup_weapons_anyway; float g_weaponarena; +WEPSET_DECLARE_A(g_weaponarena_weapons); float g_weaponarena_random; float g_weaponarena_random_with_laser; string g_weaponarena_list; @@ -749,7 +750,9 @@ float g_weapondamagefactor; float g_weaponforcefactor; float g_weaponspreadfactor; -float start_weapons; +WEPSET_DECLARE_A(start_weapons); +WEPSET_DECLARE_A(start_weapons_default); +WEPSET_DECLARE_A(start_weapons_defaultmask); float start_items; float start_ammo_shells; float start_ammo_nails; @@ -758,7 +761,9 @@ float start_ammo_cells; float start_ammo_fuel; float start_health; float start_armorvalue; -float warmup_start_weapons; +WEPSET_DECLARE_A(warmup_start_weapons); +WEPSET_DECLARE_A(warmup_start_weapons_default); +WEPSET_DECLARE_A(warmup_start_weapons_defaultmask); float warmup_start_ammo_shells; float warmup_start_ammo_nails; float warmup_start_ammo_rockets; @@ -774,27 +779,34 @@ entity get_weaponinfo(float w); float want_weapon(string cvarprefix, entity weaponinfo, float allguns) { var float i = weaponinfo.weapon; + var float d = 0; if (!i) return 0; - var float t = cvar(strcat(cvarprefix, weaponinfo.netname)); + if (g_lms || g_ca || allguns) + d = (weaponinfo.spawnflags & WEP_FLAG_NORMAL); + else if (g_cts) + d = (i == WEP_SHOTGUN); + else if (g_nexball) + d = 0; // weapon is set a few lines later + else + d = (i == WEP_LASER || i == WEP_SHOTGUN); + if(g_grappling_hook) // if possible, redirect off-hand hook to on-hand hook + d |= (i == WEP_HOOK); + if(weaponinfo.spawnflags & WEP_FLAG_MUTATORBLOCKED) // never default mutator blocked guns + d = 0; - if (t < 0) // "default" weapon selection - { - if (g_lms || g_ca || allguns) - t = (weaponinfo.spawnflags & WEP_FLAG_NORMAL); - else if(t < -1) - t = 0; - else if (g_cts) - t = (i == WEP_SHOTGUN); - else if (g_nexball) - t = 0; // weapon is set a few lines later - else - t = (i == WEP_LASER || i == WEP_SHOTGUN); - if(g_grappling_hook) // if possible, redirect off-hand hook to on-hand hook - t |= (i == WEP_HOOK); - } + var float t = cvar(strcat(cvarprefix, weaponinfo.netname)); + + // bit order in t: + // 1: want or not + // 2: is default? + // 4: is set by default? + if(t < 0) + t = 4 | (3 * d); + else + t |= (2 * d); return t; } @@ -806,7 +818,9 @@ void readplayerstartcvars() string s; // initialize starting values for players - start_weapons = 0; + WEPSET_CLEAR_A(start_weapons); + WEPSET_CLEAR_A(start_weapons_default); + WEPSET_CLEAR_A(start_weapons_defaultmask); start_items = 0; start_ammo_shells = 0; start_ammo_nails = 0; @@ -816,6 +830,8 @@ void readplayerstartcvars() start_armorvalue = cvar("g_balance_armor_start"); g_weaponarena = 0; + WEPSET_CLEAR_A(g_weaponarena_weapons); + s = cvar_string("g_weaponarena"); if (s == "0" || s == "") { @@ -833,34 +849,32 @@ void readplayerstartcvars() } else if (s == "all") { + g_weaponarena = 1; g_weaponarena_list = "All Weapons"; for (j = WEP_FIRST; j <= WEP_LAST; ++j) - { - e = get_weaponinfo(j); - g_weaponarena |= e.weapons; - weapon_action(e.weapon, WR_PRECACHE); - } + if not(e.spawnflags & WEP_FLAG_MUTATORBLOCKED) + WEPSET_OR_AW(g_weaponarena_weapons, j); } else if (s == "most") { + g_weaponarena = 1; g_weaponarena_list = "Most Weapons"; for (j = WEP_FIRST; j <= WEP_LAST; ++j) { e = get_weaponinfo(j); - if (e.spawnflags & WEP_FLAG_NORMAL) - { - g_weaponarena |= e.weapons; - weapon_action(e.weapon, WR_PRECACHE); - } + if not(e.spawnflags & WEP_FLAG_MUTATORBLOCKED) + if (e.spawnflags & WEP_FLAG_NORMAL) + WEPSET_OR_AW(g_weaponarena_weapons, j); } } else if (s == "none") { + g_weaponarena = 1; g_weaponarena_list = "No Weapons"; - g_weaponarena = WEPBIT_ALL + 1; // this supports no single weapon bit! } else { + g_weaponarena = 1; t = tokenize_console(s); g_weaponarena_list = ""; for (i = 0; i < t; ++i) @@ -871,8 +885,7 @@ void readplayerstartcvars() e = get_weaponinfo(j); if (e.netname == s) { - g_weaponarena |= e.weapons; - weapon_action(e.weapon, WR_PRECACHE); + WEPSET_OR_AW(g_weaponarena_weapons, j); g_weaponarena_list = strcat(g_weaponarena_list, e.message, " & "); break; } @@ -896,7 +909,7 @@ void readplayerstartcvars() g_minstagib = 0; // incompatible g_pinata = 0; // incompatible g_weapon_stay = 0; // incompatible - start_weapons = g_weaponarena; + WEPSET_COPY_AA(start_weapons, g_weaponarena_weapons); if(!(g_lms || g_ca)) start_items |= IT_UNLIMITED_AMMO; } @@ -907,8 +920,7 @@ void readplayerstartcvars() g_bloodloss = 0; // incompatible start_health = 100; start_armorvalue = 0; - start_weapons = WEPBIT_MINSTANEX; - weapon_action(WEP_MINSTANEX, WR_PRECACHE); + WEPSET_COPY_AW(start_weapons, WEP_MINSTANEX); g_minstagib_invis_alpha = cvar("g_minstagib_invis_alpha"); start_items |= IT_UNLIMITED_SUPERWEAPONS; @@ -920,8 +932,13 @@ void readplayerstartcvars() for (i = WEP_FIRST; i <= WEP_LAST; ++i) { e = get_weaponinfo(i); - if(want_weapon("g_start_weapon_", e, FALSE)) - start_weapons |= e.weapons; + float w = want_weapon("g_start_weapon_", e, FALSE); + if(w & 1) + WEPSET_OR_AW(start_weapons, i); + if(w & 2) + WEPSET_OR_AW(start_weapons_default, i); + if(w & 4) + WEPSET_OR_AW(start_weapons_defaultmask, i); } } @@ -979,7 +996,9 @@ void readplayerstartcvars() warmup_start_ammo_fuel = start_ammo_fuel; warmup_start_health = start_health; warmup_start_armorvalue = start_armorvalue; - warmup_start_weapons = start_weapons; + WEPSET_COPY_AA(warmup_start_weapons, start_weapons); + WEPSET_COPY_AA(warmup_start_weapons_default, start_weapons_default); + WEPSET_COPY_AA(warmup_start_weapons_defaultmask, start_weapons_defaultmask); if (!g_weaponarena && !g_minstagib && !g_ca) { @@ -990,17 +1009,27 @@ void readplayerstartcvars() warmup_start_ammo_fuel = cvar("g_warmup_start_ammo_fuel"); warmup_start_health = cvar("g_warmup_start_health"); warmup_start_armorvalue = cvar("g_warmup_start_armor"); - warmup_start_weapons = 0; + WEPSET_CLEAR_A(warmup_start_weapons); for (i = WEP_FIRST; i <= WEP_LAST; ++i) { e = get_weaponinfo(i); - if(want_weapon("g_start_weapon_", e, cvar("g_warmup_allguns"))) - warmup_start_weapons |= e.weapons; + float w = want_weapon("g_start_weapon_", e, cvar("g_warmup_allguns")); + if(w & 1) + WEPSET_OR_AW(warmup_start_weapons, i); + if(w & 2) + WEPSET_OR_AW(warmup_start_weapons_default, i); + if(w & 4) + WEPSET_OR_AW(warmup_start_weapons_defaultmask, i); } } } - if (g_jetpack || (g_grappling_hook && (start_weapons & WEPBIT_HOOK))) + if (g_jetpack) + start_items |= IT_JETPACK; + + MUTATOR_CALLHOOK(SetStartItems); + + if ((start_items & IT_JETPACK) || (g_grappling_hook && WEPSET_CONTAINS_AW(start_weapons, WEP_HOOK))) { g_grappling_hook = 0; // these two can't coexist, as they use the same button start_items |= IT_FUEL_REGEN; @@ -1008,16 +1037,11 @@ void readplayerstartcvars() warmup_start_ammo_fuel = max(warmup_start_ammo_fuel, cvar("g_balance_fuel_rotstable")); } - if (g_jetpack) - start_items |= IT_JETPACK; - - MUTATOR_CALLHOOK(SetStartItems); - for (i = WEP_FIRST; i <= WEP_LAST; ++i) { e = get_weaponinfo(i); - if(e.weapons & (start_weapons | warmup_start_weapons)) - weapon_action(e.weapon, WR_PRECACHE); + if(WEPSET_CONTAINS_AW(start_weapons, i) || WEPSET_CONTAINS_AW(warmup_start_weapons, i)) + weapon_action(i, WR_PRECACHE); } start_ammo_shells = max(0, start_ammo_shells); @@ -1065,19 +1089,26 @@ float sv_pitch_fixyaw; string GetGametype(); // g_world.qc void readlevelcvars(void) { - // first load all the mutators - if(cvar("g_invincible_projectiles")) - MUTATOR_ADD(mutator_invincibleprojectiles); - if(cvar("g_nix")) - MUTATOR_ADD(mutator_nix); + g_minstagib = cvar("g_minstagib"); + + // load ALL the mutators if(cvar("g_dodging")) MUTATOR_ADD(mutator_dodging); - if(cvar("g_rocket_flying")) - MUTATOR_ADD(mutator_rocketflying); - if(cvar("g_vampire")) - MUTATOR_ADD(mutator_vampire); if(cvar("g_spawn_near_teammate")) MUTATOR_ADD(mutator_spawn_near_teammate); + if(!g_minstagib) + { + if(cvar("g_invincible_projectiles")) + MUTATOR_ADD(mutator_invincibleprojectiles); + if(cvar("g_new_toys")) + MUTATOR_ADD(mutator_new_toys); + if(cvar("g_nix")) + MUTATOR_ADD(mutator_nix); + if(cvar("g_rocket_flying")) + MUTATOR_ADD(mutator_rocketflying); + if(cvar("g_vampire")) + MUTATOR_ADD(mutator_vampire); + } // is this a mutator? is this a mode? if(cvar("g_sandbox")) @@ -1123,7 +1154,6 @@ void readlevelcvars(void) g_grappling_hook = cvar("g_grappling_hook"); g_jetpack = cvar("g_jetpack"); g_midair = cvar("g_midair"); - g_minstagib = cvar("g_minstagib"); g_norecoil = cvar("g_norecoil"); g_bloodloss = cvar("g_bloodloss"); sv_maxidle = cvar("sv_maxidle"); diff --git a/qcsrc/server/mutators/base.qh b/qcsrc/server/mutators/base.qh index a8828f8c6..cd9c36fa0 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -206,6 +206,13 @@ MUTATOR_HOOKABLE(SetModname); // OUT string modname; // name of the mutator/mod if it warrants showing as such in the server browser +MUTATOR_HOOKABLE(SetWeaponreplace); + // IN + entity self; // map entity + entity other; // weapon info + // IN+OUT + string ret_string; + MUTATOR_HOOKABLE(PortalTeleport); // called whenever a player goes through a portal gun teleport // allows you to strip a player of an item if they go through the teleporter to help prevent cheating diff --git a/qcsrc/server/mutators/gamemode_nexball.qc b/qcsrc/server/mutators/gamemode_nexball.qc index c27c466a6..9d7870aca 100644 --- a/qcsrc/server/mutators/gamemode_nexball.qc +++ b/qcsrc/server/mutators/gamemode_nexball.qc @@ -139,9 +139,9 @@ void GiveBall(entity plyr, entity ball) ownr = self; self = plyr; - self.weaponentity.weapons = self.weapons; + WEPSET_COPY_EE(self.weaponentity, self); self.weaponentity.switchweapon = self.weapon; - self.weapons = W_WeaponBit(WEP_PORTO); + WEPSET_COPY_EW(self, WEP_PORTO); weapon_action(WEP_PORTO, WR_RESETPLAYER); self.switchweapon = WEP_PORTO; W_SwitchWeapon(WEP_PORTO); @@ -921,14 +921,14 @@ MUTATOR_HOOKFUNCTION(nexball_PlayerPreThink) } else { - if(self.weaponentity.weapons) + if(!WEPSET_EMPTY_E(self.weaponentity)) { - self.weapons = self.weaponentity.weapons; + WEPSET_COPY_EE(self, self.weaponentity); weapon_action(WEP_PORTO, WR_RESETPLAYER); self.switchweapon = self.weaponentity.switchweapon; W_SwitchWeapon(self.switchweapon); - self.weaponentity.weapons = 0; + WEPSET_CLEAR_E(self.weaponentity); } } @@ -938,12 +938,12 @@ MUTATOR_HOOKFUNCTION(nexball_PlayerPreThink) MUTATOR_HOOKFUNCTION(nexball_PlayerSpawn) { - self.weaponentity.weapons = 0; + WEPSET_CLEAR_E(self.weaponentity); if(nexball_mode & NBM_BASKETBALL) - self.weapons |= W_WeaponBit(WEP_PORTO); + WEPSET_OR_EW(self, WEP_PORTO); else - self.weapons = 0; // W_WeaponBit(WEP_PORTO); + WEPSET_CLEAR_E(self); return FALSE; } diff --git a/qcsrc/server/mutators/mutator_new_toys.qc b/qcsrc/server/mutators/mutator_new_toys.qc new file mode 100644 index 000000000..cc4f94324 --- /dev/null +++ b/qcsrc/server/mutators/mutator_new_toys.qc @@ -0,0 +1,217 @@ +/* + +CORE laser nex lg rl cry gl elec hagar fireb hook + minsta porto + tuba + +NEW rifle hlac minel seeker +IDEAS OPEN flak OPEN FUN FUN FUN FUN + + + +How this mutator works: + ======================= + +When a gun tries to spawn, this mutator is called. It will provide alternate +weaponreplace lists. + +Entity: + +{ +"classname" "weapon_nex" +"new_toys" "rifle" +} +-> This will spawn as Rifle in this mutator ONLY, and as Nex otherwise. + +{ +"classname" "weapon_nex" +"new_toys" "nex rifle" +} +-> This will spawn as either Nex or Rifle in this mutator ONLY, and as Nex otherwise. + +{ +"classname" "weapon_nex" +"new_toys" "nex" +} +-> This is always a Nex. + +If the map specifies no "new_toys" argument + +There will be two default replacements selectable: "replace all" and "replace random". +In "replace all" mode, e.g. Nex will have the default replacement "rifle". +In "replace random" mode, Nex will have the default replacement "nex rifle". + +This mutator's replacements run BEFORE regular weaponreplace! + +The New Toys guns do NOT get a spawn function, so they can only ever be spawned +when this mutator is active. + +Likewise, warmup, give all, give ALL and impulse 99 will not give them unless +this mutator is active. + +Outside this mutator, they still can be spawned by: +- setting their start weapon cvar to 1 +- give weaponname +- weaponreplace +- weaponarena (but all and most weapons arena again won't include them) + +This mutator performs the default replacements on the DEFAULTS of the +start weapon selection. + +These weapons appear in the menu's priority list, BUT get a suffix +"(Mutator weapon)". + +Picking up a "new toys" weapon will not play standard weapon pickup sound, but +roflsound "New toys, new toys!" sound. + +*/ + +.string new_toys; + +float autocvar_g_new_toys_autoreplace; +#define NT_AUTOREPLACE_NEVER 0 +#define NT_AUTOREPLACE_ALWAYS 1 +#define NT_AUTOREPLACE_RANDOM 2 + +MUTATOR_HOOKFUNCTION(nt_SetModname) +{ + modname = "NewToys"; + return 0; +} + +float nt_IsNewToy(float w) +{ + switch(w) + { + case WEP_SEEKER: + case WEP_MINE_LAYER: + case WEP_HLAC: + case WEP_RIFLE: + return TRUE; + default: + return FALSE; + } +} + +string nt_GetFullReplacement(string w) +{ + switch(w) + { + case "hagar": return "seeker"; + case "rocketlauncher": return "minelayer"; + case "uzi": return "hlac"; + case "nex": return "rifle"; + default: return string_null; + } +} + +string nt_GetReplacement(string w, float m) +{ + if(m == NT_AUTOREPLACE_NEVER) + return w; + string s = nt_GetFullReplacement(w); + if not(s) + return w; + if(m == NT_AUTOREPLACE_RANDOM) + s = strcat(w, " ", s); + return s; +} + +MUTATOR_HOOKFUNCTION(nt_SetStartItems) +{ + // rearrange start_weapon_default + // apply those bits that are set by start_weapon_defaultmask + // same for warmup + + float i, j, k, n; + + WEPSET_DECLARE_A(newdefault); + WEPSET_DECLARE_A(warmup_newdefault); + + WEPSET_CLEAR_A(newdefault); + WEPSET_CLEAR_A(warmup_newdefault); + + for(i = WEP_FIRST; i <= WEP_LAST; ++i) + { + entity e = get_weaponinfo(i); + if(!e.weapon) + continue; + + n = tokenize_console(nt_GetReplacement(e.netname, autocvar_g_new_toys_autoreplace)); + + for(j = 0; j < n; ++j) + for(k = WEP_FIRST; k <= WEP_LAST; ++k) + if(get_weaponinfo(k).netname == argv(j)) + { + if(WEPSET_CONTAINS_AW(start_weapons, i)) + WEPSET_OR_AW(newdefault, k); + if(WEPSET_CONTAINS_AW(warmup_start_weapons, i)) + WEPSET_OR_AW(warmup_newdefault, k); + } + } + + WEPSET_AND_AA(newdefault, start_weapons_defaultmask); + WEPSET_ANDNOT_AA(start_weapons, start_weapons_defaultmask); + WEPSET_OR_AA(start_weapons, newdefault); + + WEPSET_AND_AA(warmup_newdefault, warmup_start_weapons_defaultmask); + WEPSET_ANDNOT_AA(warmup_start_weapons, warmup_start_weapons_defaultmask); + WEPSET_OR_AA(warmup_start_weapons, warmup_newdefault); + + return 0; +} + +MUTATOR_HOOKFUNCTION(nt_SetWeaponreplace) +{ + // otherwise, we do replace + if(self.new_toys) + { + // map defined replacement: + ret_string = self.new_toys; + } + else + { + // auto replacement: + ret_string = nt_GetReplacement(other.netname, autocvar_g_new_toys_autoreplace); + } + + // apply regular weaponreplace + ret_string = W_Apply_Weaponreplace(ret_string); + + return 0; +} + +MUTATOR_HOOKFUNCTION(nt_FilterItem) +{ + if(nt_IsNewToy(self.weapon)) + self.item_pickupsound = "weapons/weaponpickup_new_toys.ogg"; + return 0; +} + +MUTATOR_DEFINITION(mutator_new_toys) +{ + MUTATOR_HOOK(SetModname, nt_SetModname, CBC_ORDER_ANY); + MUTATOR_HOOK(SetStartItems, nt_SetStartItems, CBC_ORDER_ANY); + MUTATOR_HOOK(SetWeaponreplace, nt_SetWeaponreplace, CBC_ORDER_LAST); + MUTATOR_HOOK(FilterItem, nt_FilterItem, CBC_ORDER_ANY); + + MUTATOR_ONADD + { + if(time > 1) // game loads at time 1 + error("This cannot be added at runtime\n"); + + precache_sound("weapons/weaponpickup_new_toys.ogg"); + + // mark the guns as ok to use by e.g. impulse 99 + float i; + for(i = WEP_FIRST; i <= WEP_LAST; ++i) + if(nt_IsNewToy(i)) + get_weaponinfo(i).spawnflags &~= WEP_FLAG_MUTATORBLOCKED; + } + MUTATOR_ONREMOVE + { + error("This cannot be removed at runtime\n"); + } + + return 0; +} diff --git a/qcsrc/server/mutators/mutator_nix.qc b/qcsrc/server/mutators/mutator_nix.qc index 28bb84469..dad19e4a3 100644 --- a/qcsrc/server/mutators/mutator_nix.qc +++ b/qcsrc/server/mutators/mutator_nix.qc @@ -9,28 +9,23 @@ float nix_nextweapon_ammo; .float nix_lastinfotime; .float nix_nextincr; -.float nix_save_cells; -.float nix_save_shells; -.float nix_save_nails; -.float nix_save_rockets; -.float nix_save_fuel; -.float nix_save_weapons; - float NIX_CanChooseWeapon(float wpn) { entity e; e = get_weaponinfo(wpn); - if(!e.weapons) // skip dummies + if(!e.weapon) // skip dummies return FALSE; if(g_weaponarena) { - if not(g_weaponarena & e.weapons) + if not(WEPSET_CONTAINS_AW(g_weaponarena_weapons, wpn)) return FALSE; } else { if(wpn == WEP_LASER && g_nix_with_laser) return FALSE; + if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED) + return FALSE; if not(e.spawnflags & WEP_FLAG_NORMAL) return FALSE; } @@ -141,10 +136,10 @@ void NIX_GiveCurrentWeapon() self.nix_nextincr = time + autocvar_g_balance_nix_incrtime; } - self.weapons = 0; + WEPSET_CLEAR_E(self); if(g_nix_with_laser) - self.weapons = self.weapons | WEPBIT_LASER; - self.weapons = self.weapons | W_WeaponBit(nix_weapon); + WEPSET_ANDNOT_EW(self, WEP_LASER); + WEPSET_OR_EW(self, nix_weapon); if(self.switchweapon != nix_weapon) if(!client_hasweapon(self, self.switchweapon, TRUE, FALSE)) @@ -165,15 +160,6 @@ MUTATOR_HOOKFUNCTION(nix_ForbidThrowCurrentWeapon) return 1; // no throwing in NIX } -MUTATOR_HOOKFUNCTION(nix_SetStartItems) -{ - NIX_precache(); - // we do NOT change the start weapons any more, so we can later turn off the mutator! - // start_weapons = 0; // will be done later, when player spawns - // warmup_start_weapons = 0; // will be done later, when player spawns - return 0; -} - MUTATOR_HOOKFUNCTION(nix_BuildMutatorsString) { ret_string = strcat(ret_string, ":NIX"); @@ -232,18 +218,24 @@ MUTATOR_HOOKFUNCTION(nix_PlayerSpawn) return 0; } +MUTATOR_HOOKFUNCTION(nix_SetModname) +{ + modname = "NIX"; + return 0; +} + MUTATOR_DEFINITION(mutator_nix) { entity e; MUTATOR_HOOK(ForbidThrowCurrentWeapon, nix_ForbidThrowCurrentWeapon, CBC_ORDER_ANY); - MUTATOR_HOOK(SetStartItems, nix_SetStartItems, CBC_ORDER_EXCLUSIVE); MUTATOR_HOOK(BuildMutatorsString, nix_BuildMutatorsString, CBC_ORDER_ANY); MUTATOR_HOOK(BuildMutatorsPrettyString, nix_BuildMutatorsPrettyString, CBC_ORDER_ANY); MUTATOR_HOOK(FilterItem, nix_FilterItem, CBC_ORDER_ANY); MUTATOR_HOOK(OnEntityPreSpawn, nix_OnEntityPreSpawn, CBC_ORDER_ANY); MUTATOR_HOOK(PlayerPreThink, nix_PlayerPreThink, CBC_ORDER_ANY); MUTATOR_HOOK(PlayerSpawn, nix_PlayerSpawn, CBC_ORDER_ANY); + MUTATOR_HOOK(SetModname, nix_SetModname, CBC_ORDER_LAST); MUTATOR_ONADD { @@ -253,28 +245,6 @@ MUTATOR_DEFINITION(mutator_nix) nix_nextweapon = 0; NIX_precache(); - - FOR_EACH_PLAYER(e) - { - if(e.deadflag == DEAD_NO) - { - e.nix_save_cells = e.ammo_cells; - e.nix_save_shells = e.ammo_shells; - e.nix_save_nails = e.ammo_nails; - e.nix_save_rockets = e.ammo_rockets; - e.nix_save_fuel = e.ammo_fuel; - e.nix_save_weapons = e.weapons; - } - else - { - e.nix_save_cells = 0; - e.nix_save_shells = 0; - e.nix_save_nails = 0; - e.nix_save_rockets = 0; - e.nix_save_fuel = 0; - e.nix_save_weapons = 0; - } - } } MUTATOR_ONREMOVE @@ -283,12 +253,12 @@ MUTATOR_DEFINITION(mutator_nix) FOR_EACH_PLAYER(e) if(e.deadflag == DEAD_NO) { - e.ammo_cells = max(start_ammo_cells, e.nix_save_cells); - e.ammo_shells = max(start_ammo_shells, e.nix_save_shells); - e.ammo_nails = max(start_ammo_nails, e.nix_save_nails); - e.ammo_rockets = max(start_ammo_rockets, e.nix_save_rockets); - e.ammo_fuel = max(start_ammo_fuel, e.nix_save_fuel); - e.weapons = (start_weapons | e.nix_save_weapons); + e.ammo_cells = start_ammo_cells; + e.ammo_shells = start_ammo_shells; + e.ammo_nails = start_ammo_nails; + e.ammo_rockets = start_ammo_rockets; + e.ammo_fuel = start_ammo_fuel; + WEPSET_COPY_EA(e, start_weapons); if(!client_hasweapon(e, e.weapon, TRUE, FALSE)) e.switchweapon = w_getbestweapon(self); } diff --git a/qcsrc/server/mutators/mutators.qh b/qcsrc/server/mutators/mutators.qh index debdae989..7c797848a 100644 --- a/qcsrc/server/mutators/mutators.qh +++ b/qcsrc/server/mutators/mutators.qh @@ -4,12 +4,12 @@ MUTATOR_DECLARATION(gamemode_keepaway); MUTATOR_DECLARATION(gamemode_ctf); MUTATOR_DECLARATION(gamemode_nexball); +MUTATOR_DECLARATION(mutator_dodging); MUTATOR_DECLARATION(mutator_invincibleprojectiles); +MUTATOR_DECLARATION(mutator_new_toys); MUTATOR_DECLARATION(mutator_nix); -MUTATOR_DECLARATION(mutator_dodging); MUTATOR_DECLARATION(mutator_rocketflying); -MUTATOR_DECLARATION(mutator_vampire); -MUTATOR_DECLARATION(mutator_spawn_near_teammate); MUTATOR_DECLARATION(mutator_spawn_near_teammate); +MUTATOR_DECLARATION(mutator_vampire); MUTATOR_DECLARATION(sandbox); diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index c20090022..a0afb040c 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -212,6 +212,7 @@ mutators/gamemode_keyhunt.qc mutators/gamemode_keepaway.qc mutators/gamemode_nexball.qc mutators/mutator_invincibleproj.qc +mutators/mutator_new_toys.qc mutators/mutator_nix.qc mutators/mutator_dodging.qc mutators/mutator_rocketflying.qc diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc index 5b9a2e5f9..76a7838f2 100644 --- a/qcsrc/server/t_items.qc +++ b/qcsrc/server/t_items.qc @@ -29,7 +29,7 @@ float have_pickup_item(void) if(g_ca) return FALSE; if(g_weaponarena) - if((self.weapons & WEPBIT_ALL) || (self.items & IT_AMMO)) + if(!WEPSET_EMPTY_E(self) || (self.items & IT_AMMO)) return FALSE; } return TRUE; @@ -83,7 +83,7 @@ float Item_Customize() { if(self.spawnshieldtime) return TRUE; - if(self.weapons != (self.weapons & other.weapons)) + if(!WEPSET_CONTAINS_ALL_EE(other, self)) { self.colormod = '0 0 0'; self.glowmod = self.colormod; @@ -265,7 +265,7 @@ void Item_RespawnCountdown (void) void Item_ScheduleRespawnIn(entity e, float t) { - if((e.flags & FL_POWERUP) || (e.weapons & WEPBIT_SUPERWEAPONS)) + if((e.flags & FL_POWERUP) || WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS)) { e.think = Item_RespawnCountdown; e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS); @@ -348,7 +348,6 @@ float Item_GiveTo(entity item, entity player) float pickedup; float it; float i; - entity e; // if nothing happens to player, just return without taking the item pickedup = FALSE; @@ -377,7 +376,7 @@ float Item_GiveTo(entity item, entity player) // else if(item.items == IT_CELLS) // AnnounceTo(player, "ammo"); - if (item.weapons & WEPBIT_MINSTANEX) + if (WEPSET_CONTAINS_EW(item, WEP_MINSTANEX)) W_GiveWeapon (player, WEP_MINSTANEX, item.netname); player.health = 100; } @@ -426,7 +425,7 @@ float Item_GiveTo(entity item, entity player) if (player.switchweapon == w_getbestweapon(player)) _switchweapon = TRUE; - if not(player.weapons & W_WeaponBit(player.switchweapon)) + if not(WEPSET_CONTAINS_EW(player, player.switchweapon)) _switchweapon = TRUE; pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL); @@ -438,14 +437,17 @@ float Item_GiveTo(entity item, entity player) pickedup |= Item_GiveAmmoTo(item, player, armorvalue, item.max_armorvalue, ITEM_MODE_ARMOR); if (item.flags & FL_WEAPON) - if ((it = item.weapons - (item.weapons & player.weapons)) || (item.spawnshieldtime && self.pickup_anyway)) { - pickedup = TRUE; - for(i = WEP_FIRST; i <= WEP_LAST; ++i) + WEPSET_DECLARE_A(it); + WEPSET_COPY_AE(it, item); + WEPSET_ANDNOT_AE(it, player); + + if (!WEPSET_EMPTY_A(it) || (item.spawnshieldtime && self.pickup_anyway)) { - e = get_weaponinfo(i); - if(it & e.weapons) - W_GiveWeapon (player, e.weapon, item.netname); + pickedup = TRUE; + for(i = WEP_FIRST; i <= WEP_LAST; ++i) + if(WEPSET_CONTAINS_AW(it, i)) + W_GiveWeapon (player, i, item.netname); } } @@ -573,7 +575,7 @@ void Item_Reset() if(self.waypointsprite_attached) WaypointSprite_Kill(self.waypointsprite_attached); - if((self.flags & FL_POWERUP) | (self.weapons & WEPBIT_SUPERWEAPONS)) // do not spawn powerups initially! + if((self.flags & FL_POWERUP) | WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS)) // do not spawn powerups initially! Item_ScheduleInitialRespawn(self); } } @@ -622,10 +624,10 @@ float generic_pickupevalfunc(entity player, entity item) {return item.bot_pickup float weapon_pickupevalfunc(entity player, entity item) { - float c, i, j, position; + float c, j, position; // See if I have it already - if(player.weapons & item.weapons == item.weapons) + if(!WEPSET_CONTAINS_ALL_EE(player, item)) { // If I can pick it up if(!item.spawnshieldtime) @@ -644,34 +646,27 @@ float weapon_pickupevalfunc(entity player, entity item) // If custom weapon priorities for bots is enabled rate most wanted weapons higher if( bot_custom_weapon && c ) { - for(i = WEP_FIRST; i <= WEP_LAST ; ++i) - { - // Find weapon - if( (get_weaponinfo(i)).weapons & item.weapons != item.weapons ) - continue; - - // Find the highest position on any range - position = -1; - for(j = 0; j < WEP_LAST ; ++j){ - if( - bot_weapons_far[j] == i || - bot_weapons_mid[j] == i || - bot_weapons_close[j] == i - ) - { - position = j; - break; - } - } - - // Rate it - if (position >= 0 ) + // Find the highest position on any range + position = -1; + for(j = 0; j < WEP_LAST ; ++j){ + if( + bot_weapons_far[j] == item.weapon || + bot_weapons_mid[j] == item.weapon || + bot_weapons_close[j] == item.weapon + ) { - position = WEP_LAST - position; - // item.bot_pickupbasevalue is overwritten here - return (BOT_PICKUP_RATING_LOW + ( (BOT_PICKUP_RATING_HIGH - BOT_PICKUP_RATING_LOW) * (position / WEP_LAST ))) * c; + position = j; + break; } } + + // Rate it + if (position >= 0 ) + { + position = WEP_LAST - position; + // item.bot_pickupbasevalue is overwritten here + return (BOT_PICKUP_RATING_LOW + ( (BOT_PICKUP_RATING_HIGH - BOT_PICKUP_RATING_LOW) * (position / WEP_LAST ))) * c; + } } return item.bot_pickupbasevalue * c; @@ -688,7 +683,7 @@ float commodity_pickupevalfunc(entity player, entity item) { wi = get_weaponinfo(i); - if not(wi.weapons & player.weapons) + if not(WEPSET_CONTAINS_EW(player, i)) continue; if(wi.items & IT_SHELLS) @@ -747,10 +742,30 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime, { startitem_failed = FALSE; + if(self.model == "") + self.model = itemmodel; + if(self.item_pickupsound == "") + self.item_pickupsound = pickupsound; + if(!self.respawntime) // both need to be set + { + self.respawntime = defaultrespawntime; + self.respawntimejitter = defaultrespawntimejitter; + } + self.items = itemid; - self.weapons = weaponid; + self.weapon = weaponid; + + if(weaponid) + WEPSET_COPY_EW(self, weaponid); self.flags = FL_ITEM | itemflags; + if(MUTATOR_CALLHOOK(FilterItem)) // error means we do not want the item + { + startitem_failed = TRUE; + remove(self); + return; + } + // is it a dropped weapon? if (self.classname == "droppedweapon") { @@ -768,7 +783,7 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime, if(self.strength_finished || self.invincible_finished || self.superweapons_finished) /* if(self.items == 0) - if(self.weapons == (self.weapons & WEPBIT_SUPERWEAPONS)) // only superweapons + if(WEPSET_CONTAINS_ALL_AE(WEPBIT_SUPERWEAPONS, self)) // only superweapons if(self.ammo_nails == 0) if(self.ammo_cells == 0) if(self.ammo_rockets == 0) @@ -793,13 +808,6 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime, } else { - if(MUTATOR_CALLHOOK(FilterItem)) // error means we do not want the item - { - startitem_failed = TRUE; - remove(self); - return; - } - if(!have_pickup_item()) { startitem_failed = TRUE; @@ -807,11 +815,6 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime, return; } - if(self.model != "") - itemmodel = self.model; - if(self.item_pickupsound != "") - pickupsound = self.item_pickupsound; - self.reset = Item_Reset; // it's a level item if(self.spawnflags & 1) @@ -864,10 +867,10 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime, self.is_item = TRUE; } - weaponsInMap |= weaponid; + WEPSET_OR_AW(weaponsInMap, weaponid); - precache_model (itemmodel); - precache_sound (pickupsound); + precache_model (self.model); + precache_sound (self.item_pickupsound); precache_sound ("misc/itemrespawncountdown.wav"); if(!g_minstagib && itemid == IT_STRENGTH) @@ -884,18 +887,7 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime, self.bot_pickup = TRUE; self.bot_pickupevalfunc = pickupevalfunc; self.bot_pickupbasevalue = pickupbasevalue; - self.mdl = itemmodel; - self.item_pickupsound = pickupsound; - if(self.weapons) - self.weapon = WEP_FIRST + log2of(lowestbit(self.weapons)); - else - self.weapon = 0; - // let mappers override respawntime - if(!self.respawntime) // both set - { - self.respawntime = defaultrespawntime; - self.respawntimejitter = defaultrespawntimejitter; - } + self.mdl = self.model; self.netname = itemname; self.touch = Item_Touch; setmodel (self, self.mdl); // precision set below @@ -1005,8 +997,23 @@ void weapon_defaultspawnfunc(float wpn) if(self.classname != "droppedweapon" && self.classname != "replacedweapon") { e = get_weaponinfo(wpn); - s = cvar_string(strcat("g_weaponreplace_", e.netname)); - if(s == "0") + + if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED) + { + print("Attempted to spawn a mutator-blocked weapon; these guns will in the future require a mutator\n"); + /* + objerror("Attempted to spawn a mutator-blocked weapon rejected"); + startitem_failed = TRUE; + return; + */ + } + + s = W_Apply_Weaponreplace(e.netname); + ret_string = s; + other = e; + MUTATOR_CALLHOOK(SetWeaponreplace); + s = ret_string; + if(s == "") { remove(self); startitem_failed = TRUE; @@ -1039,7 +1046,7 @@ void weapon_defaultspawnfunc(float wpn) } self = oldself; } - if(t >= 1) + if(t >= 1) // always the case! { s = argv(0); wpn = 0; @@ -1069,7 +1076,7 @@ void weapon_defaultspawnfunc(float wpn) if(!self.respawntime) { - if(e.weapons & WEPBIT_SUPERWEAPONS) + if(WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS)) { self.respawntime = g_pickup_respawntime_superweapon; self.respawntimejitter = g_pickup_respawntimejitter_superweapon; @@ -1081,7 +1088,7 @@ void weapon_defaultspawnfunc(float wpn) } } - if(e.weapons & WEPBIT_SUPERWEAPONS) + if(WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS)) if(!self.superweapons_finished) self.superweapons_finished = autocvar_g_balance_superweapons_time; @@ -1105,7 +1112,7 @@ void weapon_defaultspawnfunc(float wpn) f = FL_WEAPON; // no weapon-stay on superweapons - if(e.weapons & WEPBIT_SUPERWEAPONS) + if(WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS)) f |= FL_NO_WEAPON_STAY; // weapon stay isn't supported for teamed weapons @@ -1117,7 +1124,7 @@ void weapon_defaultspawnfunc(float wpn) if(self.ammo_cells) self.ammo_cells = autocvar_g_minstagib_ammo_drop; - StartItem(e.model, "weapons/weaponpickup.wav", self.respawntime, self.respawntimejitter, e.message, 0, e.weapons, f, weapon_pickupevalfunc, e.bot_pickupbasevalue); + StartItem(e.model, "weapons/weaponpickup.wav", self.respawntime, self.respawntimejitter, e.message, 0, e.weapon, f, weapon_pickupevalfunc, e.bot_pickupbasevalue); if (self.modelindex) // don't precache if self was removed weapon_action(e.weapon, WR_PRECACHE); } @@ -1425,7 +1432,7 @@ void spawnfunc_target_items (void) e = get_weaponinfo(j); if(argv(i) == e.netname) { - self.weapons |= e.weapons; + WEPSET_OR_EW(self, j); if(self.spawnflags == 0 || self.spawnflags == 2) weapon_action(e.weapon, WR_PRECACHE); break; @@ -1477,8 +1484,8 @@ void spawnfunc_target_items (void) for(j = WEP_FIRST; j <= WEP_LAST; ++j) { e = get_weaponinfo(j); - if(e.weapons) - self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.weapons & e.weapons), e.netname); + if(e.weapon) + self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, WEPSET_CONTAINS_EW(self, j), e.netname); } } self.netname = strzone(self.netname); @@ -1539,6 +1546,36 @@ void spawnfunc_item_jetpack(void) #define OP_PLUS 3 #define OP_MINUS 4 +float GiveWeapon(entity e, float wpn, float op, float val) +{ + float v0, v1; + v0 = WEPSET_CONTAINS_EW(e, wpn); + switch(op) + { + case OP_SET: + if(val > 0) + WEPSET_OR_EW(e, wpn); + else + WEPSET_ANDNOT_EW(e, wpn); + break; + case OP_MIN: + case OP_PLUS: + if(val > 0) + WEPSET_OR_EW(e, wpn); + break; + case OP_MAX: + if(val <= 0) + WEPSET_ANDNOT_EW(e, wpn); + break; + case OP_MINUS: + if(val > 0) + WEPSET_ANDNOT_EW(e, wpn); + break; + } + v1 = WEPSET_CONTAINS_EW(e, wpn); + return (v0 != v1); +} + float GiveBit(entity e, .float fld, float bit, float op, float val) { float v0, v1; @@ -1619,7 +1656,9 @@ void GiveRot(entity e, float v0, float v1, .float rotfield, float rottime, .floa e.regenfield = max(e.regenfield, time + regentime); } +#define PREGIVE_WEAPONS(e) WEPSET_DECLARE_A(save_weapons); WEPSET_COPY_AE(save_weapons, e) #define PREGIVE(e,f) float save_##f; save_##f = (e).f +#define POSTGIVE_WEAPON(e,b,snd_incr,snd_decr) GiveSound((e), WEPSET_CONTAINS_AW(save_weapons, b), WEPSET_CONTAINS_EW(e, b), 0, snd_incr, snd_decr) #define POSTGIVE_BIT(e,f,b,snd_incr,snd_decr) GiveSound((e), save_##f & (b), (e).f & (b), 0, snd_incr, snd_decr) #define POSTGIVE_VALUE(e,f,t,snd_incr,snd_decr) GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr) #define POSTGIVE_VALUE_ROT(e,f,t,rotfield,rottime,regenfield,regentime,snd_incr,snd_decr) GiveRot((e), save_##f, (e).f, rotfield, rottime, regenfield, regentime); GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr) @@ -1646,7 +1685,7 @@ float GiveItems(entity e, float beginarg, float endarg) e.superweapons_finished = max(0, e.superweapons_finished - time); PREGIVE(e, items); - PREGIVE(e, weapons); + PREGIVE_WEAPONS(e); PREGIVE(e, strength_finished); PREGIVE(e, invincible_finished); PREGIVE(e, superweapons_finished); @@ -1699,8 +1738,9 @@ float GiveItems(entity e, float beginarg, float endarg) for(j = WEP_FIRST; j <= WEP_LAST; ++j) { wi = get_weaponinfo(j); - if(wi.weapons) - got += GiveBit(e, weapons, wi.weapons, op, val); + if(wi.weapon) + if not(wi.spawnflags & WEP_FLAG_MUTATORBLOCKED) + got += GiveWeapon(e, j, op, val); } case "allammo": got += GiveValue(e, ammo_cells, op, val); @@ -1761,7 +1801,7 @@ float GiveItems(entity e, float beginarg, float endarg) wi = get_weaponinfo(j); if(cmd == wi.netname) { - got += GiveBit(e, weapons, wi.weapons, op, val); + got += GiveWeapon(e, j, op, val); break; } } @@ -1780,11 +1820,11 @@ float GiveItems(entity e, float beginarg, float endarg) for(j = WEP_FIRST; j <= WEP_LAST; ++j) { wi = get_weaponinfo(j); - if(wi.weapons) + if(wi.weapon) { - POSTGIVE_BIT(e, weapons, wi.weapons, "weapons/weaponpickup.wav", string_null); - if not(save_weapons & wi.weapons) - if(e.weapons & wi.weapons) + POSTGIVE_WEAPON(e, j, "weapons/weaponpickup.wav", string_null); + if not(WEPSET_CONTAINS_AW(save_weapons, j)) + if(WEPSET_CONTAINS_EW(e, j)) weapon_action(wi.weapon, WR_PRECACHE); } } @@ -1799,7 +1839,7 @@ float GiveItems(entity e, float beginarg, float endarg) POSTGIVE_VALUE_ROT(e, health, 1, pauserothealth_finished, autocvar_g_balance_pause_health_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, "misc/megahealth.wav", string_null); if(e.superweapons_finished <= 0) - if(self.weapons & WEPBIT_SUPERWEAPONS) + if(WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS)) e.superweapons_finished = autocvar_g_balance_superweapons_time; if (g_minstagib) @@ -1821,7 +1861,7 @@ float GiveItems(entity e, float beginarg, float endarg) else e.superweapons_finished += time; - if not(e.weapons & W_WeaponBit(e.switchweapon)) + if not(WEPSET_CONTAINS_EW(e, e.switchweapon)) _switchweapon = TRUE; if(_switchweapon) W_SwitchWeapon_Force(e, w_getbestweapon(e)); diff --git a/qcsrc/server/t_quake3.qc b/qcsrc/server/t_quake3.qc index f415e1fd1..82b5f4457 100644 --- a/qcsrc/server/t_quake3.qc +++ b/qcsrc/server/t_quake3.qc @@ -22,9 +22,9 @@ void spawnfunc_ammo_lightning() { spawnfunc_item_cells(); } void spawnfunc_weapon_plasmagun() { spawnfunc_weapon_hagar(); } void spawnfunc_ammo_cells() { spawnfunc_item_rockets(); } -// Rail -> Rifle -void spawnfunc_weapon_railgun() { spawnfunc_weapon_rifle(); } -void spawnfunc_ammo_slugs() { spawnfunc_item_bullets(); } +// Rail -> Nex +void spawnfunc_weapon_railgun() { spawnfunc_weapon_nex(); } +void spawnfunc_ammo_slugs() { spawnfunc_item_cells(); } // BFG -> Crylink void spawnfunc_weapon_bfg() { spawnfunc_weapon_crylink(); } diff --git a/qcsrc/server/w_common.qc b/qcsrc/server/w_common.qc index fab3b41b2..3343fa7c3 100644 --- a/qcsrc/server/w_common.qc +++ b/qcsrc/server/w_common.qc @@ -6,7 +6,7 @@ void W_GiveWeapon (entity e, float wep, string name) if (!wep) return; - e.weapons = e.weapons | W_WeaponBit(wep); + WEPSET_OR_EW(e, wep); oldself = self; self = e; diff --git a/qcsrc/server/w_hlac.qc b/qcsrc/server/w_hlac.qc index 2eb2918ed..62be05f0d 100644 --- a/qcsrc/server/w_hlac.qc +++ b/qcsrc/server/w_hlac.qc @@ -1,5 +1,5 @@ #ifdef REGISTER_WEAPON -REGISTER_WEAPON(HLAC, w_hlac, IT_CELLS, 6, WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "hlac", "hlac", _("Heavy Laser Assault Cannon")) +REGISTER_WEAPON(HLAC, w_hlac, IT_CELLS, 6, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "hlac", "hlac", _("Heavy Laser Assault Cannon")) #else #ifdef SVQC diff --git a/qcsrc/server/w_minelayer.qc b/qcsrc/server/w_minelayer.qc index 3ec50da50..0e73ba717 100644 --- a/qcsrc/server/w_minelayer.qc +++ b/qcsrc/server/w_minelayer.qc @@ -1,5 +1,5 @@ #ifdef REGISTER_WEAPON -REGISTER_WEAPON(MINE_LAYER, w_minelayer, IT_ROCKETS, 4, WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "minelayer", "minelayer", _("Mine Layer")) +REGISTER_WEAPON(MINE_LAYER, w_minelayer, IT_ROCKETS, 4, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "minelayer", "minelayer", _("Mine Layer")) #else #ifdef SVQC void W_Mine_Think (void); @@ -325,8 +325,6 @@ void W_Mine_Attack (void) self.minelayer_mines = W_Mine_Count(self); } -void spawnfunc_weapon_minelayer (void); // defined in t_items.qc - float W_PlacedMines(float detonate) { entity mine; diff --git a/qcsrc/server/w_minstanex.qc b/qcsrc/server/w_minstanex.qc index d8dc33ec6..aa8507905 100644 --- a/qcsrc/server/w_minstanex.qc +++ b/qcsrc/server/w_minstanex.qc @@ -1,5 +1,5 @@ #ifdef REGISTER_WEAPON -REGISTER_WEAPON(MINSTANEX, w_minstanex, IT_CELLS, 7, WEP_FLAG_HIDDEN | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_FLAG_SUPERWEAPON | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "minstanex", "minstanex", _("MinstaNex")) +REGISTER_WEAPON(MINSTANEX, w_minstanex, IT_CELLS, 7, WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_FLAG_SUPERWEAPON | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "minstanex", "minstanex", _("MinstaNex")) #else #ifdef SVQC .float minstanex_lasthit; diff --git a/qcsrc/server/w_porto.qc b/qcsrc/server/w_porto.qc index c919c497e..1fb823da9 100644 --- a/qcsrc/server/w_porto.qc +++ b/qcsrc/server/w_porto.qc @@ -36,7 +36,7 @@ void W_Porto_Fail (float failhard) self.realowner.porto_current = world; - if(self.cnt < 0 && !failhard && self.realowner.playerid == self.playerid && self.realowner.deadflag == DEAD_NO && !(self.realowner.weapons & WEPBIT_PORTO)) + if(self.cnt < 0 && !failhard && self.realowner.playerid == self.playerid && self.realowner.deadflag == DEAD_NO && !WEPSET_CONTAINS_EW(self.realowner, WEP_PORTO)) { setsize (self, '-16 -16 0', '16 16 32'); setorigin(self, self.origin + trace_plane_normal); @@ -202,12 +202,6 @@ void W_Porto_Attack (float type) { entity gren; - if(type == -1) - { - if not(self.items & IT_UNLIMITED_SUPERWEAPONS) - self.weapons = self.weapons - (self.weapons & WEPBIT_PORTO); - } - W_SetupShot (self, FALSE, 4, "porto/fire.wav", CH_WEAPON_A, 0); // always shoot from the eye w_shotdir = v_forward; diff --git a/qcsrc/server/w_rifle.qc b/qcsrc/server/w_rifle.qc index 89cb37257..1c5f766d7 100644 --- a/qcsrc/server/w_rifle.qc +++ b/qcsrc/server/w_rifle.qc @@ -1,5 +1,5 @@ #ifdef REGISTER_WEAPON -REGISTER_WEAPON(RIFLE, w_rifle, IT_NAILS, 7, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "campingrifle", "rifle", _("Rifle")) +REGISTER_WEAPON(RIFLE, w_rifle, IT_NAILS, 7, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "campingrifle", "rifle", _("Rifle")) #else #ifdef SVQC diff --git a/qcsrc/server/w_seeker.qc b/qcsrc/server/w_seeker.qc index 7cf9f58d8..be58650dc 100644 --- a/qcsrc/server/w_seeker.qc +++ b/qcsrc/server/w_seeker.qc @@ -1,5 +1,5 @@ #ifdef REGISTER_WEAPON -REGISTER_WEAPON(SEEKER, w_seeker, IT_ROCKETS, 8, WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "seeker", "seeker", _("T.A.G. Seeker")) +REGISTER_WEAPON(SEEKER, w_seeker, IT_ROCKETS, 8, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "seeker", "seeker", _("T.A.G. Seeker")) #else #ifdef SVQC //.float proxytime; = autoswitch diff --git a/sound/weapons/weaponpickup_new_toys.ogg b/sound/weapons/weaponpickup_new_toys.ogg new file mode 100644 index 000000000..34660eef0 Binary files /dev/null and b/sound/weapons/weaponpickup_new_toys.ogg differ