]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'Lyberta/PlayerTemplates' into Lyberta/Survival
authorLyberta <lyberta@lyberta.net>
Sat, 25 Nov 2017 06:49:27 +0000 (09:49 +0300)
committerLyberta <lyberta@lyberta.net>
Sat, 25 Nov 2017 06:49:27 +0000 (09:49 +0300)
72 files changed:
defaultServer.cfg
mutators.cfg
physics.cfg
physicsCPMA.cfg
physicsFruit.cfg
physicsHavoc.cfg
physicsLeeStricklin-ModdedFruit.cfg
physicsLeeStricklin.cfg
physicsLeeStricklinOld.cfg
physicsLzd.cfg
physicsNexuiz10.cfg
physicsNexuiz11.cfg
physicsNexuiz151.cfg
physicsNexuiz151b.cfg
physicsNexuiz16rc1.cfg
physicsNexuiz20.cfg
physicsNexuiz25.cfg
physicsNexuiz26.cfg
physicsNoQWBunny-nexbased.cfg
physicsOverkill.cfg
physicsQ.cfg
physicsQ2.cfg
physicsQ2a.cfg
physicsQ3.cfg
physicsQBF.cfg
physicsQBFplus.cfg
physicsSamual.cfg
physicsWarsow.cfg
physicsWarsowClassicBunny.cfg
physicsWarsowDev.cfg
physicsX.cfg
physicsX010.cfg
physicsX07.cfg
physicsXDF.cfg
physicsXDFLight.cfg
qcsrc/client/hud/panel/physics.qc
qcsrc/common/items/item.qh
qcsrc/common/items/item/ammo.qh
qcsrc/common/items/item/armor.qh
qcsrc/common/items/item/health.qh
qcsrc/common/items/item/jetpack.qh
qcsrc/common/items/item/powerup.qh
qcsrc/common/mutators/mutator/_mod.inc
qcsrc/common/mutators/mutator/_mod.qh
qcsrc/common/mutators/mutator/dodging/sv_dodging.qc
qcsrc/common/mutators/mutator/instagib/items.qh
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/mutators/mutator/random_items/sv_random_items.qc
qcsrc/common/mutators/mutator/random_items/sv_random_items.qh
qcsrc/common/mutators/mutator/stale_move_negation/_mod.inc [new file with mode: 0644]
qcsrc/common/mutators/mutator/stale_move_negation/_mod.qh [new file with mode: 0644]
qcsrc/common/mutators/mutator/stale_move_negation/sv_stale_move_negation.qc [new file with mode: 0644]
qcsrc/common/mutators/mutator/stale_move_negation/sv_stale_move_negation.qh [new file with mode: 0644]
qcsrc/common/physics/player.qc
qcsrc/common/physics/player.qh
qcsrc/common/stats.qh
qcsrc/common/triggers/func/button.qc
qcsrc/common/triggers/func/button.qh
qcsrc/common/triggers/trigger/heal.qc
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc
qcsrc/server/autocvars.qh
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/items.qc
qcsrc/server/items.qh
qcsrc/server/mutators/mutator/gamemode_ca.qc
qcsrc/server/player.qc
qcsrc/server/teamplay.qc
randomitems-xonotic.cfg [new file with mode: 0644]

index 47037c069b62ca6aea1538be444c949192e3f721..99845f6480f256dd2eaf79057b48ce76997b5a5b 100644 (file)
@@ -77,6 +77,7 @@ set sv_jumpspeedcap_min "" "lower bound on the baseline velocity of a jump; fina
 set sv_jumpspeedcap_max "" "upper bound on the baseline velocity of a jump; final velocity will be <= (jumpheight * max + jumpheight)"
 set sv_jumpspeedcap_max_disable_on_ramps 0 "disable upper baseline velocity bound on ramps to preserve the old rampjump style"
 set sv_track_canjump 0 "track if the player released the jump key between 2 jumps to decide if they are able to jump or not"
+set sv_jumpvelocity_crouch 0 "jump height while crouching, set to 0 to use regular jump height"
 
 set sv_precacheplayermodels 1
 set sv_precacheweapons 0
index 7c4a0ff1a88e29b396cb8d15ffc87144a34e6b1a..e37c190902d4901aa02ee2e5abbd86188c6f4489 100644 (file)
@@ -12,17 +12,21 @@ seta cl_dodging_timeout 0.2 "determines how long apart (in seconds) two taps on
 
 set sv_dodging_air_dodging 0
 set sv_dodging_wall_dodging 0 "allow dodging off walls"
-set sv_dodging_delay 0.5 "determines how long a player has to wait to be able to dodge again after dodging"
+set sv_dodging_delay 0.6 "determines how long a player has to wait to be able to dodge again after dodging"
 set sv_dodging_up_speed 200 "the jump velocity of the dodge"
-set sv_dodging_horiz_speed 400 "the horizontal velocity of the dodge"
-set sv_dodging_horiz_speed_frozen 200 "the horizontal velocity of the dodge while frozen"
+set sv_dodging_horiz_speed_min 200 "the lower bound of current velocity for force scaling"
+set sv_dodging_horiz_speed_max 1000 "the upper bound of current velocity for force scaling"
+set sv_dodging_horiz_force_slowest 400 "the horizontal velocity of the dodge when current velocity is <= sv_dodging_horiz_speed_min, values between min and max are linearly scaled"
+set sv_dodging_horiz_force_fastest 400 "the horizontal velocity of the dodge when current velocity is >= sv_dodging_horiz_speed_max, values between min and max are linearly scaled"
+set sv_dodging_horiz_force_frozen 200 "the horizontal velocity of the dodge while frozen"
 set sv_dodging_ramp_time 0.1 "a ramp so that the horizontal part of the dodge is added smoothly (seconds)"
 set sv_dodging_height_threshold 10 "the maximum height above ground where to allow dodging"
 set sv_dodging_wall_distance_threshold 10 "the maximum distance from a wall that still allows dodging"
 set sv_dodging_sound 1 "if 1 dodging makes a sound. if 0 dodging is silent"
 set sv_dodging_frozen 0 "allow dodging while frozen"
 set sv_dodging_frozen_doubletap 0
-set sv_dodging_maxspeed 450 "maximum speed a player can be moving at before they dodge again"
+set sv_dodging_maxspeed 350 "maximum speed a player can be moving at to use the standard dodging from an (almost) standstill"
+set sv_dodging_air_maxspeed 450 "maximum speed a player can be moving at before they dodge again when air dodging is enabled"
 
 
 // ===========
@@ -476,164 +480,17 @@ set g_dynamic_handicap_exponent 1 "The exponent used to calculate handicap. 1 me
 set g_dynamic_handicap_min 0 "The minimum value of the handicap."
 set g_dynamic_handicap_max 0 "The maximum value of the handicap."
 
+// =====================
+//  stale-move negation
+// =====================
+set g_smneg 0 "Stale-move negation: penalize repeated use of the same weapon"
+set g_smneg_bonus 1 "Stale-move negation: allow weapons to become stronger than their baseline"
+set g_smneg_bonus_asymptote 4 "Stale-move negation: damage = infinity at this bonus level"
+set g_smneg_cooldown_factor 0.25 "Stale-move negation: penalty cooldown factor"
+
 // ==============
 //  random items
 // ==============
 set g_random_items 0 "Whether to enable random items."
-set g_random_items_replace_item_health_small "random" "Classnames to replace small health with."
-set g_random_items_replace_item_health_medium "random" "Classnames to replace medium health with."
-set g_random_items_replace_item_health_big "random" "Classnames to replace big health with."
-set g_random_items_replace_item_health_mega "random" "Classnames to replace mega health with."
-set g_random_items_replace_item_armor_small "random" "Classnames to replace small armor with."
-set g_random_items_replace_item_armor_medium "random" "Classnames to replace medium armor with."
-set g_random_items_replace_item_armor_big "random" "Classnames to replace big armor with."
-set g_random_items_replace_item_armor_mega "random" "Classnames to replace mega armor with."
-set g_random_items_replace_item_shells "random" "Classnames to replace shells with."
-set g_random_items_replace_item_bullets "random" "Classnames to replace bullets with."
-set g_random_items_replace_item_rockets "random" "Classnames to replace rockets with."
-set g_random_items_replace_item_cells "random" "Classnames to replace cells with."
-set g_random_items_replace_item_plasma "random" "Classnames to replace plasma with."
-set g_random_items_replace_item_fuel "random" "Classnames to replace fuel with."
-set g_random_items_replace_weapon_blaster "random" "Classnames to replace blaster with."
-set g_random_items_replace_weapon_shotgun "random" "Classnames to replace shotgun with."
-set g_random_items_replace_weapon_machinegun "random" "Classnames to replace machinegun with."
-set g_random_items_replace_weapon_mortar "random" "Classnames to replace mortar with."
-set g_random_items_replace_weapon_electro "random" "Classnames to replace electro with."
-set g_random_items_replace_weapon_crylink "random" "Classnames to replace crylink with."
-set g_random_items_replace_weapon_vortex "random" "Classnames to replace vortex with."
-set g_random_items_replace_weapon_hagar "random" "Classnames to replace hagar with."
-set g_random_items_replace_weapon_devastator "random" "Classnames to replace devastator with."
-set g_random_items_replace_weapon_shockwave "random" "Classnames to replace shockwave with."
-set g_random_items_replace_weapon_arc "random" "Classnames to replace arc with."
-set g_random_items_replace_weapon_hook "random" "Classnames to replace hook with."
-set g_random_items_replace_weapon_tuba "random" "Classnames to replace tuba with."
-set g_random_items_replace_weapon_porto "random" "Classnames to replace port-o-launch with."
-set g_random_items_replace_weapon_fireball "random" "Classnames to replace fireball with."
-set g_random_items_replace_weapon_minelayer "random" "Classnames to replace mine layer with."
-set g_random_items_replace_weapon_hlac "random" "Classnames to replace HLAC with."
-set g_random_items_replace_weapon_rifle "random" "Classnames to replace rifle with."
-set g_random_items_replace_weapon_seeker "random" "Classnames to replace TAG seeker with."
-set g_random_items_replace_weapon_vaporizer "random" "Classnames to replace vaporizer with."
-set g_random_items_replace_weapon_hmg "random" "Classnames to replace HMG with."
-set g_random_items_replace_weapon_rpc "random" "Classnames to replace RPC with."
-set g_random_items_replace_item_strength "random" "Classnames to replace strength with."
-set g_random_items_replace_item_shield "random" "Classnames to replace shield with."
-set g_random_items_replace_item_fuel_regen "random" "Classnames to replace fuel regeneration with."
-set g_random_items_replace_item_jetpack "random" "Classnames to replace jetpack with."
-set g_random_items_replace_item_vaporizer_cells "random" "Classnames to replace vaporizer cells with."
-set g_random_items_replace_item_invisibility "random" "Classnames to replace invisibility with."
-set g_random_items_replace_item_extralife "random" "Classnames to replace extra life with."
-set g_random_items_replace_item_speed "random" "Classnames to replace speed with."
-set g_random_items_health_probability 1 "Probability of random health items spawning in the map."
-set g_random_items_armor_probability 1 "Probability of random armor items spawning in the map."
-set g_random_items_resource_probability 1 "Probability of random resource items spawning in the map."
-set g_random_items_weapon_probability 1 "Probability of random weapons spawning in the map."
-set g_random_items_powerup_probability 0.15 "Probability of random powerups spawning in the map."
-set g_random_items_item_health_small_probability 10 "Probability of random small health spawning in the map."
-set g_random_items_item_health_medium_probability 4 "Probability of random medium health spawning in the map."
-set g_random_items_item_health_big_probability 2 "Probability of random big health spawning in the map."
-set g_random_items_item_health_mega_probability 1 "Probability of random mega health spawning in the map."
-set g_random_items_item_armor_small_probability 10 "Probability of random small armor spawning in the map."
-set g_random_items_item_armor_medium_probability 4 "Probability of random medium armor spawning in the map."
-set g_random_items_item_armor_big_probability 2 "Probability of random big armor spawning in the map."
-set g_random_items_item_armor_mega_probability 1 "Probability of random mega armor spawning in the map."
-set g_random_items_item_shells_probability 1 "Probability of random shells spawning in the map."
-set g_random_items_item_bullets_probability 1 "Probability of random bullets spawning in the map."
-set g_random_items_item_rockets_probability 1 "Probability of random rockets spawning in the map."
-set g_random_items_item_cells_probability 1 "Probability of random cells spawning in the map."
-set g_random_items_item_plasma_probability 0 "Probability of random plasma spawning in the map."
-set g_random_items_item_fuel_probability 0 "Probability of random fuel spawning in the map."
-set g_random_items_weapon_blaster_probability 0 "Probability of random blaster spawning in the map."
-set g_random_items_weapon_shotgun_probability 0 "Probability of random shotgun spawning in the map."
-set g_random_items_weapon_machinegun_probability 1 "Probability of random machinegun spawning in the map."
-set g_random_items_weapon_mortar_probability 1 "Probability of random mortar spawning in the map."
-set g_random_items_weapon_electro_probability 1 "Probability of random electro spawning in the map."
-set g_random_items_weapon_crylink_probability 1 "Probability of random crylink spawning in the map."
-set g_random_items_weapon_vortex_probability 1 "Probability of random vortex spawning in the map."
-set g_random_items_weapon_hagar_probability 1 "Probability of random hagar spawning in the map."
-set g_random_items_weapon_devastator_probability 1 "Probability of random devastator spawning in the map."
-set g_random_items_weapon_shockwave_probability 0 "Probability of random shockwave spawning in the map."
-set g_random_items_weapon_arc_probability 0 "Probability of random arc spawning in the map."
-set g_random_items_weapon_hook_probability 0 "Probability of random hook spawning in the map."
-set g_random_items_weapon_tuba_probability 0 "Probability of random tuba spawning in the map."
-set g_random_items_weapon_porto_probability 0 "Probability of random port-o-launch spawning in the map."
-set g_random_items_weapon_fireball_probability 0 "Probability of random fireball spawning in the map."
-set g_random_items_weapon_minelayer_probability 0 "Probability of random mine layer spawning in the map."
-set g_random_items_weapon_hlac_probability 0 "Probability of random HLAC spawning in the map."
-set g_random_items_weapon_rifle_probability 0 "Probability of random rifle spawning in the map."
-set g_random_items_weapon_seeker_probability 0 "Probability of random TAG seeker spawning in the map."
-set g_random_items_weapon_vaporizer_probability 0 "Probability of random vaporizer spawning in the map."
-set g_random_items_item_strength_probability 1 "Probability of random strength spawning in the map."
-set g_random_items_item_shield_probability 1 "Probability of random shield spawning in the map."
-set g_random_items_item_fuel_regen_probability 0 "Probability of random fuel regeneration spawning in the map."
-set g_random_items_item_jetpack_probability 0 "Probability of random jetpack spawning in the map."
-set g_random_items_item_vaporizer_cells_probability 20 "Probability of random vaporizer cells spawning in the map."
-set g_random_items_item_invisibility_probability 1 "Probability of random invisibility spawning in the map."
-set g_random_items_item_extralife_probability 1 "Probability of random extra life spawning in the map."
-set g_random_items_item_speed_probability 1 "Probability of random speed spawning in the map."
-set g_random_items_overkill_item_health_mega_probability 1 "Probability of random mega health spawning in the map during overkill."
-set g_random_items_overkill_item_armor_small_probability 10 "Probability of random small armor spawning in the map during overkill."
-set g_random_items_overkill_item_armor_medium_probability 4 "Probability of random medium armor spawning in the map during overkill."
-set g_random_items_overkill_item_armor_big_probability 2 "Probability of random big armor spawning in the map during overkill."
-set g_random_items_overkill_item_armor_mega_probability 1 "Probability of random mega armor spawning in the map during overkill."
-set g_random_items_overkill_weapon_hmg_probability 0.5 "Probability of random HMG spawning in the map during overkill."
-set g_random_items_overkill_weapon_rpc_probability 0.5 "Probability of random RPC spawning in the map during overkill."
 set g_random_loot 0 "Whether to enable random loot."
-set g_random_loot_min 0 "Minimum amount of loot items."
-set g_random_loot_max 4 "Maximum amount of loot items."
-set g_random_loot_time 10 "Amount of time the loot will stay in seconds."
-set g_random_loot_spread 200 "How far can loot be thrown."
-set g_random_loot_health_probability 1 "Probability of random health items spawning as loot."
-set g_random_loot_armor_probability 1 "Probability of random armor items spawning as loot."
-set g_random_loot_resource_probability 1 "Probability of random ammo items spawning as loot."
-set g_random_loot_weapon_probability 1 "Probability of random weapons spawning as loot."
-set g_random_loot_powerup_probability 0.2 "Probability of random powerups spawning as loot."
-set g_random_loot_item_health_small_probability 4 "Probability of random small health spawning as loot."
-set g_random_loot_item_health_medium_probability 3 "Probability of random medium health spawning as loot."
-set g_random_loot_item_health_big_probability 2 "Probability of random big health spawning as loot."
-set g_random_loot_item_health_mega_probability 1 "Probability of random mega health spawning as loot."
-set g_random_loot_item_armor_small_probability 4 "Probability of random small armor spawning as loot."
-set g_random_loot_item_armor_medium_probability 3 "Probability of random medium armor spawning as loot."
-set g_random_loot_item_armor_big_probability 2 "Probability of random big armor spawning as loot."
-set g_random_loot_item_armor_mega_probability 1 "Probability of random mega armor spawning as loot."
-set g_random_loot_item_shells_probability 1 "Probability of random shells spawning as loot."
-set g_random_loot_item_bullets_probability 1 "Probability of random bullets spawning as loot."
-set g_random_loot_item_rockets_probability 1 "Probability of random rockets spawning as loot."
-set g_random_loot_item_cells_probability 1 "Probability of random cells spawning as loot."
-set g_random_loot_item_plasma_probability 0 "Probability of random plasma spawning as loot."
-set g_random_loot_item_fuel_probability 0 "Probability of random fuel spawning as loot."
-set g_random_loot_weapon_blaster_probability 0 "Probability of random blaster spawning as loot."
-set g_random_loot_weapon_shotgun_probability 0 "Probability of random shotgun spawning as loot."
-set g_random_loot_weapon_machinegun_probability 1 "Probability of random machinegun spawning as loot."
-set g_random_loot_weapon_mortar_probability 1 "Probability of random mortar spawning as loot."
-set g_random_loot_weapon_electro_probability 1 "Probability of random electro spawning as loot."
-set g_random_loot_weapon_crylink_probability 1 "Probability of random crylink spawning as loot."
-set g_random_loot_weapon_vortex_probability 1 "Probability of random vortex spawning as loot."
-set g_random_loot_weapon_hagar_probability 1 "Probability of random hagar spawning as loot."
-set g_random_loot_weapon_devastator_probability 1 "Probability of random devastator spawning as loot."
-set g_random_loot_weapon_shockwave_probability 0 "Probability of random shockwave spawning as loot."
-set g_random_loot_weapon_arc_probability 0 "Probability of random arc spawning as loot."
-set g_random_loot_weapon_hook_probability 0 "Probability of random hook spawning as loot."
-set g_random_loot_weapon_tuba_probability 0 "Probability of random tuba spawning as loot."
-set g_random_loot_weapon_porto_probability 0 "Probability of random port-o-launch spawning as loot."
-set g_random_loot_weapon_fireball_probability 0 "Probability of random fireball spawning as loot."
-set g_random_loot_weapon_minelayer_probability 0 "Probability of random mine layer spawning as loot."
-set g_random_loot_weapon_hlac_probability 0 "Probability of random HLAC spawning as loot."
-set g_random_loot_weapon_rifle_probability 0 "Probability of random rifle spawning as loot."
-set g_random_loot_weapon_seeker_probability 0 "Probability of random TAG seeker spawning as loot."
-set g_random_loot_weapon_vaporizer_probability 0 "Probability of random vaporizer spawning as loot."
-set g_random_loot_item_strength_probability 1 "Probability of random strength spawning as loot."
-set g_random_loot_item_shield_probability 1 "Probability of random shield spawning as loot."
-set g_random_loot_item_fuel_regen_probability 0 "Probability of random fuel regeneration spawning as loot."
-set g_random_loot_item_jetpack_probability 0 "Probability of random jetpack spawning as loot."
-set g_random_loot_item_vaporizer_cells_probability 20 "Probability of random vaporizer cells spawning as loot."
-set g_random_loot_item_invisibility_probability 1 "Probability of random invisibility spawning as loot."
-set g_random_loot_item_extralife_probability 1 "Probability of random extra life spawning as loot."
-set g_random_loot_item_speed_probability 1 "Probability of random speed spawning as loot."
-set g_random_loot_overkill_item_health_mega_probability 1 "Probability of random mega health spawning as loot during overkill."
-set g_random_loot_overkill_item_armor_small_probability 10 "Probability of random small armor spawning as loot during overkill."
-set g_random_loot_overkill_item_armor_medium_probability 4 "Probability of random medium armor spawning as loot during overkill."
-set g_random_loot_overkill_item_armor_big_probability 2 "Probability of random big armor spawning as loot during overkill."
-set g_random_loot_overkill_item_armor_mega_probability 1 "Probability of random mega armor spawning as loot during overkill."
-set g_random_loot_overkill_weapon_hmg_probability 1 "Probability of random HMG spawning as loot during overkill."
-set g_random_loot_overkill_weapon_rpc_probability 1 "Probability of random RPC spawning as loot during overkill."
+exec randomitems-xonotic.cfg
index 88742ff0b89943675ba5347037376d6fe96325a6..b74f68b3db4d1c3c341c70216e80765f7c28f8cc 100644 (file)
@@ -18,6 +18,7 @@ set g_physics_xonotic_airstrafeaccel_qw -0.95
 set g_physics_xonotic_airspeedlimit_nonqw 900
 set g_physics_xonotic_maxspeed 360
 set g_physics_xonotic_jumpvelocity 260
+set g_physics_xonotic_jumpvelocity_crouch 0
 set g_physics_xonotic_maxairstrafespeed 100
 set g_physics_xonotic_maxairspeed 360
 set g_physics_xonotic_airstrafeaccelerate 18
@@ -48,6 +49,7 @@ set g_physics_nexuiz_airstrafeaccel_qw 0
 set g_physics_nexuiz_airspeedlimit_nonqw 0
 set g_physics_nexuiz_maxspeed 400
 set g_physics_nexuiz_jumpvelocity 300 "333 to match xonotic physics"
+set g_physics_nexuiz_jumpvelocity_crouch 0 "333 to match xonotic physics"
 set g_physics_nexuiz_maxairstrafespeed 0
 set g_physics_nexuiz_maxairspeed 220
 set g_physics_nexuiz_airstrafeaccelerate 0
@@ -78,6 +80,7 @@ set g_physics_quake_airstrafeaccel_qw 0
 set g_physics_quake_airspeedlimit_nonqw 0
 set g_physics_quake_maxspeed 320
 set g_physics_quake_jumpvelocity 270
+set g_physics_quake_jumpvelocity_crouch 0
 set g_physics_quake_maxairstrafespeed 0
 set g_physics_quake_maxairspeed 30
 set g_physics_quake_airstrafeaccelerate 0
@@ -108,6 +111,7 @@ set g_physics_warsow_airstrafeaccel_qw 0
 set g_physics_warsow_airspeedlimit_nonqw 0
 set g_physics_warsow_maxspeed 320
 set g_physics_warsow_jumpvelocity 280
+set g_physics_warsow_jumpvelocity_crouch 0
 set g_physics_warsow_maxairstrafespeed 30
 set g_physics_warsow_maxairspeed 320
 set g_physics_warsow_airstrafeaccelerate 70
@@ -138,6 +142,7 @@ set g_physics_defrag_airstrafeaccel_qw 1
 set g_physics_defrag_airspeedlimit_nonqw 0
 set g_physics_defrag_maxspeed 320
 set g_physics_defrag_jumpvelocity 270
+set g_physics_defrag_jumpvelocity_crouch 0
 set g_physics_defrag_maxairstrafespeed 30
 set g_physics_defrag_maxairspeed 320
 set g_physics_defrag_airstrafeaccelerate 70
@@ -168,6 +173,7 @@ set g_physics_quake3_airstrafeaccel_qw 0
 set g_physics_quake3_airspeedlimit_nonqw 0
 set g_physics_quake3_maxspeed 320
 set g_physics_quake3_jumpvelocity 270
+set g_physics_quake3_jumpvelocity_crouch 0
 set g_physics_quake3_maxairstrafespeed 0
 set g_physics_quake3_maxairspeed 320
 set g_physics_quake3_airstrafeaccelerate 0
@@ -198,6 +204,7 @@ set g_physics_vecxis_airstrafeaccel_qw 0
 set g_physics_vecxis_airspeedlimit_nonqw 0
 set g_physics_vecxis_maxspeed 400
 set g_physics_vecxis_jumpvelocity 300 "333 to match xonotic physics"
+set g_physics_vecxis_jumpvelocity_crouch 0 "333 to match xonotic physics"
 set g_physics_vecxis_maxairstrafespeed 0
 set g_physics_vecxis_maxairspeed 220
 set g_physics_vecxis_airstrafeaccelerate 0
@@ -228,6 +235,7 @@ set g_physics_quake2_airstrafeaccel_qw 0
 set g_physics_quake2_airspeedlimit_nonqw 0
 set g_physics_quake2_maxspeed 300
 set g_physics_quake2_jumpvelocity 270
+set g_physics_quake2_jumpvelocity_crouch 0
 set g_physics_quake2_maxairstrafespeed 0
 set g_physics_quake2_maxairspeed 300
 set g_physics_quake2_airstrafeaccelerate 0
@@ -258,6 +266,7 @@ set g_physics_bones_airstrafeaccel_qw 1
 set g_physics_bones_airspeedlimit_nonqw 0
 set g_physics_bones_maxspeed 320
 set g_physics_bones_jumpvelocity 270
+set g_physics_bones_jumpvelocity_crouch 0
 set g_physics_bones_maxairstrafespeed 30
 set g_physics_bones_maxairspeed 320
 set g_physics_bones_airstrafeaccelerate 70
@@ -288,6 +297,7 @@ set g_physics_overkill_airstrafeaccel_qw -0.95
 set g_physics_overkill_airspeedlimit_nonqw 900
 set g_physics_overkill_maxspeed 400
 set g_physics_overkill_jumpvelocity 260
+set g_physics_overkill_jumpvelocity_crouch 0
 set g_physics_overkill_maxairstrafespeed 100
 set g_physics_overkill_maxairspeed 360
 set g_physics_overkill_airstrafeaccelerate 24
index 612a779dac5fb69ad978febcc0a3cbdc9b7279aa..3c1614dcd3b1943061a3c35ca3489127fdb7f2e1 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 8
 edgefriction 1
 sv_stepheight 18
 sv_jumpvelocity 270
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate 4
 sv_waterfriction 1
 sv_airaccel_sideways_friction 0
index 8e0a7f0fe73f8084a776eac1274dd255a71a5f9c..8c034b8a9010faf99eab9bab51d2f1cd7a662bb5 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 8
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 270
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0 // breaks strafing?
index e5d431b3e7b6c7d3f5babb72291b6cd144a30361..f45a73f14ca2eb09447feb72868eb1abd3861b91 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 7
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0.65
index 81d54d2eede716dc852bde66054b6063b5130bf3..b2c35d086b6cd2241877cf61c879659f35e0a098 100644 (file)
@@ -18,6 +18,7 @@ sv_stepheight 26
 // actually, what we want is 266.6666 for 180bpm
 // but 260 takes same amount of frames and is nicer to mappers
 sv_jumpvelocity 260
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0 // breaks strafing?
index 741224b1195736d1f0b1bcb35499eb8cdadbda0f..f529ed66dcc993101481bcca323b95948dc40d12 100644 (file)
@@ -18,6 +18,7 @@ sv_stepheight 26
 // actually, what we want is 266.6666 for 180bpm
 // but 260 takes same amount of frames and is nicer to mappers
 sv_jumpvelocity 260
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index 83689d1614e26474644270f2ecfd3ebbc5d28c55..522c30197186f99c6fa06c6d3164f93e87ec3382 100644 (file)
@@ -13,6 +13,7 @@ sv_friction 9.6 // higher values make you slide less
 edgefriction 1 // div0 says no! lol
 sv_stepheight 26
 sv_jumpvelocity 304
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0 // pain in the ass to tweak without screwing up the strafing
index de271c2987b5e75cce1b3b3293c1d8fdc8fef502..0c32adb2ef49436e331559d07bfb793b5a747c43 100644 (file)
@@ -12,6 +12,7 @@ sv_friction 5
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 310
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0.35
index 28d7c7f2cebce23ea74fe1a0e9b4d5d9ba875008..1f0b8bde150e79bab98a249c31669c6689a57af5 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 5
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index 7633e5a28878384f09a1418796937a91d0cdb979..51ef497e7fcdc61d47f6041898805bca772c743f 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 5
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index aaec2756f6bece0a7a24572766dd275b299cbddd..0dd5b0da2948dcbc8ebb9b32d97c6d80c2b21818 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 5
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index 3cd9df61ee398d349f77e55b87b43553f76c6b78..5b9b21bf6717c88494704ddc4000065130da157d 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 5
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index 17b8de8e4c0a88138d661683a27e63e6f685f74b..4bad86850de9b29cab187f76d94296855f8995e5 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 5
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index 168ec2d349a65ebdd3256e7fca7992a4255244b7..531952a36533c992e390871454a511b7cafb0a96 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 5
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0.3
index 6038e7b6af70ea7a654e9c2b5de3105db5a7bbb5..4de91d19a812122e2659726b1214597770626b38 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 7
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0.35
index cb088f9df067d3f0f8360c70941f58787057c707..151d360cb6179aac640729e144bfd9e1d9337406 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 7
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0.35
index 2b054788a1cf314fc17a257c3543c2acb15b500d..7acc35544a1c4211a6859383d45f37debfaa05a5 100644 (file)
@@ -19,6 +19,7 @@ sv_stepheight 26
 // actually, what we want is 266.6666 for 180bpm
 // but 260 takes same amount of frames and is nicer to mappers
 sv_jumpvelocity 260
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index 526f7e22226d4442519db20892e50c6e6ff5fb9c..a6f36a77e8320a7f8d4719a4f57987b88553cc91 100644 (file)
@@ -24,6 +24,7 @@ sv_stepheight 31
 // this is smaller than 112 qu, so a 112 qu high corridor (7 of 8 grid units in
 // the 16 grid, and the 8th unit used for wall/floor) just lets a player jump!
 sv_jumpvelocity 260
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index c880f511e4d678f7c958d047ef46062ed283da8e..4f880c90fc128acd897c7007fb9e60769c81ee31 100644 (file)
@@ -12,6 +12,7 @@ sv_friction 4
 edgefriction 1
 sv_stepheight 18
 sv_jumpvelocity 270
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index 992cb3e62b7740b9015fe88233b9953be0212d47..f45a81b7739fb4f55ed8dd63d5504b01c2a6a236 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 6
 edgefriction 1
 sv_stepheight 18
 sv_jumpvelocity 270
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction 1
 sv_airaccel_sideways_friction 0
index ce323269699ac3a5189d4ec5b399b4ffcb617d22..585262a2ed0080811a1be8d47ac7fa926de4c1b9 100644 (file)
@@ -12,6 +12,7 @@ sv_friction 6
 edgefriction 1
 sv_stepheight 18
 sv_jumpvelocity 270
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction 1
 sv_airaccel_sideways_friction 0
index a6d46ca820ba0022beda3220eaa9e860bac5244e..3ce18b52a98bef30d6c6f32da3ba0fa0a2a22f5d 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 6
 edgefriction 1
 sv_stepheight 18
 sv_jumpvelocity 270
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate 4
 sv_waterfriction 1
 sv_airaccel_sideways_friction 0
index 39b705637a312df7c3cbe1bf69da98c26a76aed0..6b210f55b92e61f893298fc23c2dffb35acd79b1 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 5
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0.8
index 2e092b1230cb00afc2feb3607d529091385dcdf6..e8772b3f3f48037726fb5cfe2397f8a4d8561cff 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 5
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0.5
index 8506e2255c5e54150ed95f66de075d9178402e85..4f22085f9a11d8c1829e2024b4f880f11ceb0347 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 4
 edgefriction 1
 sv_stepheight 34
 sv_jumpvelocity 300
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0.3
index 1bd23b647f636fca8aa9d759a133c69bffff0e08..de7352aab54e56de9803d38cdec59a0298038583 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 8
 edgefriction 1
 sv_stepheight 18
 sv_jumpvelocity 280
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate 10
 sv_waterfriction 1
 sv_airaccel_sideways_friction 0
index 985be7e95cf7a1fa82eec39bb8b67c0b6ea172e1..7705a4d512d70856f008aa0d2c1148d282581525 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 8
 edgefriction 1
 sv_stepheight 18
 sv_jumpvelocity 280
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate 10
 sv_waterfriction 1
 sv_airaccel_sideways_friction 0
index dff451087b10aacd24bb57504002da5d61a47717..9009beab33a14e949a7f0d575d67dc7673617387 100644 (file)
@@ -11,6 +11,7 @@ sv_friction 8
 edgefriction 1
 sv_stepheight 18
 sv_jumpvelocity 280
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate 10
 sv_waterfriction 1
 sv_airaccel_sideways_friction 0
index 6b154508ec63d798e0f2ba18eae78287e7f8f971..6076dd73d19702226a4fe2efe3a842c4582a843f 100644 (file)
@@ -25,6 +25,7 @@ sv_stepheight 31
 // this is smaller than 112 qu, so a 112 qu high corridor (7 of 8 grid units in
 // the 16 grid, and the 8th unit used for wall/floor) just lets a player jump!
 sv_jumpvelocity 260
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index 9c5a7d334a214804d0a84a0daf2a18e768e70be8..a5349c98fdfbd4212256335b808f8df22325e2c1 100644 (file)
@@ -18,6 +18,7 @@ sv_stepheight 26
 // actually, what we want is 266.6666 for 180bpm
 // but 260 takes same amount of frames and is nicer to mappers
 sv_jumpvelocity 260
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index 1fd86cd8000140b33d0af6001cd0b513ef26a794..8ae771f1cf468a9ac21ec05d4b94cdc4e2782708 100644 (file)
@@ -24,6 +24,7 @@ sv_stepheight 26
 // this is smaller than 112 qu, so a 112 qu high corridor (7 of 8 grid units in
 // the 16 grid, and the 8th unit used for wall/floor) just lets a player jump!
 sv_jumpvelocity 260
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate -1
 sv_waterfriction -1
 sv_airaccel_sideways_friction 0
index e192ab47627b613e10f21974d0c1cdac813dc956..e0bea6a0ea560a17c0c442a280c7293417b84505 100644 (file)
@@ -16,6 +16,7 @@ edgefriction 1
 sv_stepheight 26
 // CPMA: 18
 sv_jumpvelocity 270
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate 4
 sv_waterfriction 1
 sv_airaccel_sideways_friction 0
index 24705deb89a93b23e972c173ec33c476577906c0..f9bed43f6e65096b7edcfa4309e7e969237b2168 100644 (file)
@@ -16,6 +16,7 @@ edgefriction 1
 sv_stepheight 26
 // CPMA: 18
 sv_jumpvelocity 270
+sv_jumpvelocity_crouch 0
 sv_wateraccelerate 4
 sv_waterfriction 1
 sv_airaccel_sideways_friction 0
index e1fffb59f34e52684ee1ac0ec2191322e61e8c59..a6c65183d4541cc0cb23c1cdf133e594fc3c1e0c 100644 (file)
@@ -88,10 +88,10 @@ void HUD_Physics()
        const int acc_decimals = 2;
        if(time > physics_update_time)
        {
+               discrete_acceleration = acceleration;
                // workaround for ftos_decimals returning a negative 0
                if(discrete_acceleration > -1 / (10 ** acc_decimals) && discrete_acceleration < 0)
                        discrete_acceleration = 0;
-               discrete_acceleration = acceleration;
                discrete_speed = speed;
                physics_update_time += autocvar_hud_panel_physics_update_interval;
                if(physics_update_time < time)
index 6ec6dd8a4a843cf000b03d91b6d72fed1b94d63a..b7fc933e8b5dbaf35dde8a37fca1762c51a4e08a 100644 (file)
@@ -56,8 +56,12 @@ const int IT_PICKUPMASK                      = IT_UNLIMITED_AMMO | IT_JETPACK | IT_FU
 
 #endif
 
-enum {
-    ITEM_FLAG_MUTATORBLOCKED = BIT(0)
+enum
+{
+       ITEM_FLAG_NORMAL = BIT(0), ///< Item is usable during normal gameplay.
+       ITEM_FLAG_INSTAGIB = BIT(1), ///< Item is usable in instagib.
+       ITEM_FLAG_OVERKILL = BIT(2), ///< Item is usable in overkill.
+       ITEM_FLAG_MUTATORBLOCKED = BIT(3)
 };
 
 #define ITEM_HANDLE(signal, ...) __Item_Send_##signal(__VA_ARGS__)
index cc3cfe06419b39499374bb05bdc6747a6ee48a7f..1d5bd87baceb116b7e241f9955e4e12b8f6d3ee9 100644 (file)
@@ -51,6 +51,7 @@ ENDCLASS(Bullets)
 REGISTER_ITEM(Bullets, Bullets) {
     this.m_canonical_spawnfunc = "item_bullets";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model    =   MDL_Bullets_ITEM;
 #endif
     this.netname    =   "bullets";
@@ -80,6 +81,7 @@ void ammo_cells_init(entity item)
 REGISTER_ITEM(Cells, Ammo) {
     this.m_canonical_spawnfunc = "item_cells";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model    =   MDL_Cells_ITEM;
 #endif
     this.netname    =   "cells";
@@ -109,6 +111,7 @@ void ammo_plasma_init(entity item)
 REGISTER_ITEM(Plasma, Ammo) {
     this.m_canonical_spawnfunc = "item_plasma";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model    =   MDL_Plasma_ITEM;
 #endif
     this.netname    =   "plasma";
@@ -138,6 +141,7 @@ void ammo_rockets_init(entity item)
 REGISTER_ITEM(Rockets, Ammo) {
     this.m_canonical_spawnfunc = "item_rockets";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model    =   MDL_Rockets_ITEM;
 #endif
     this.netname    =   "rockets";
@@ -171,6 +175,7 @@ ENDCLASS(Shells)
 REGISTER_ITEM(Shells, Shells) {
     this.m_canonical_spawnfunc = "item_shells";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model    =   MDL_Shells_ITEM;
 #endif
     this.netname    =   "shells";
index 9a9326c43e1ae20a7a469ea2786ab5120fdf0195..7f37c75aec002465260b1852810253e05c6a4b11 100644 (file)
@@ -34,6 +34,7 @@ void item_armorsmall_init(entity item)
 REGISTER_ITEM(ArmorSmall, Armor) {
     this.m_canonical_spawnfunc = "item_armor_small";
 #ifdef GAMEQC
+    this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
     this.m_model                =   MDL_ArmorSmall_ITEM;
     this.m_sound                =   SND_ArmorSmall;
 #endif
@@ -71,6 +72,7 @@ void item_armormedium_init(entity item)
 REGISTER_ITEM(ArmorMedium, Armor) {
     this.m_canonical_spawnfunc = "item_armor_medium";
 #ifdef GAMEQC
+    this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
     this.m_model                =   MDL_ArmorMedium_ITEM;
     this.m_sound                =   SND_ArmorMedium;
 #endif
@@ -108,6 +110,7 @@ void item_armorbig_init(entity item)
 REGISTER_ITEM(ArmorBig, Armor) {
     this.m_canonical_spawnfunc = "item_armor_big";
 #ifdef GAMEQC
+    this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
     this.m_model                =   MDL_ArmorBig_ITEM;
     this.m_sound                =   SND_ArmorBig;
 #endif
@@ -147,6 +150,7 @@ void item_armormega_init(entity item)
 REGISTER_ITEM(ArmorMega, Armor) {
     this.m_canonical_spawnfunc = "item_armor_mega";
 #ifdef GAMEQC
+    this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
     this.m_model                =   MDL_ArmorMega_ITEM;
     this.m_sound                =   SND_ArmorMega;
 #endif
index 3ffb5728b1a1d86ea51b8ea93f53824ffb088b28..da431086e18587448cf697c8127390fd166134f0 100644 (file)
@@ -34,6 +34,7 @@ void item_healthsmall_init(entity item)
 REGISTER_ITEM(HealthSmall, Health) {
     this.m_canonical_spawnfunc = "item_health_small";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model                =   MDL_HealthSmall_ITEM;
     this.m_sound                =   SND_HealthSmall;
 #endif
@@ -71,6 +72,7 @@ void item_healthmedium_init(entity item)
 REGISTER_ITEM(HealthMedium, Health) {
     this.m_canonical_spawnfunc = "item_health_medium";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model                =   MDL_HealthMedium_ITEM;
     this.m_sound                =   SND_HealthMedium;
 #endif
@@ -108,6 +110,7 @@ void item_healthbig_init(entity item)
 REGISTER_ITEM(HealthBig, Health) {
     this.m_canonical_spawnfunc = "item_health_big";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model                =   MDL_HealthBig_ITEM;
     this.m_sound                =   SND_HealthBig;
 #endif
@@ -147,6 +150,7 @@ void item_healthmega_init(entity item)
 REGISTER_ITEM(HealthMega, Health) {
     this.m_canonical_spawnfunc = "item_health_mega";
 #ifdef GAMEQC
+    this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
     this.m_model                =   MDL_HealthMega_ITEM;
     this.m_sound                =   SND_HealthMega;
 #endif
index 389a11a29ce93b691be944b9b3eb58f5ee44777e..284bf3d390fce1c7b62653a9570b9ef20a7dffe5 100644 (file)
@@ -30,6 +30,7 @@ ENDCLASS(Jetpack)
 REGISTER_ITEM(Jetpack, Powerup) {
     this.m_canonical_spawnfunc = "item_jetpack";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model                =   MDL_Jetpack_ITEM;
     this.m_itemid               =   IT_JETPACK;
 #endif
@@ -63,6 +64,7 @@ void ammo_fuel_init(entity item)
 REGISTER_ITEM(JetpackFuel, Ammo) {
     this.m_canonical_spawnfunc = "item_fuel";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model    =   MDL_JetpackFuel_ITEM;
 #endif
     this.netname    =   "fuel";
@@ -87,6 +89,7 @@ ENDCLASS(JetpackRegen)
 REGISTER_ITEM(JetpackRegen, JetpackRegen) {
     this.m_canonical_spawnfunc = "item_fuel_regen";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model                =   MDL_JetpackRegen_ITEM;
 #endif
     this.netname                =   "fuel_regen";
index 787a7c94691898f2eb04566cc4b448159f72f218..fe47b63430ddd1726b774f080f56905a4dc7568c 100644 (file)
@@ -33,6 +33,7 @@ void powerup_strength_init(entity item)
 REGISTER_ITEM(Strength, Powerup) {
     this.m_canonical_spawnfunc = "item_strength";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model            =   MDL_Strength_ITEM;
     this.m_sound            =   SND_Strength;
     this.m_glow             =   true;
@@ -68,6 +69,7 @@ void powerup_shield_init(entity item)
 REGISTER_ITEM(Shield, Powerup) {
     this.m_canonical_spawnfunc = "item_shield";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_NORMAL;
     this.m_model            =   MDL_Shield_ITEM;
     this.m_sound            =   SND_Shield;
     this.m_glow             =   true;
index 59b2c117d2cb63e705726ce6e997c4e46b359775..d1a6acfc91c0988929456b8eecbf7abc1354f70f 100644 (file)
@@ -31,6 +31,7 @@
 #include <common/mutators/mutator/running_guns/_mod.inc>
 #include <common/mutators/mutator/sandbox/_mod.inc>
 #include <common/mutators/mutator/spawn_near_teammate/_mod.inc>
+#include <common/mutators/mutator/stale_move_negation/_mod.inc>
 #include <common/mutators/mutator/superspec/_mod.inc>
 #include <common/mutators/mutator/touchexplode/_mod.inc>
 #include <common/mutators/mutator/vampire/_mod.inc>
index b1c627fb6d76d3c48b75a31198a10fa7453c23cb..a865d1922d9b0844ec65a711006f1cc3bf6ae679 100644 (file)
@@ -31,6 +31,7 @@
 #include <common/mutators/mutator/running_guns/_mod.qh>
 #include <common/mutators/mutator/sandbox/_mod.qh>
 #include <common/mutators/mutator/spawn_near_teammate/_mod.qh>
+#include <common/mutators/mutator/stale_move_negation/_mod.qh>
 #include <common/mutators/mutator/superspec/_mod.qh>
 #include <common/mutators/mutator/touchexplode/_mod.qh>
 #include <common/mutators/mutator/vampire/_mod.qh>
index 70aac4d9a3fcda663448d035199f3d46b93dc1a0..6640cb8bf23a51a48c08cdd4662fbd89a4fcefcf 100644 (file)
@@ -1,32 +1,42 @@
 #include "sv_dodging.qh"
 
+// TODO the CSQC blocks in this sv_ file are currently not compiled but will be when dodging prediction gets enabled
+
 #define PHYS_DODGING                                           g_dodging
 #define PHYS_DODGING_DELAY                                     autocvar_sv_dodging_delay
 #define PHYS_DODGING_DISTANCE_THRESHOLD        autocvar_sv_dodging_wall_distance_threshold
-#define PHYS_DODGING_FROZEN_NODOUBLETAP                autocvar_sv_dodging_frozen_doubletap
+#define PHYS_DODGING_FROZEN_DOUBLETAP          autocvar_sv_dodging_frozen_doubletap
 #define PHYS_DODGING_HEIGHT_THRESHOLD          autocvar_sv_dodging_height_threshold
-#define PHYS_DODGING_HORIZ_SPEED                       autocvar_sv_dodging_horiz_speed
-#define PHYS_DODGING_HORIZ_SPEED_FROZEN        autocvar_sv_dodging_horiz_speed_frozen
+#define PHYS_DODGING_HORIZ_SPEED_MIN           autocvar_sv_dodging_horiz_speed_min
+#define PHYS_DODGING_HORIZ_SPEED_MAX           autocvar_sv_dodging_horiz_speed_max
+#define PHYS_DODGING_HORIZ_FORCE_SLOWEST       autocvar_sv_dodging_horiz_force_slowest
+#define PHYS_DODGING_HORIZ_FORCE_FASTEST       autocvar_sv_dodging_horiz_force_fastest
+#define PHYS_DODGING_HORIZ_FORCE_FROZEN        autocvar_sv_dodging_horiz_force_frozen
 #define PHYS_DODGING_RAMP_TIME                                 autocvar_sv_dodging_ramp_time
 #define PHYS_DODGING_UP_SPEED                          autocvar_sv_dodging_up_speed
 #define PHYS_DODGING_WALL                                      autocvar_sv_dodging_wall_dodging
 #define PHYS_DODGING_AIR                                       autocvar_sv_dodging_air_dodging
 #define PHYS_DODGING_MAXSPEED                          autocvar_sv_dodging_maxspeed
+#define PHYS_DODGING_AIR_MAXSPEED                      autocvar_sv_dodging_air_maxspeed
 
 // we ran out of stats slots! TODO: re-enable this when prediction is available for dodging
 #if 0
 #define PHYS_DODGING                                           STAT(DODGING, this)
 #define PHYS_DODGING_DELAY                                     STAT(DODGING_DELAY, this)
 #define PHYS_DODGING_DISTANCE_THRESHOLD        STAT(DODGING_DISTANCE_THRESHOLD, this)
-#define PHYS_DODGING_FROZEN_NODOUBLETAP                STAT(DODGING_FROZEN_NO_DOUBLETAP, this)
+#define PHYS_DODGING_FROZEN_DOUBLETAP          STAT(DODGING_FROZEN_DOUBLETAP, this)
 #define PHYS_DODGING_HEIGHT_THRESHOLD          STAT(DODGING_HEIGHT_THRESHOLD, this)
-#define PHYS_DODGING_HORIZ_SPEED                       STAT(DODGING_HORIZ_SPEED, this)
-#define PHYS_DODGING_HORIZ_SPEED_FROZEN        STAT(DODGING_HORIZ_SPEED_FROZEN, this)
+#define PHYS_DODGING_HORIZ_SPEED_MIN           STAT(DODGING_HORIZ_SPEED_MIN, this)
+#define PHYS_DODGING_HORIZ_SPEED_MAX           STAT(DODGING_HORIZ_SPEED_MAX, this)
+#define PHYS_DODGING_HORIZ_FORCE_SLOWEST       STAT(DODGING_HORIZ_FORCE_SLOWEST, this)
+#define PHYS_DODGING_HORIZ_FORCE_FASTEST       STAT(DODGING_HORIZ_FORCE_FASTEST, this)
+#define PHYS_DODGING_HORIZ_FORCE_FROZEN        STAT(DODGING_HORIZ_FORCE_FROZEN, this)
 #define PHYS_DODGING_RAMP_TIME                                 STAT(DODGING_RAMP_TIME, this)
 #define PHYS_DODGING_UP_SPEED                          STAT(DODGING_UP_SPEED, this)
 #define PHYS_DODGING_WALL                                      STAT(DODGING_WALL, this)
 #define PHYS_DODGING_AIR                                       STAT(DODGING_AIR, this)
 #define PHYS_DODGING_MAXSPEED                          STAT(DODGING_MAXSPEED, this)
+#define PHYS_DODGING_AIR_MAXSPEED                      STAT(DODGING_AIR_MAXSPEED, this)
 #endif
 
 #ifdef CSQC
 
 bool autocvar_sv_dodging_sound;
 
-// set to 1 to indicate dodging has started.. reset by physics hook after dodge has been done..
-.float dodging_action;
-
-// the jump part of the dodge cannot be ramped
-.float dodging_single_action;
-
 #include <common/animdecide.qh>
 #include <common/physics/player.qh>
 
@@ -81,7 +85,6 @@ REGISTER_MUTATOR(dodging, true);
 // the jump part of the dodge cannot be ramped
 .float dodging_single_action;
 
-
 // these are used to store the last key press time for each of the keys..
 .float last_FORWARD_KEY_time;
 .float last_BACKWARD_KEY_time;
@@ -95,123 +98,126 @@ REGISTER_MUTATOR(dodging, true);
 // and to ramp up the dodge acceleration in the physics hook.
 .float last_dodging_time;
 
-// This is the velocity gain to be added over the ramp time.
-// It will decrease from frame to frame during dodging_action = 1
-// until it's 0.
-.float dodging_velocity_gain;
+// the total speed that will be added over the ramp time
+.float dodging_force_total;
+// the part of total yet to be added
+.float dodging_force_remaining;
 
 #ifdef CSQC
 .int pressedkeys;
 #endif
 
-// returns true if the player is close to a wall
-bool check_close_to_wall(entity this, float threshold)
-{
-       if (PHYS_DODGING_WALL == 0) { return false; }
-
 #define X(dir) \
        tracebox(this.origin, this.mins, this.maxs, this.origin + threshold * dir, true, this); \
        if (trace_fraction < 1 && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) \
                return true;
 
+// returns true if the player is close to a wall
+bool is_close_to_wall(entity this, float threshold)
+{
        X(v_right);
        X(-v_right);
        X(v_forward);
        X(-v_forward);
-#undef X
 
        return false;
 }
 
-bool check_close_to_ground(entity this, float threshold)
+bool is_close_to_ground(entity this, float threshold)
 {
-       return IS_ONGROUND(this) ? true : false;
+       if (IS_ONGROUND(this)) return true;
+       X(-v_up); // necessary for dodging down a slope using doubletap (using `+dodge` works anyway)
+
+       return false;
+}
+
+#undef X
+
+float determine_force(entity player) {
+       if (PHYS_FROZEN(player)) return PHYS_DODGING_HORIZ_FORCE_FROZEN;
+
+       float horiz_vel = vlen(vec2(player.velocity));
+       return map_bound_ranges(horiz_vel,
+                               PHYS_DODGING_HORIZ_SPEED_MIN, PHYS_DODGING_HORIZ_SPEED_MAX,
+                               PHYS_DODGING_HORIZ_FORCE_SLOWEST, PHYS_DODGING_HORIZ_FORCE_FASTEST);
 }
 
 bool PM_dodging_checkpressedkeys(entity this)
 {
-       if(!PHYS_DODGING)
-               return false;
-
        bool frozen_dodging = (PHYS_FROZEN(this) && PHYS_DODGING_FROZEN(this));
-       bool frozen_no_doubletap = (frozen_dodging && !PHYS_DODGING_FROZEN_NODOUBLETAP);
+       bool frozen_no_doubletap = (frozen_dodging && !PHYS_DODGING_FROZEN_DOUBLETAP);
+
+       float tap_direction_x = 0;
+       float tap_direction_y = 0;
+       bool dodge_detected = false;
+       vector mymovement = PHYS_CS(this).movement;
 
-       // first check if the last dodge is far enough back in time so we can dodge again
+       #define X(COND,BTN,RESULT)                                                                                                                                                              \
+       if (mymovement_##COND) {                                                                                                                                                                \
+               /* is this a state change? */                                                                                                                                           \
+               if(!(PHYS_DODGING_PRESSED_KEYS(this) & KEY_##BTN) || frozen_no_doubletap) {                                                     \
+                       tap_direction_##RESULT;                                                                                                                                                 \
+                       if ((time - this.last_##BTN##_KEY_time) < PHYS_DODGING_TIMEOUT(this) || frozen_no_doubletap) {  \
+                               dodge_detected = true;                                                                                                                                          \
+                       } else if(PHYS_INPUT_BUTTON_DODGE(this)) {                                                                                                              \
+                               dodge_detected = true;                                                                                                                                          \
+                       }                                                                                                                                                                                               \
+                       this.last_##BTN##_KEY_time = time;                                                                                                                              \
+               }                                                                                                                                                                                                       \
+       }
+       X(x < 0, BACKWARD,      x--);
+       X(x > 0, FORWARD,       x++);
+       X(y < 0, LEFT,          y--);
+       X(y > 0, RIGHT,         y++);
+       #undef X
+
+       if (!dodge_detected) return false;
+
+       // this check has to be after checking keys:
+       // the first key press of the double tap is allowed to be before dodging delay,
+       // only the second has to be after, otherwise +dodge gives an advantage because typical repress time is 0.1 s
+       // or higher which means players using +dodge would be able to do it more often
        if ((time - this.last_dodging_time) < PHYS_DODGING_DELAY)
                return false;
 
        makevectors(this.angles);
 
-       bool wall_dodge = false;
+       bool can_dodge = (is_close_to_ground(this, PHYS_DODGING_HEIGHT_THRESHOLD) && (PHYS_DODGING_MAXSPEED == 0 || vdist(this.velocity, <, PHYS_DODGING_MAXSPEED)));
+       bool can_wall_dodge = (PHYS_DODGING_WALL && is_close_to_wall(this, PHYS_DODGING_DISTANCE_THRESHOLD));
+       bool can_air_dodge = (PHYS_DODGING_AIR && (PHYS_DODGING_AIR_MAXSPEED == 0 || vdist(this.velocity, <, PHYS_DODGING_AIR_MAXSPEED)));
+       if (!can_dodge && !can_wall_dodge && !can_air_dodge) return false;
 
-       if(!PHYS_DODGING_AIR)
-       if(!check_close_to_ground(this, PHYS_DODGING_HEIGHT_THRESHOLD))
-       {
-               wall_dodge = check_close_to_wall(this, PHYS_DODGING_DISTANCE_THRESHOLD);
-               if(!wall_dodge) // we're not on the ground, and wall dodging isn't allowed, end it!
-                       return true;
-       }
+       this.last_dodging_time = time;
 
-       if(!wall_dodge && PHYS_DODGING_MAXSPEED && vdist(this.velocity, >, PHYS_DODGING_MAXSPEED))
-               return false;
+       this.dodging_action = 1;
+       this.dodging_single_action = 1;
 
-       float tap_direction_x = 0;
-       float tap_direction_y = 0;
-       bool dodge_detected = false;
-       vector mymovement = PHYS_CS(this).movement;
+       this.dodging_force_total = determine_force(this);
+       this.dodging_force_remaining = this.dodging_force_total;
 
-       #define X(COND,BTN,RESULT)                                                                                                                      \
-       if (mymovement_##COND)                                                                                          \
-               /* is this a state change? */                                                                                                   \
-               if(!(PHYS_DODGING_PRESSED_KEYS(this) & KEY_##BTN) || frozen_no_doubletap) {             \
-                               tap_direction_##RESULT;                                                                                                 \
-                               if ((time - this.last_##BTN##_KEY_time) < PHYS_DODGING_TIMEOUT(this) || frozen_no_doubletap)    \
-                                       dodge_detected = true;                                                                                          \
-                               if(PHYS_INPUT_BUTTON_DODGE(this))                                                                               \
-                                       dodge_detected = true;                                                                                          \
-                               this.last_##BTN##_KEY_time = time;                                                                              \
-               }
-       X(x < 0, BACKWARD,      x--);
-       X(x > 0, FORWARD,       x++);
-       X(y < 0, LEFT,          y--);
-       X(y > 0, RIGHT,         y++);
-       #undef X
-
-       if (dodge_detected)
-       {
-               this.last_dodging_time = time;
-
-               this.dodging_action = 1;
-               this.dodging_single_action = 1;
+       this.dodging_direction.x = tap_direction_x;
+       this.dodging_direction.y = tap_direction_y;
 
-               this.dodging_velocity_gain = PHYS_DODGING_HORIZ_SPEED;
+       // normalize the dodging_direction vector.. (unlike UT99) XD
+       float length = sqrt(this.dodging_direction.x ** 2 + this.dodging_direction.y ** 2);
 
-               this.dodging_direction_x = tap_direction_x;
-               this.dodging_direction_y = tap_direction_y;
+       this.dodging_direction.x = this.dodging_direction.x / length;
+       this.dodging_direction.y = this.dodging_direction.y / length;
 
-               // normalize the dodging_direction vector.. (unlike UT99) XD
-               float length = this.dodging_direction_x * this.dodging_direction_x
-                                       + this.dodging_direction_y * this.dodging_direction_y;
-               length = sqrt(length);
-
-               this.dodging_direction_x = this.dodging_direction_x * 1.0 / length;
-               this.dodging_direction_y = this.dodging_direction_y * 1.0 / length;
-               return true;
-       }
-       return false;
+       return true;
 }
 
 void PM_dodging(entity this)
 {
-       if (!PHYS_DODGING)
-               return;
+       // can't use return value from PM_dodging_checkpressedkeys because they're called from different hooks
+       if (!this.dodging_action) return;
 
        // when swimming or dead, no dodging allowed..
        if (this.waterlevel >= WATERLEVEL_SWIMMING || IS_DEAD(this))
        {
                this.dodging_action = 0;
-               this.dodging_direction_x = 0;
-               this.dodging_direction_y = 0;
+               this.dodging_direction.x = 0;
+               this.dodging_direction.y = 0;
                return;
        }
 
@@ -221,31 +227,18 @@ void PM_dodging(entity this)
        else
                makevectors(this.angles);
 
+       // fraction of the force to apply each frame
        // if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code
        // will be called ramp_time/frametime times = 2 times. so, we need to
        // add 0.5 * the total speed each frame until the dodge action is done..
        float common_factor = PHYS_DODGING_FRAMETIME / PHYS_DODGING_RAMP_TIME;
+       // NOTE: depending on cl_netfps the client may (and probably will) send more input frames during each server frame
+       // but common_factor uses server frame rate so players with higher cl_netfps will ramp slightly faster
 
-       // if ramp time is smaller than frametime we get problems ;D
-       common_factor = min(common_factor, 1);
-
-       float horiz_speed = PHYS_FROZEN(this) ? PHYS_DODGING_HORIZ_SPEED_FROZEN : PHYS_DODGING_HORIZ_SPEED;
-       float new_velocity_gain = this.dodging_velocity_gain - (common_factor * horiz_speed);
-       new_velocity_gain = max(0, new_velocity_gain);
-
-       float velocity_difference = this.dodging_velocity_gain - new_velocity_gain;
-
-       // ramp up dodging speed by adding some velocity each frame.. TODO: do it! :D
-       if (this.dodging_action == 1)
-       {
-               //disable jump key during dodge accel phase
-               if(PHYS_CS(this).movement.z > 0) { PHYS_CS(this).movement_z = 0; }
-
-               this.velocity += ((this.dodging_direction_y * velocity_difference) * v_right)
-                                       + ((this.dodging_direction_x * velocity_difference) * v_forward);
-
-               this.dodging_velocity_gain = this.dodging_velocity_gain - velocity_difference;
-       }
+       float velocity_increase = min(common_factor * this.dodging_force_total, this.dodging_force_remaining);
+       this.dodging_force_remaining -= velocity_increase;
+       this.velocity += this.dodging_direction.x * velocity_increase * v_forward
+                      + this.dodging_direction.y * velocity_increase * v_right;
 
        // the up part of the dodge is a single shot action
        if (this.dodging_single_action == 1)
@@ -264,21 +257,18 @@ void PM_dodging(entity this)
                this.dodging_single_action = 0;
        }
 
-       // are we done with the dodging ramp yet?
-       if((this.dodging_action == 1) && ((time - this.last_dodging_time) > PHYS_DODGING_RAMP_TIME))
+       if(this.dodging_force_remaining <= 0)
        {
                // reset state so next dodge can be done correctly
                this.dodging_action = 0;
-               this.dodging_direction_x = 0;
-               this.dodging_direction_y = 0;
+               this.dodging_direction.x = 0;
+               this.dodging_direction.y = 0;
        }
 }
 
+#ifdef CSQC
 void PM_dodging_GetPressedKeys(entity this)
 {
-#ifdef CSQC
-       if(!PHYS_DODGING) { return; }
-
        PM_dodging_checkpressedkeys(this);
 
        int keys = this.pressedkeys;
@@ -292,15 +282,16 @@ void PM_dodging_GetPressedKeys(entity this)
        keys = BITSET(keys, KEY_ATCK,           PHYS_INPUT_BUTTON_ATCK(this));
        keys = BITSET(keys, KEY_ATCK2,          PHYS_INPUT_BUTTON_ATCK2(this));
        this.pressedkeys = keys;
-#endif
 }
+#endif
 
 MUTATOR_HOOKFUNCTION(dodging, PlayerPhysics)
 {
-    entity player = M_ARGV(0, entity);
+       entity player = M_ARGV(0, entity);
 
-       // print("dodging_PlayerPhysics\n");
+#ifdef CSQC
        PM_dodging_GetPressedKeys(player);
+#endif
        PM_dodging(player);
 }
 
@@ -308,13 +299,6 @@ MUTATOR_HOOKFUNCTION(dodging, PlayerPhysics)
 
 REPLICATE(cvar_cl_dodging_timeout, float, "cl_dodging_timeout");
 
-MUTATOR_HOOKFUNCTION(dodging, PlayerPreThink)
-{
-       entity player = M_ARGV(0, entity);
-
-       STAT(DODGING_TIMEOUT, player) = CS(player).cvar_cl_dodging_timeout;
-}
-
 MUTATOR_HOOKFUNCTION(dodging, GetPressedKeys)
 {
        entity player = M_ARGV(0, entity);
index 597fddc11e2fee1a4eb99a97aaf679dccb6fd975..ab6843ed53ea7e358ceed756771c0515d3f07e65 100644 (file)
@@ -24,8 +24,8 @@ void ammo_vaporizercells_init(entity item)
 #endif
 REGISTER_ITEM(VaporizerCells, Ammo) {
     this.m_canonical_spawnfunc = "item_vaporizer_cells";
-    this.spawnflags = ITEM_FLAG_MUTATORBLOCKED;
 #ifdef GAMEQC
+    this.spawnflags = ITEM_FLAG_INSTAGIB | ITEM_FLAG_MUTATORBLOCKED;
     this.m_model                =   MDL_VaporizerCells_ITEM;
     this.m_sound                =   SND_VaporizerCells;
 #endif
@@ -52,6 +52,7 @@ SOUND(ExtraLife, Item_Sound("megahealth"));
 REGISTER_ITEM(ExtraLife, Powerup) {
     this.m_canonical_spawnfunc = "item_extralife";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_INSTAGIB;
     this.m_model                =   MDL_ExtraLife_ITEM;
     this.m_sound                =   SND_ExtraLife;
 #endif
@@ -81,6 +82,7 @@ void powerup_invisibility_init(entity item);
 REGISTER_ITEM(Invisibility, Powerup) {
     this.m_canonical_spawnfunc = "item_invisibility";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_INSTAGIB;
     this.m_model            =   MDL_Invisibility_ITEM;
     this.m_sound            =   SND_Invisibility;
     this.m_glow             =   true;
@@ -115,6 +117,7 @@ void powerup_speed_init(entity item);
 REGISTER_ITEM(Speed, Powerup) {
     this.m_canonical_spawnfunc = "item_speed";
 #ifdef GAMEQC
+       this.spawnflags = ITEM_FLAG_INSTAGIB;
     this.m_model            =   MDL_Speed_ITEM;
     this.m_sound            =   SND_Speed;
     this.m_glow             =   true;
index 120fabe569198b59b83a46f462b5024edc1b1805..7462de81f2a03a37cccab8794fee8e884f6fec79 100644 (file)
@@ -17,6 +17,23 @@ REGISTER_MUTATOR(ok, expr_evaluate(autocvar_g_overkill) && !cvar("g_instagib") &
        {
                precache_all_playermodels("models/ok_player/*.dpm");
 
+               if (autocvar_g_overkill_filter_healthmega)
+               {
+                       ITEM_HealthMega.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+               }
+               if (autocvar_g_overkill_filter_armormedium)
+               {
+                       ITEM_ArmorMedium.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+               }
+               if (autocvar_g_overkill_filter_armorbig)
+               {
+                       ITEM_ArmorBig.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+               }
+               if (autocvar_g_overkill_filter_armormega)
+               {
+                       ITEM_ArmorMega.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+               }
+
                WEP_RPC.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
                WEP_HMG.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
 
@@ -27,6 +44,11 @@ REGISTER_MUTATOR(ok, expr_evaluate(autocvar_g_overkill) && !cvar("g_instagib") &
 
        MUTATOR_ONREMOVE
        {
+               ITEM_HealthMega.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+               ITEM_ArmorMedium.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+               ITEM_ArmorBig.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+               ITEM_ArmorMega.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+
                WEP_RPC.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
                WEP_HMG.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
        }
@@ -247,14 +269,6 @@ MUTATOR_HOOKFUNCTION(ok, FilterItem)
        if(item.ok_item)
                return false;
 
-       switch(item.itemdef)
-       {
-               case ITEM_HealthMega: return autocvar_g_overkill_filter_healthmega;
-               case ITEM_ArmorMedium: return autocvar_g_overkill_filter_armormedium;
-               case ITEM_ArmorBig: return autocvar_g_overkill_filter_armorbig;
-               case ITEM_ArmorMega: return autocvar_g_overkill_filter_armormega;
-       }
-
        return true;
 }
 
index 3330bfeddd8c02fee0210d99bbb8816a3378e646..47234be290531e7d8a4966e313ac0f2bdb1acde7 100644 (file)
@@ -25,17 +25,6 @@ enum
 
 // Map probability cvars
 
-/// \brief Probability of random health items spawning in the map.
-float autocvar_g_random_items_health_probability;
-/// \brief Probability of random armor items spawning in the map.
-float autocvar_g_random_items_armor_probability;
-/// \brief Probability of random resource items spawning in the map.
-float autocvar_g_random_items_resource_probability;
-/// \brief Probability of random weapons spawning in the map.
-float autocvar_g_random_items_weapon_probability;
-/// \brief Probability of random powerups spawning in the map.
-float autocvar_g_random_items_powerup_probability;
-
 /// \brief Probability of random %s spawning in the map.
 /// float autocvar_g_random_items_%s_probability;
 
@@ -53,19 +42,8 @@ float autocvar_g_random_loot_spread; ///< How far can loot be thrown.
 
 // Loot probability cvars
 
-/// \brief Probability of random health items spawning as loot.
-float autocvar_g_random_loot_health_probability;
-/// \brief Probability of random armor items spawning as loot.
-float autocvar_g_random_loot_armor_probability;
-/// \brief Probability of random resource items spawning as loot.
-float autocvar_g_random_loot_resource_probability;
-/// \brief Probability of random weapons spawning as loot.
-float autocvar_g_random_loot_weapon_probability;
-/// \brief Probability of random powerups spawning as loot.
-float autocvar_g_random_loot_powerup_probability;
-
 /// \brief Probability of random %s spawning as loot.
-/// float autocvar_g_random_loot_weapon_%s_probability;
+/// float autocvar_g_random_loot_%s_probability;
 
 /// \brief Probability of random %s spawning as loot during overkill.
 /// float autocvar_g_random_loot_overkill_%s_probability;
@@ -74,177 +52,94 @@ float autocvar_g_random_loot_powerup_probability;
 /// recursion.
 bool random_items_is_spawning = false;
 
-//========================= Free functions ====================================
+//====================== Forward declarations =================================
 
-string RandomItems_GetItemVarName(string class_name)
+/// \brief Returns a random classname of the item with specific property.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the item.
+string RandomItems_GetRandomItemClassNameWithProperty(string prefix,
+       .bool item_property);
+
+//=========================== Public API ======================================
+
+string RandomItems_GetRandomItemClassName(string prefix)
 {
-       if (startsWith(class_name, "weapon_"))
+       if (autocvar_g_instagib)
        {
-               FOREACH(Weapons, it.m_canonical_spawnfunc == class_name, {
-                       if (it.spawnflags & WEP_FLAG_MUTATORBLOCKED)
-                       {
-                               return "";
-                       }
-                       return class_name;
-               });
-       }
-       bool is_ok = expr_evaluate(autocvar_g_overkill);
-       switch (class_name)
-       {
-               #define X(classname) case #classname: return #classname
-               #define XCOND(classname, var, expr) case #classname: if (expr) return #var; else break
-               X(item_health_small);
-               X(item_health_medium);
-               X(item_health_big);
-               XCOND(item_health_mega, item_health_mega, !is_ok || !autocvar_g_overkill_filter_healthmega);
-
-               X(item_armor_small);
-               XCOND(item_armor_medium, item_armor_medium, !is_ok || !autocvar_g_overkill_filter_armormedium);
-               XCOND(item_armor_big, item_armor_big, !is_ok || !autocvar_g_overkill_filter_armorbig);
-               XCOND(item_armor_mega, item_armor_mega, !is_ok || !autocvar_g_overkill_filter_armormega);
-
-               X(item_shells);
-               X(item_bullets);
-               X(item_rockets);
-               X(item_cells);
-               X(item_plasma);
-               X(item_fuel);
-
-               X(item_strength);
-               X(item_shield);
-               X(item_fuel_regen);
-               X(item_jetpack);
-
-               X(item_vaporizer_cells);
-               X(item_invisibility);
-               X(item_extralife);
-               X(item_speed);
-
-               #undef X
-               #undef XCOND
+               return RandomItems_GetRandomInstagibItemClassName(prefix);
        }
-       return "";
-}
-
-/// \brief Returns list of classnames to replace a map item with.
-/// \param[in] item Item to inspect.
-/// \return List of classnames to replace a map item with.
-string RandomItems_GetItemReplacementClassNames(entity item)
-{
-       string class_name = RandomItems_GetItemVarName(item.classname);
-       if (class_name)
+       if (expr_evaluate(autocvar_g_overkill))
        {
-               return cvar_string(sprintf("g_random_items_replace_%s", class_name));
+               return RandomItems_GetRandomOverkillItemClassName(prefix);
        }
-       return "";
+       return RandomItems_GetRandomVanillaItemClassName(prefix);
 }
 
-/// \brief Returns a random classname of the instagib map item.
-/// \return Random classname of the instagib map item.
-string RandomItems_GetRandomInstagibMapItemClassName()
+string RandomItems_GetRandomVanillaItemClassName(string prefix)
 {
        RandomSelection_Init();
-       #define X(classname) \
-               RandomSelection_AddString( \
-                       classname, \
-                       cvar(sprintf("g_random_items_%s_probability", RandomItems_GetItemVarName(classname))), \
-                       1 \
-               )
-       X("item_vaporizer_cells");
-       X("item_invisibility");
-       X("item_extralife");
-       X("item_speed");
-       #undef X
-       return RandomSelection_chosen_string;
-}
-
-/// \brief Returns a random classname of the overkill map item.
-/// \return Random classname of the overkill map item.
-string RandomItems_GetRandomOverkillMapItemClassName()
-{
-       RandomSelection_Init();
-       string varname;
-       #define X(classname) MACRO_BEGIN \
-               if ((varname = RandomItems_GetItemVarName(classname))) \
-               { \
-                       RandomSelection_AddString( \
-                               classname, \
-                               cvar(sprintf("g_random_items_overkill_%s_probability", varname)), \
-                               1 \
-                       ); \
-               } \
-       MACRO_END
-       X("item_health_mega");
-       X("item_armor_small");
-       X("item_armor_medium");
-       X("item_armor_big");
-       X("item_armor_mega");
-       X("weapon_hmg");
-       X("weapon_rpc");
-       #undef X
-       return RandomSelection_chosen_string;
-}
-
-/// \brief Returns a random classname of the map item.
-/// \return Random classname of the map item.
-string RandomItems_GetRandomMapItemClassName()
-{
-       if (autocvar_g_instagib)
+       string cvar_name = sprintf("g_%s_health_probability", prefix);
+       if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
        {
-               return RandomItems_GetRandomInstagibMapItemClassName();
+               LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
        }
-       if (expr_evaluate(autocvar_g_overkill))
+       else
        {
-               return RandomItems_GetRandomOverkillMapItemClassName();
+               RandomSelection_AddFloat(RANDOM_ITEM_TYPE_HEALTH, cvar(cvar_name), 1);
+       }
+       cvar_name = sprintf("g_%s_armor_probability", prefix);
+       if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+       {
+               LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+       }
+       else
+       {
+               RandomSelection_AddFloat(RANDOM_ITEM_TYPE_ARMOR, cvar(cvar_name), 1);
+       }
+       cvar_name = sprintf("g_%s_resource_probability", prefix);
+       if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+       {
+               LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+       }
+       else
+       {
+               RandomSelection_AddFloat(RANDOM_ITEM_TYPE_RESOURCE, cvar(cvar_name), 1);
+       }
+       cvar_name = sprintf("g_%s_weapon_probability", prefix);
+       if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+       {
+               LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+       }
+       else
+       {
+               RandomSelection_AddFloat(RANDOM_ITEM_TYPE_WEAPON, cvar(cvar_name), 1);
+       }
+       cvar_name = sprintf("g_%s_powerup_probability", prefix);
+       if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+       {
+               LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+       }
+       else
+       {
+               RandomSelection_AddFloat(RANDOM_ITEM_TYPE_POWERUP, cvar(cvar_name), 1);
        }
-       RandomSelection_Init();
-       #define X(type, name) \
-               RandomSelection_AddFloat( \
-                       RANDOM_ITEM_TYPE_##type, \
-                       autocvar_g_random_items_##name##_probability, \
-                       1 \
-               )
-       X(HEALTH, health);
-       X(ARMOR, armor);
-       X(RESOURCE, resource);
-       X(WEAPON, weapon);
-       X(POWERUP, powerup);
-       #undef X
        int item_type = RandomSelection_chosen_float;
        switch (item_type)
        {
                case RANDOM_ITEM_TYPE_HEALTH:
                {
-                       RandomSelection_Init();
-                       FOREACH(Items, it.instanceOfHealth,
-                       {
-                               RandomSelection_AddString(it.m_canonical_spawnfunc,
-                                       cvar(sprintf("g_random_items_%s_probability",
-                                       it.m_canonical_spawnfunc)), 1);
-                       });
-                       return RandomSelection_chosen_string;
+                       return RandomItems_GetRandomItemClassNameWithProperty(prefix,
+                               instanceOfHealth);
                }
                case RANDOM_ITEM_TYPE_ARMOR:
                {
-                       RandomSelection_Init();
-                       FOREACH(Items, it.instanceOfArmor,
-                       {
-                               RandomSelection_AddString(it.m_canonical_spawnfunc,
-                                       cvar(sprintf("g_random_items_%s_probability",
-                                       it.m_canonical_spawnfunc)), 1);
-                       });
-                       return RandomSelection_chosen_string;
+                       return RandomItems_GetRandomItemClassNameWithProperty(prefix,
+                               instanceOfArmor);
                }
                case RANDOM_ITEM_TYPE_RESOURCE:
                {
-                       RandomSelection_Init();
-                       FOREACH(Items, it.instanceOfAmmo,
-                       {
-                               RandomSelection_AddString(it.m_canonical_spawnfunc,
-                                       cvar(sprintf("g_random_items_%s_probability",
-                                       it.m_canonical_spawnfunc)), 1);
-                       });
-                       return RandomSelection_chosen_string;
+                       return RandomItems_GetRandomItemClassNameWithProperty(prefix,
+                               instanceOfAmmo);
                }
                case RANDOM_ITEM_TYPE_WEAPON:
                {
@@ -252,8 +147,14 @@ string RandomItems_GetRandomMapItemClassName()
                        FOREACH(Weapons, it != WEP_Null &&
                                !(it.spawnflags & WEP_FLAG_MUTATORBLOCKED),
                        {
-                               string cvar_name = sprintf("g_random_items_%s_probability",
+                               cvar_name = sprintf("g_%s_%s_probability", prefix,
                                        it.m_canonical_spawnfunc);
+                               if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+                               {
+                                       LOG_WARNF("Random items: cvar %s doesn't exist.",
+                                               cvar_name);
+                                       continue;
+                               }
                                RandomSelection_AddString(it.m_canonical_spawnfunc,
                                        cvar(cvar_name), 1);
                        });
@@ -261,24 +162,100 @@ string RandomItems_GetRandomMapItemClassName()
                }
                case RANDOM_ITEM_TYPE_POWERUP:
                {
-                       RandomSelection_Init();
-                       #define X(classname) \
-                               RandomSelection_AddString( \
-                                       classname, \
-                                       cvar(sprintf("g_random_items_%s_probability", classname)), \
-                                       1 \
-                               )
-                       X("item_strength");
-                       X("item_shield");
-                       X("item_fuel_regen");
-                       X("item_jetpack");
-                       #undef X
-                       return RandomSelection_chosen_string;
+                       return RandomItems_GetRandomItemClassNameWithProperty(prefix,
+                               instanceOfPowerup);
                }
        }
        return "";
 }
 
+string RandomItems_GetRandomInstagibItemClassName(string prefix)
+{
+       RandomSelection_Init();
+       FOREACH(Items, it.spawnflags & ITEM_FLAG_INSTAGIB,
+       {
+               string cvar_name = sprintf("g_%s_%s_probability", prefix,
+                       it.m_canonical_spawnfunc);
+               if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+               {
+                       LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+                       continue;
+               }
+               RandomSelection_AddString(it.m_canonical_spawnfunc, cvar(cvar_name), 1);
+       });
+       return RandomSelection_chosen_string;
+}
+
+string RandomItems_GetRandomOverkillItemClassName(string prefix)
+{
+       RandomSelection_Init();
+       FOREACH(Items, (it.spawnflags & ITEM_FLAG_OVERKILL) &&
+               !(it.spawnflags & ITEM_FLAG_MUTATORBLOCKED),
+       {
+               string cvar_name = sprintf("g_%s_overkill_%s_probability", prefix,
+                       it.m_canonical_spawnfunc);
+               if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+               {
+                       LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+                       continue;
+               }
+               RandomSelection_AddString(it.m_canonical_spawnfunc, cvar(cvar_name), 1);
+       });
+       string cvar_name = sprintf("g_%s_overkill_weapon_hmg_probability", prefix);
+       if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+       {
+               LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+       }
+       else
+       {
+               RandomSelection_AddString("weapon_hmg", cvar(cvar_name), 1);
+       }
+       cvar_name = sprintf("g_%s_overkill_weapon_rpc_probability", prefix);
+       if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+       {
+               LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+       }
+       else
+       {
+               RandomSelection_AddString("weapon_rpc", cvar(cvar_name), 1);
+       }
+       return RandomSelection_chosen_string;
+}
+
+//========================= Free functions ====================================
+
+/// \brief Returns list of classnames to replace a map item with.
+/// \param[in] item Item to inspect.
+/// \return List of classnames to replace a map item with.
+string RandomItems_GetItemReplacementClassNames(entity item)
+{
+       string cvar_name = sprintf("g_random_items_replace_%s", item.classname);
+       if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+       {
+               LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+               return "";
+       }
+       return cvar_string(cvar_name);
+}
+
+string RandomItems_GetRandomItemClassNameWithProperty(string prefix,
+       .bool item_property)
+{
+       RandomSelection_Init();
+       FOREACH(Items, it.item_property && (it.spawnflags & ITEM_FLAG_NORMAL),
+       {
+               string cvar_name = sprintf("g_%s_%s_probability", prefix,
+                       it.m_canonical_spawnfunc);
+               if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+               {
+                       LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+                       continue;
+               }
+               RandomSelection_AddString(it.m_canonical_spawnfunc, cvar(cvar_name), 1);
+       });
+       return RandomSelection_chosen_string;
+}
+
 /// \brief Replaces a map item.
 /// \param[in] item Item to replace.
 /// \return Spawned item on success, NULL otherwise.
@@ -293,7 +270,7 @@ entity RandomItems_ReplaceMapItem(entity item)
        string new_classname;
        if (new_classnames == "random")
        {
-               new_classname = RandomItems_GetRandomMapItemClassName();
+               new_classname = RandomItems_GetRandomItemClassName("random_items");
                if (new_classname == "")
                {
                        return NULL;
@@ -321,7 +298,8 @@ entity RandomItems_ReplaceMapItem(entity item)
        entity new_item;
        if (!expr_evaluate(autocvar_g_overkill))
        {
-               new_item = Item_Create(strzone(new_classname), item.origin);
+               new_item = Item_Create(strzone(new_classname), item.origin,
+                       item.noalign);
                random_items_is_spawning = false;
                if (new_item == NULL)
                {
@@ -333,6 +311,7 @@ entity RandomItems_ReplaceMapItem(entity item)
                new_item = spawn();
                new_item.classname = strzone(new_classname);
                new_item.spawnfunc_checked = true;
+               new_item.noalign = item.noalign;
                new_item.ok_item = true;
                Item_Initialize(new_item, new_classname);
                random_items_is_spawning = false;
@@ -349,152 +328,12 @@ entity RandomItems_ReplaceMapItem(entity item)
        return new_item;
 }
 
-/// \brief Returns a random classname of the instagib loot item.
-/// \return Random classname of the instagib loot item.
-string RandomItems_GetRandomInstagibLootItemClassName()
-{
-       RandomSelection_Init();
-       #define X(classname) \
-               RandomSelection_AddString( \
-                       classname, \
-                       cvar(sprintf("g_random_loot_%s_probability", RandomItems_GetItemVarName(classname))), \
-                       1 \
-               )
-       X("item_vaporizer_cells");
-       X("item_invisibility");
-       X("item_extralife");
-       X("item_speed");
-       #undef X
-       return RandomSelection_chosen_string;
-}
-
-/// \brief Returns a random classname of the overkill loot item.
-/// \return Random classname of the overkill loot item.
-string RandomItems_GetRandomOverkillLootItemClassName()
-{
-       RandomSelection_Init();
-       string varname;
-       #define X(classname) MACRO_BEGIN \
-               if ((varname = RandomItems_GetItemVarName(classname))) \
-               { \
-                       RandomSelection_AddString( \
-                               classname, \
-                               cvar(sprintf("g_random_loot_overkill_%s_probability", varname)), \
-                               1 \
-                       ); \
-               } \
-       MACRO_END
-       X("item_health_mega");
-       X("item_armor_small");
-       X("item_armor_medium");
-       X("item_armor_big");
-       X("item_armor_mega");
-       X("weapon_hmg");
-       X("weapon_rpc");
-       #undef X
-       return RandomSelection_chosen_string;
-}
-
-/// \brief Returns a random classname of the loot item.
-/// \return Random classname of the loot item.
-string RandomItems_GetRandomLootItemClassName()
-{
-       if (autocvar_g_instagib)
-       {
-               return RandomItems_GetRandomInstagibLootItemClassName();
-       }
-       if (expr_evaluate(autocvar_g_overkill))
-       {
-               return RandomItems_GetRandomOverkillLootItemClassName();
-       }
-       RandomSelection_Init();
-       #define X(type, name) \
-               RandomSelection_AddFloat( \
-                       RANDOM_ITEM_TYPE_##type, \
-                       autocvar_g_random_loot_##name##_probability, \
-                       1 \
-               )
-       X(HEALTH, health);
-       X(ARMOR, armor);
-       X(RESOURCE, resource);
-       X(WEAPON, weapon);
-       X(POWERUP, powerup);
-       #undef X
-       int item_type = RandomSelection_chosen_float;
-       switch (item_type)
-       {
-               case RANDOM_ITEM_TYPE_HEALTH:
-               {
-                       RandomSelection_Init();
-                       FOREACH(Items, it.instanceOfHealth,
-                       {
-                               RandomSelection_AddString(it.m_canonical_spawnfunc,
-                                       cvar(sprintf("g_random_loot_%s_probability",
-                                       it.m_canonical_spawnfunc)), 1);
-                       });
-                       return RandomSelection_chosen_string;
-               }
-               case RANDOM_ITEM_TYPE_ARMOR:
-               {
-                       RandomSelection_Init();
-                       FOREACH(Items, it.instanceOfArmor,
-                       {
-                               RandomSelection_AddString(it.m_canonical_spawnfunc,
-                                       cvar(sprintf("g_random_loot_%s_probability",
-                                       it.m_canonical_spawnfunc)), 1);
-                       });
-                       return RandomSelection_chosen_string;
-               }
-               case RANDOM_ITEM_TYPE_RESOURCE:
-               {
-                       RandomSelection_Init();
-                       FOREACH(Items, it.instanceOfAmmo,
-                       {
-                               RandomSelection_AddString(it.m_canonical_spawnfunc,
-                                       cvar(sprintf("g_random_loot_%s_probability",
-                                       it.m_canonical_spawnfunc)), 1);
-                       });
-                       return RandomSelection_chosen_string;
-               }
-               case RANDOM_ITEM_TYPE_WEAPON:
-               {
-                       RandomSelection_Init();
-                       FOREACH(Weapons, it != WEP_Null &&
-                               !(it.spawnflags & WEP_FLAG_MUTATORBLOCKED),
-                       {
-                               string cvar_name = sprintf("g_random_loot_%s_probability",
-                                       it.m_canonical_spawnfunc);
-                               RandomSelection_AddString(it.m_canonical_spawnfunc,
-                                       cvar(cvar_name), 1);
-                       });
-                       return RandomSelection_chosen_string;
-               }
-               case RANDOM_ITEM_TYPE_POWERUP:
-               {
-                       RandomSelection_Init();
-                       #define X(classname) \
-                               RandomSelection_AddString( \
-                                       classname, \
-                                       cvar(sprintf("g_random_loot_%s_probability", classname)), \
-                                       1 \
-                               )
-                       X("item_strength");
-                       X("item_shield");
-                       X("item_jetpack");
-                       X("item_fuel_regen");
-                       #undef X
-                       return RandomSelection_chosen_string;
-               }
-       }
-       return "";
-}
-
 /// \brief Spawns a random loot item.
 /// \param[in] position Position of the item.
 /// \return No return.
 void RandomItems_SpawnLootItem(vector position)
 {
-       string class_name = RandomItems_GetRandomLootItemClassName();
+       string class_name = RandomItems_GetRandomItemClassName("random_loot");
        if (class_name == "")
        {
                return;
index a0cc25baf0733707f651ed6bc335b9d02762e8fa..c9b4dbb9011ca91cd905d0c7221e3f089f4745b0 100644 (file)
@@ -1,3 +1,32 @@
 #pragma once
 
+/// \file
+/// \brief Header file that describes the random items mutator.
+/// \author Lyberta
+/// \copyright GNU GPLv2 or any later version.
+
 bool autocvar_g_random_items; ///< Whether to enable random items.
+
+/// \brief Returns a random classname of the item.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the item.
+/// \note This function will automatically detect gamemode and use cvars from
+/// that gamemode.
+string RandomItems_GetRandomItemClassName(string prefix);
+
+/// \brief Returns a random classname of the vanilla item.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the vanilla item.
+/// \note This includes mutator items that don't change gameplay a lot such as
+/// jetpack and new toys.
+string RandomItems_GetRandomVanillaItemClassName(string prefix);
+
+/// \brief Returns a random classname of the instagib item.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the instagib item.
+string RandomItems_GetRandomInstagibItemClassName(string prefix);
+
+/// \brief Returns a random classname of the overkill item.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the overkill item.
+string RandomItems_GetRandomOverkillItemClassName(string prefix);
diff --git a/qcsrc/common/mutators/mutator/stale_move_negation/_mod.inc b/qcsrc/common/mutators/mutator/stale_move_negation/_mod.inc
new file mode 100644 (file)
index 0000000..0e94058
--- /dev/null
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef SVQC
+    #include <common/mutators/mutator/stale_move_negation/sv_stale_move_negation.qc>
+#endif
diff --git a/qcsrc/common/mutators/mutator/stale_move_negation/_mod.qh b/qcsrc/common/mutators/mutator/stale_move_negation/_mod.qh
new file mode 100644 (file)
index 0000000..a2c60b4
--- /dev/null
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef SVQC
+    #include <common/mutators/mutator/stale_move_negation/sv_stale_move_negation.qh>
+#endif
diff --git a/qcsrc/common/mutators/mutator/stale_move_negation/sv_stale_move_negation.qc b/qcsrc/common/mutators/mutator/stale_move_negation/sv_stale_move_negation.qc
new file mode 100644 (file)
index 0000000..c54a8a6
--- /dev/null
@@ -0,0 +1,49 @@
+#include "sv_stale_move_negation.qh"
+
+AUTOCVAR(g_smneg, bool, false, "Stale-move negation: penalize repeated use of the same weapon");
+AUTOCVAR(g_smneg_bonus, bool, true, "Stale-move negation: allow weapons to become stronger than their baseline");
+AUTOCVAR(g_smneg_bonus_asymptote, float, 4, "Stale-move negation: damage = infinity at this bonus level");
+AUTOCVAR(g_smneg_cooldown_factor, float, 1 / 4, "Stale-move negation: penalty cooldown factor");
+REGISTER_MUTATOR(mutator_smneg, autocvar_g_smneg);
+
+MUTATOR_HOOKFUNCTION(mutator_smneg, BuildMutatorsString) {
+    M_ARGV(0, string) = strcat(M_ARGV(0, string), ":StaleMoveNegation");
+}
+
+MUTATOR_HOOKFUNCTION(mutator_smneg, BuildMutatorsPrettyString) {
+    M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Stale-move negation");
+}
+
+.float x_smneg_weight[Weapons_MAX];
+
+float smneg_multiplier(float weight) {
+    float a = autocvar_g_smneg_bonus_asymptote;
+    float x = max(
+        (!autocvar_g_smneg_bonus ? 0 : (-a + .1)),
+        weight / start_health
+    );
+    float z = (M_PI / 5) * a;
+    float f = (x > 0)
+        ? (atan(z / x) / (M_PI / 2))
+        : (tan(-(x / z)) + 1);
+    return f;
+}
+
+MUTATOR_HOOKFUNCTION(mutator_smneg, Damage_Calculate) {
+    float deathtype = M_ARGV(3, float);
+    Weapon w = DEATH_WEAPONOF(deathtype);
+    if (w == WEP_Null) return;
+
+    entity frag_attacker = M_ARGV(1, entity);
+    entity c = CS(frag_attacker);
+    float weight = c.x_smneg_weight[w.m_id];
+    float f = smneg_multiplier(weight);
+    float frag_damage = M_ARGV(4, float) = f * M_ARGV(4, float);
+    M_ARGV(6, vector) = f * M_ARGV(6, vector); // force
+
+    c.x_smneg_weight[w.m_id] = weight + frag_damage;
+    float restore = frag_damage * autocvar_g_smneg_cooldown_factor;
+    FOREACH(Weapons, it != WEP_Null && it != w, {
+        c.x_smneg_weight[it.m_id] -= restore;
+    });
+}
diff --git a/qcsrc/common/mutators/mutator/stale_move_negation/sv_stale_move_negation.qh b/qcsrc/common/mutators/mutator/stale_move_negation/sv_stale_move_negation.qh
new file mode 100644 (file)
index 0000000..6f70f09
--- /dev/null
@@ -0,0 +1 @@
+#pragma once
index 20e2d4cc32f16d0b736e421d0a1172262492ff7c..20c580a8591b0e371981d671ba208a459229e2b2 100644 (file)
@@ -75,6 +75,7 @@ void Physics_UpdateStats(entity this)
        STAT(MOVEVARS_AIRACCELERATE, this) = Physics_ClientOption(this, "airaccelerate", autocvar_sv_airaccelerate);
        STAT(MOVEVARS_AIRSTOPACCELERATE, this) = Physics_ClientOption(this, "airstopaccelerate", autocvar_sv_airstopaccelerate);
        STAT(MOVEVARS_JUMPVELOCITY, this) = Physics_ClientOption(this, "jumpvelocity", autocvar_sv_jumpvelocity);
+       STAT(MOVEVARS_JUMPVELOCITY_CROUCH, this) = Physics_ClientOption(this, "jumpvelocity_crouch", autocvar_sv_jumpvelocity_crouch);
        STAT(MOVEVARS_TRACK_CANJUMP, this) = Physics_ClientOption(this, "track_canjump", autocvar_sv_track_canjump);
 }
 #endif
@@ -303,7 +304,7 @@ bool PlayerJump(entity this)
 #endif
 
        bool doublejump = false;
-       float mjumpheight = PHYS_JUMPVELOCITY(this);
+       float mjumpheight = ((PHYS_JUMPVELOCITY_CROUCH(this) && IS_DUCKED(this)) ? PHYS_JUMPVELOCITY_CROUCH(this) : PHYS_JUMPVELOCITY(this));
        bool track_jump = PHYS_CL_TRACK_CANJUMP(this);
 
        if (MUTATOR_CALLHOOK(PlayerJump, this, mjumpheight, doublejump))
index ae59381e5c11394ce93abcf441cd5c453be4d8a6..0ebea585f80e61071cedd24e4c8e2d22abdec445 100644 (file)
@@ -82,6 +82,7 @@ bool IsFlying(entity a);
 
 #define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS(s) STAT(MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS)
 #define PHYS_JUMPVELOCITY(s)                STAT(MOVEVARS_JUMPVELOCITY, s)
+#define PHYS_JUMPVELOCITY_CROUCH(s)         STAT(MOVEVARS_JUMPVELOCITY_CROUCH, s)
 
 #define PHYS_MAXAIRSPEED(s)                 STAT(MOVEVARS_MAXAIRSPEED, s)
 #define PHYS_MAXAIRSTRAFESPEED(s)           STAT(MOVEVARS_MAXAIRSTRAFESPEED, s)
index 66bd60ea4a8c89b503f8ce110946de1bf9c02697..ac57550604ea511ac6521c98168e767f7b805907 100644 (file)
@@ -217,28 +217,36 @@ float autocvar_sv_dodging_wall_distance_threshold;
 bool autocvar_sv_dodging_frozen;
 bool autocvar_sv_dodging_frozen_doubletap;
 float autocvar_sv_dodging_height_threshold;
-float autocvar_sv_dodging_horiz_speed;
-float autocvar_sv_dodging_horiz_speed_frozen;
+float autocvar_sv_dodging_horiz_speed_min;
+float autocvar_sv_dodging_horiz_speed_max;
+float autocvar_sv_dodging_horiz_force_slowest;
+float autocvar_sv_dodging_horiz_force_fastest;
+float autocvar_sv_dodging_horiz_force_frozen;
 float autocvar_sv_dodging_ramp_time;
 float autocvar_sv_dodging_up_speed;
 bool autocvar_sv_dodging_wall_dodging;
 bool autocvar_sv_dodging_air_dodging;
-float autocvar_sv_dodging_maxspeed = 450;
+float autocvar_sv_dodging_maxspeed;
+float autocvar_sv_dodging_air_maxspeed;
 #endif
 
 #if 0
 REGISTER_STAT(DODGING, int, g_dodging)
 REGISTER_STAT(DODGING_DELAY, float, autocvar_sv_dodging_delay)
 REGISTER_STAT(DODGING_DISTANCE_THRESHOLD, float, autocvar_sv_dodging_wall_distance_threshold)
-REGISTER_STAT(DODGING_FROZEN_NO_DOUBLETAP, int, autocvar_sv_dodging_frozen_doubletap)
+REGISTER_STAT(DODGING_FROZEN_DOUBLETAP, int, autocvar_sv_dodging_frozen_doubletap)
 REGISTER_STAT(DODGING_HEIGHT_THRESHOLD, float, autocvar_sv_dodging_height_threshold)
-REGISTER_STAT(DODGING_HORIZ_SPEED, float, autocvar_sv_dodging_horiz_speed)
-REGISTER_STAT(DODGING_HORIZ_SPEED_FROZEN, float, autocvar_sv_dodging_horiz_speed_frozen)
+REGISTER_STAT(DODGING_HORIZ_SPEED_MIN, float, autocvar_sv_dodging_horiz_speed_min)
+REGISTER_STAT(DODGING_HORIZ_SPEED_MAX, float, autocvar_sv_dodging_horiz_speed_max)
+REGISTER_STAT(DODGING_HORIZ_FORCE_SLOWEST, float, autocvar_sv_dodging_horiz_force_slowest)
+REGISTER_STAT(DODGING_HORIZ_FORCE_FASTEST, float, autocvar_sv_dodging_horiz_force_fastest)
+REGISTER_STAT(DODGING_HORIZ_FORCE_FROZEN, float, autocvar_sv_dodging_horiz_force_frozen)
 REGISTER_STAT(DODGING_RAMP_TIME, float, autocvar_sv_dodging_ramp_time)
 REGISTER_STAT(DODGING_UP_SPEED, float, autocvar_sv_dodging_up_speed)
 REGISTER_STAT(DODGING_WALL, bool, autocvar_sv_dodging_wall_dodging)
 REGISTER_STAT(DODGING_AIR, bool, autocvar_sv_dodging_air_dodging)
 REGISTER_STAT(DODGING_MAXSPEED, float, autocvar_sv_dodging_maxspeed)
+REGISTER_STAT(DODGING_AIR_MAXSPEED, float, autocvar_sv_dodging_air_maxspeed)
 #endif
 /** cvar loopback */
 REGISTER_STAT(DODGING_FROZEN, int, autocvar_sv_dodging_frozen)
@@ -345,6 +353,7 @@ REGISTER_STAT(MOVEVARS_AIRACCELERATE, float)
 // FIXME: Was 0 on server, 1 on client. Still want that?
 REGISTER_STAT(MOVEVARS_ENTGRAVITY, float, (this.gravity) ? this.gravity : 1)
 REGISTER_STAT(MOVEVARS_JUMPVELOCITY, float)
+REGISTER_STAT(MOVEVARS_JUMPVELOCITY_CROUCH, float)
 REGISTER_STAT(MOVEVARS_MAXAIRSPEED, float)
 REGISTER_STAT(MOVEVARS_STEPHEIGHT, float, autocvar_sv_stepheight)
 REGISTER_STAT(MOVEVARS_AIRACCEL_QW, float)
index 8ded50d16b2da0d88a35c68eb333006786a15636..ddd62ae4e8f5f3ce5fc22b43d35086cc67d686ad 100644 (file)
@@ -94,11 +94,22 @@ void button_damage(entity this, entity inflictor, entity attacker, float damage,
        if(this.spawnflags & DOOR_NOSPLASH)
                if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
                        return;
-       this.health = this.health - damage;
-       if (this.health <= 0)
+       if (this.spawnflags & BUTTON_DONTACCUMULATEDMG)
        {
-               this.enemy = attacker;
-               button_fire(this);
+               if (this.health <= damage)
+               {
+                       this.enemy = attacker;
+                       button_fire(this);
+               }
+       }
+       else
+       {
+               this.health = this.health - damage;
+               if (this.health <= 0)
+               {
+                       this.enemy = attacker;
+                       button_fire(this);
+               }
        }
 }
 
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..75a6006eb5e703e24b79362c9df7b0f39e328376 100644 (file)
@@ -1 +1,3 @@
 #pragma once
+
+const int BUTTON_DONTACCUMULATEDMG = 128;
index e7b309062848d0fe673b8d797f4039512f292372..4447ea21e25f0cf7928378fc97a462eb004c2b05 100644 (file)
@@ -13,7 +13,9 @@ void trigger_heal_touch(entity this, entity toucher)
                if (!IS_DEAD(toucher))
                if (toucher.triggerhealtime < time)
                {
-                       EXACTTRIGGER_TOUCH(this, toucher);
+                       bool is_trigger = !boolean(!this.nottargeted && this.targetname != "");
+                       if(is_trigger)
+                               EXACTTRIGGER_TOUCH(this, toucher);
                        toucher.triggerhealtime = time + 1;
 
                        if (toucher.health < this.max_health)
@@ -26,6 +28,11 @@ void trigger_heal_touch(entity this, entity toucher)
        }
 }
 
+void trigger_heal_use(entity this, entity actor, entity trigger)
+{
+       trigger_heal_touch(this, actor);
+}
+
 spawnfunc(trigger_heal)
 {
        this.active = ACTIVE_ACTIVE;
@@ -40,4 +47,17 @@ spawnfunc(trigger_heal)
                this.noise = "misc/mediumhealth.wav";
        precache_sound(this.noise);
 }
+
+spawnfunc(target_heal)
+{
+       this.active = ACTIVE_ACTIVE;
+       this.use = trigger_heal_use;
+       if (!this.health)
+               this.health = 10;
+       if (!this.max_health)
+               this.max_health = 200; //Max health topoff for field
+       if(this.noise == "")
+               this.noise = "misc/mediumhealth.wav";
+       precache_sound(this.noise);
+}
 #endif
index df965074587315eebbc4781704aba2f7386410f9..822411c6a23a93d2b58093f3e28c1616564be7b1 100644 (file)
@@ -38,9 +38,9 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
 
        torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
 
-       grav = PHYS_GRAVITY(other);
-       if(PHYS_ENTGRAVITY(other))
-               grav *= PHYS_ENTGRAVITY(other);
+       grav = PHYS_GRAVITY(tgt);
+       if(PHYS_ENTGRAVITY(tgt))
+               grav *= PHYS_ENTGRAVITY(tgt);
 
        zdist = torg.z - org.z;
        sdist = vlen(torg - org - zdist * '0 0 1');
index 2f37eb7e2b665c260d6e5174797eaaec3d58cda4..baeb9a51bcbf127d14f8dc89acb36b6814ab5901 100644 (file)
@@ -198,6 +198,7 @@ void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
                        break;
        }
        me.encryptLabel.setText(me.encryptLabel, me.currentServerEncrypt);
+       setZonedTooltip(me.encryptLabel, _("Use the `crypto_aeslevel` cvar to change your preferences"), string_null);
 
        s = crypto_getidfp(me.currentServerCName);
        if (!s) { s = _("N/A"); }
index 4303aa9764ea3d9164380fe49023c410824786bf..b71d4459d1387469f9c1732fa906dda15617f965 100644 (file)
@@ -311,6 +311,7 @@ string autocvar_sv_jumpspeedcap_max;
 float autocvar_sv_jumpspeedcap_max_disable_on_ramps;
 string autocvar_sv_jumpspeedcap_min;
 float autocvar_sv_jumpvelocity;
+float autocvar_sv_jumpvelocity_crouch;
 bool autocvar_sv_logscores_bots;
 bool autocvar_sv_logscores_console;
 bool autocvar_sv_logscores_file;
index 4f7dd14a54da6040d8bc1c93965c515b8a37d049..d7b9a7ae0e7d6305ef86a5994b2b3e09f2edef80 100644 (file)
@@ -873,19 +873,19 @@ Called when a client types 'kill' in the console
 .float clientkill_nexttime;
 void ClientKill_Now_TeamChange(entity this)
 {
-       if(CS(this).killindicator_teamchange == -1)
+       if(this.killindicator_teamchange == -1)
        {
                JoinBestTeam( this, false, true );
        }
-       else if(CS(this).killindicator_teamchange == -2)
+       else if(this.killindicator_teamchange == -2)
        {
                if(blockSpectators)
                        Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
                PutObserverInServer(this);
        }
        else
-               SV_ChangeTeam(this, CS(this).killindicator_teamchange - 1);
-       CS(this).killindicator_teamchange = 0;
+               SV_ChangeTeam(this, this.killindicator_teamchange - 1);
+       this.killindicator_teamchange = 0;
 }
 
 void ClientKill_Now(entity this)
@@ -893,7 +893,7 @@ void ClientKill_Now(entity this)
        if(this.vehicle)
        {
            vehicles_exit(this.vehicle, VHEF_RELEASE);
-           if(!CS(this).killindicator_teamchange)
+           if(!this.killindicator_teamchange)
            {
             this.vehicle_health = -1;
             Damage(this, this, this, 1 , DEATH_KILL.m_id, this.origin, '0 0 0');
@@ -905,7 +905,7 @@ void ClientKill_Now(entity this)
 
        this.killindicator = NULL;
 
-       if(CS(this).killindicator_teamchange)
+       if(this.killindicator_teamchange)
                ClientKill_Now_TeamChange(this);
 
        if (!IS_SPEC(this) && !IS_OBSERVER(this) && MUTATOR_CALLHOOK(ClientKill_Now, this) == false)
@@ -970,7 +970,7 @@ void ClientKill_TeamChange (entity this, float targetteam) // 0 = don't change,
        return;
     killtime = M_ARGV(1, float);
 
-       CS(this).killindicator_teamchange = targetteam;
+       this.killindicator_teamchange = targetteam;
 
     if(!this.killindicator)
        {
index 2282c09cbb1cafd54e3a667886430b98b554c342..af81535a7a231bbd66f34bc0612d40caaf567999 100644 (file)
@@ -73,7 +73,6 @@ CLASS(Client, Object)
 
     ATTRIB(Client, parm_idlesince, int, this.parm_idlesince);
     ATTRIB(Client, muted, bool, this.muted);
-    ATTRIB(Client, killindicator_teamchange, int, this.killindicator_teamchange);
     ATTRIB(Client, idlekick_lasttimeleft, float, this.idlekick_lasttimeleft);
     ATTRIB(Client, pm_frametime, float, this.pm_frametime);
     ATTRIB(Client, pressedkeys, int, this.pressedkeys);
index 08a4a726bd54ab0b47362c79d69fe178dd302f8f..0566d576767bdaf8e3d6f1012e7090c0e69d2aa2 100644 (file)
@@ -375,6 +375,8 @@ const float ACTIVE_TOGGLE   = 3;
 
 .float stat_respawn_time = _STAT(RESPAWN_TIME); // shows respawn time, and is negative when awaiting respawn
 
+.int killindicator_teamchange;
+
 void PlayerUseKey(entity this);
 
 USING(spawn_evalfunc_t, vector(entity this, entity player, entity spot, vector current));
index adaa8c36984525277e41f8c52607bc4ad9e74b04..afe018c08bc0198c2240c99e44f7dea7e75295fd 100644 (file)
@@ -54,7 +54,7 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype)
        {
                // regular frag
                GameRules_scoring_add(attacker, KILLS, 1);
-               if(targ.playerid)
+               if(!warmup_stage && targ.playerid)
                        PlayerStats_GameReport_Event_Player(attacker, sprintf("kills-%d", targ.playerid), 1);
        }
 
@@ -360,11 +360,16 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
 
                        attacker.killsound += 1;
 
+                       // TODO: improve SPREE_ITEM and KILL_SPREE_LIST
+                       // these 2 macros are spread over multiple files
                        #define SPREE_ITEM(counta,countb,center,normal,gentle) \
                                case counta: \
                                { \
                                        Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
-                                       PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
+                                       if (!warmup_stage)\
+                                       {\
+                                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
+                                       }\
                                        break; \
                                }
                        switch(CS(attacker).killcount)
@@ -374,7 +379,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                        }
                        #undef SPREE_ITEM
 
-                       if(!checkrules_firstblood)
+                       if(!warmup_stage && !checkrules_firstblood)
                        {
                                checkrules_firstblood = true;
                                notif_firstblood = true; // modify the current messages so that they too show firstblood information
@@ -494,7 +499,10 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                if(GameRules_scoring_add(targ, SCORE, 0) == -5)
                {
                        Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_ACHIEVEMENT_BOTLIKE);
-                       PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
+                       if (!warmup_stage)
+                       {
+                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
+                       }
                }
        }
 
index 0bbf499b5883b7798ddf1bac303caae7cc2a4d64..29a8609bc628530049fb3b11677599529d320b5b 100644 (file)
 /// this item is on the ground.
 .bool m_isexpiring;
 
-entity Item_Create(string class_name, vector position)
+entity Item_Create(string class_name, vector position, bool no_align)
 {
        entity item = spawn();
        item.classname = class_name;
        item.spawnfunc_checked = true;
        setorigin(item, position);
+       item.noalign = no_align;
        Item_Initialize(item, class_name);
        if (wasfreed(item))
        {
index a1e3a313108e93f217df8db885a9d06a1d021f68..af55eebd4d60e42c34505515b42d3fd85dd1b689 100644 (file)
@@ -7,8 +7,10 @@
 /// \brief Creates a new item.
 /// \param[in] class_name Class name of the item.
 /// \param[in] position Position of the item.
+/// \param[in] no_align True if item should be placed directly at specified
+/// position, false to let it drop to the ground.
 /// \return Item on success, NULL otherwise.
-entity Item_Create(string class_name, vector position);
+entity Item_Create(string class_name, vector position, bool no_align);
 
 /// \brief Initializes the item according to classname.
 /// \param[in,out] item Item to initialize.
index 159df8a7818edbf5348a6d9ab184fb1227dbaefe..919df49013dd5f53cc1c5c2f819cf11c2ee38d41 100644 (file)
@@ -266,7 +266,11 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDies)
 
        ca_LastPlayerForTeam_Notify(frag_target);
        if (!allowed_to_spawn)
-               frag_target.respawn_flags =  RESPAWN_SILENT;
+       {
+               frag_target.respawn_flags = RESPAWN_SILENT;
+               // prevent unwanted sudden rejoin as spectator and move of spectator camera
+               frag_target.respawn_time = time + 2;
+       }
        if (!warmup_stage)
                eliminatedPlayers.SendFlags |= 1;
        if(IS_BOT_CLIENT(frag_target))
@@ -289,7 +293,7 @@ MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver)
 
        if (!IS_DEAD(player))
                ca_LastPlayerForTeam_Notify(player);
-       if (CS(player).killindicator_teamchange == -2) // player wants to spectate
+       if (player.killindicator_teamchange == -2) // player wants to spectate
                player.caplayer = 0;
        if (player.caplayer)
                player.frags = FRAGS_LMS_LOSER;
index ac2dcb1ede667f10ab90dd9953895faeff3c1437..26fc9e659204d7bf6305a5d2483bf1b2b4ba9819 100644 (file)
@@ -538,7 +538,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                {
                        delete(this.killindicator);
                        this.killindicator = NULL;
-                       if(CS(this).killindicator_teamchange)
+                       if(this.killindicator_teamchange)
                                defer_ClientKill_Now_TeamChange = true;
 
                        if(this.classname == "body")
@@ -558,6 +558,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                if(w != WEP_Null && accuracy_isgooddamage(attacker, this))
                        CS(attacker).accuracy.(accuracy_frags[w.m_id-1]) += 1;
 
+               this.respawn_time = 0;
                MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage);
                damage = M_ARGV(4, float);
                excess = max(0, damage - take - save);
@@ -586,6 +587,9 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                if(this.health >= 1 || !(IS_PLAYER(this) || this.classname == "body"))
                        return;
 
+               if (!this.respawn_time) // can be set in the mutator hook PlayerDies
+                       calculate_player_respawn_time(this);
+
                // when we get here, player actually dies
 
                Unfreeze(this); // remove any icy remains
@@ -621,9 +625,6 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
 
                STAT(MOVEVARS_SPECIALCOMMAND, this) = false; // sweet release
 
-               // when to allow respawn
-               calculate_player_respawn_time(this);
-
                this.death_time = time;
                if (random() < 0.5)
                        animdecide_setstate(this, this.anim_state | ANIMSTATE_DEAD1, true);
index 12aca2133a0f67aa48a09d9bd9e8a07eee5f73e2..fd73969cb81a9d16cb88c55b02bee012cd0dfaa1 100644 (file)
@@ -925,6 +925,11 @@ void SV_ChangeTeam(entity this, float _color)
        source_team = Team_TeamToNumber(source_color + 1);
        destination_team = Team_TeamToNumber(destination_color + 1);
 
+       if (destination_team == -1)
+       {
+               return;
+       }
+
        CheckAllowedTeams(this);
 
        if (destination_team == 1 && c1 < 0) destination_team = 4;
diff --git a/randomitems-xonotic.cfg b/randomitems-xonotic.cfg
new file mode 100644 (file)
index 0000000..803e6c3
--- /dev/null
@@ -0,0 +1,163 @@
+// Random items mutator config
+
+// Map items
+
+set g_random_items_replace_item_health_small "random" "Classnames to replace small health with."
+set g_random_items_replace_item_health_medium "random" "Classnames to replace medium health with."
+set g_random_items_replace_item_health_big "random" "Classnames to replace big health with."
+set g_random_items_replace_item_health_mega "random" "Classnames to replace mega health with."
+set g_random_items_replace_item_armor_small "random" "Classnames to replace small armor with."
+set g_random_items_replace_item_armor_medium "random" "Classnames to replace medium armor with."
+set g_random_items_replace_item_armor_big "random" "Classnames to replace big armor with."
+set g_random_items_replace_item_armor_mega "random" "Classnames to replace mega armor with."
+set g_random_items_replace_item_shells "random" "Classnames to replace shells with."
+set g_random_items_replace_item_bullets "random" "Classnames to replace bullets with."
+set g_random_items_replace_item_rockets "random" "Classnames to replace rockets with."
+set g_random_items_replace_item_cells "random" "Classnames to replace cells with."
+set g_random_items_replace_item_plasma "random" "Classnames to replace plasma with."
+set g_random_items_replace_item_fuel "random" "Classnames to replace fuel with."
+set g_random_items_replace_weapon_blaster "random" "Classnames to replace blaster with."
+set g_random_items_replace_weapon_shotgun "random" "Classnames to replace shotgun with."
+set g_random_items_replace_weapon_machinegun "random" "Classnames to replace machinegun with."
+set g_random_items_replace_weapon_mortar "random" "Classnames to replace mortar with."
+set g_random_items_replace_weapon_electro "random" "Classnames to replace electro with."
+set g_random_items_replace_weapon_crylink "random" "Classnames to replace crylink with."
+set g_random_items_replace_weapon_vortex "random" "Classnames to replace vortex with."
+set g_random_items_replace_weapon_hagar "random" "Classnames to replace hagar with."
+set g_random_items_replace_weapon_devastator "random" "Classnames to replace devastator with."
+set g_random_items_replace_weapon_shockwave "random" "Classnames to replace shockwave with."
+set g_random_items_replace_weapon_arc "random" "Classnames to replace arc with."
+set g_random_items_replace_weapon_hook "random" "Classnames to replace hook with."
+set g_random_items_replace_weapon_tuba "random" "Classnames to replace tuba with."
+set g_random_items_replace_weapon_porto "random" "Classnames to replace port-o-launch with."
+set g_random_items_replace_weapon_fireball "random" "Classnames to replace fireball with."
+set g_random_items_replace_weapon_minelayer "random" "Classnames to replace mine layer with."
+set g_random_items_replace_weapon_hlac "random" "Classnames to replace HLAC with."
+set g_random_items_replace_weapon_rifle "random" "Classnames to replace rifle with."
+set g_random_items_replace_weapon_seeker "random" "Classnames to replace TAG seeker with."
+set g_random_items_replace_weapon_vaporizer "random" "Classnames to replace vaporizer with."
+set g_random_items_replace_weapon_hmg "random" "Classnames to replace HMG with."
+set g_random_items_replace_weapon_rpc "random" "Classnames to replace RPC with."
+set g_random_items_replace_item_strength "random" "Classnames to replace strength with."
+set g_random_items_replace_item_shield "random" "Classnames to replace shield with."
+set g_random_items_replace_item_fuel_regen "random" "Classnames to replace fuel regeneration with."
+set g_random_items_replace_item_jetpack "random" "Classnames to replace jetpack with."
+set g_random_items_replace_item_vaporizer_cells "random" "Classnames to replace vaporizer cells with."
+set g_random_items_replace_item_invisibility "random" "Classnames to replace invisibility with."
+set g_random_items_replace_item_extralife "random" "Classnames to replace extra life with."
+set g_random_items_replace_item_speed "random" "Classnames to replace speed with."
+set g_random_items_health_probability 1 "Probability of random health items spawning in the map."
+set g_random_items_armor_probability 1 "Probability of random armor items spawning in the map."
+set g_random_items_resource_probability 1 "Probability of random resource items spawning in the map."
+set g_random_items_weapon_probability 1 "Probability of random weapons spawning in the map."
+set g_random_items_powerup_probability 0.15 "Probability of random powerups spawning in the map."
+set g_random_items_item_health_small_probability 10 "Probability of random small health spawning in the map."
+set g_random_items_item_health_medium_probability 4 "Probability of random medium health spawning in the map."
+set g_random_items_item_health_big_probability 2 "Probability of random big health spawning in the map."
+set g_random_items_item_health_mega_probability 1 "Probability of random mega health spawning in the map."
+set g_random_items_item_armor_small_probability 10 "Probability of random small armor spawning in the map."
+set g_random_items_item_armor_medium_probability 4 "Probability of random medium armor spawning in the map."
+set g_random_items_item_armor_big_probability 2 "Probability of random big armor spawning in the map."
+set g_random_items_item_armor_mega_probability 1 "Probability of random mega armor spawning in the map."
+set g_random_items_item_shells_probability 1 "Probability of random shells spawning in the map."
+set g_random_items_item_bullets_probability 1 "Probability of random bullets spawning in the map."
+set g_random_items_item_rockets_probability 1 "Probability of random rockets spawning in the map."
+set g_random_items_item_cells_probability 1 "Probability of random cells spawning in the map."
+set g_random_items_item_plasma_probability 0 "Probability of random plasma spawning in the map."
+set g_random_items_item_fuel_probability 0 "Probability of random fuel spawning in the map."
+set g_random_items_weapon_blaster_probability 0 "Probability of random blaster spawning in the map."
+set g_random_items_weapon_shotgun_probability 0 "Probability of random shotgun spawning in the map."
+set g_random_items_weapon_machinegun_probability 1 "Probability of random machinegun spawning in the map."
+set g_random_items_weapon_mortar_probability 1 "Probability of random mortar spawning in the map."
+set g_random_items_weapon_electro_probability 1 "Probability of random electro spawning in the map."
+set g_random_items_weapon_crylink_probability 1 "Probability of random crylink spawning in the map."
+set g_random_items_weapon_vortex_probability 1 "Probability of random vortex spawning in the map."
+set g_random_items_weapon_hagar_probability 1 "Probability of random hagar spawning in the map."
+set g_random_items_weapon_devastator_probability 1 "Probability of random devastator spawning in the map."
+set g_random_items_weapon_shockwave_probability 0 "Probability of random shockwave spawning in the map."
+set g_random_items_weapon_arc_probability 0 "Probability of random arc spawning in the map."
+set g_random_items_weapon_hook_probability 0 "Probability of random hook spawning in the map."
+set g_random_items_weapon_tuba_probability 0 "Probability of random tuba spawning in the map."
+set g_random_items_weapon_porto_probability 0 "Probability of random port-o-launch spawning in the map."
+set g_random_items_weapon_fireball_probability 0 "Probability of random fireball spawning in the map."
+set g_random_items_weapon_minelayer_probability 0 "Probability of random mine layer spawning in the map."
+set g_random_items_weapon_hlac_probability 0 "Probability of random HLAC spawning in the map."
+set g_random_items_weapon_rifle_probability 0 "Probability of random rifle spawning in the map."
+set g_random_items_weapon_seeker_probability 0 "Probability of random TAG seeker spawning in the map."
+set g_random_items_weapon_vaporizer_probability 0 "Probability of random vaporizer spawning in the map."
+set g_random_items_item_strength_probability 1 "Probability of random strength spawning in the map."
+set g_random_items_item_shield_probability 1 "Probability of random shield spawning in the map."
+set g_random_items_item_fuel_regen_probability 0 "Probability of random fuel regeneration spawning in the map."
+set g_random_items_item_jetpack_probability 0 "Probability of random jetpack spawning in the map."
+set g_random_items_item_vaporizer_cells_probability 20 "Probability of random vaporizer cells spawning in the map."
+set g_random_items_item_invisibility_probability 1 "Probability of random invisibility spawning in the map."
+set g_random_items_item_extralife_probability 1 "Probability of random extra life spawning in the map."
+set g_random_items_item_speed_probability 1 "Probability of random speed spawning in the map."
+set g_random_items_overkill_item_health_mega_probability 1 "Probability of random mega health spawning in the map during overkill."
+set g_random_items_overkill_item_armor_small_probability 10 "Probability of random small armor spawning in the map during overkill."
+set g_random_items_overkill_item_armor_medium_probability 4 "Probability of random medium armor spawning in the map during overkill."
+set g_random_items_overkill_item_armor_big_probability 2 "Probability of random big armor spawning in the map during overkill."
+set g_random_items_overkill_item_armor_mega_probability 1 "Probability of random mega armor spawning in the map during overkill."
+set g_random_items_overkill_weapon_hmg_probability 0.5 "Probability of random HMG spawning in the map during overkill."
+set g_random_items_overkill_weapon_rpc_probability 0.5 "Probability of random RPC spawning in the map during overkill."
+
+// Loot
+
+set g_random_loot_min 0 "Minimum amount of loot items."
+set g_random_loot_max 4 "Maximum amount of loot items."
+set g_random_loot_time 10 "Amount of time the loot will stay in seconds."
+set g_random_loot_spread 200 "How far can loot be thrown."
+set g_random_loot_health_probability 1 "Probability of random health items spawning as loot."
+set g_random_loot_armor_probability 1 "Probability of random armor items spawning as loot."
+set g_random_loot_resource_probability 1 "Probability of random ammo items spawning as loot."
+set g_random_loot_weapon_probability 1 "Probability of random weapons spawning as loot."
+set g_random_loot_powerup_probability 0.2 "Probability of random powerups spawning as loot."
+set g_random_loot_item_health_small_probability 4 "Probability of random small health spawning as loot."
+set g_random_loot_item_health_medium_probability 3 "Probability of random medium health spawning as loot."
+set g_random_loot_item_health_big_probability 2 "Probability of random big health spawning as loot."
+set g_random_loot_item_health_mega_probability 1 "Probability of random mega health spawning as loot."
+set g_random_loot_item_armor_small_probability 4 "Probability of random small armor spawning as loot."
+set g_random_loot_item_armor_medium_probability 3 "Probability of random medium armor spawning as loot."
+set g_random_loot_item_armor_big_probability 2 "Probability of random big armor spawning as loot."
+set g_random_loot_item_armor_mega_probability 1 "Probability of random mega armor spawning as loot."
+set g_random_loot_item_shells_probability 1 "Probability of random shells spawning as loot."
+set g_random_loot_item_bullets_probability 1 "Probability of random bullets spawning as loot."
+set g_random_loot_item_rockets_probability 1 "Probability of random rockets spawning as loot."
+set g_random_loot_item_cells_probability 1 "Probability of random cells spawning as loot."
+set g_random_loot_item_plasma_probability 0 "Probability of random plasma spawning as loot."
+set g_random_loot_item_fuel_probability 0 "Probability of random fuel spawning as loot."
+set g_random_loot_weapon_blaster_probability 0 "Probability of random blaster spawning as loot."
+set g_random_loot_weapon_shotgun_probability 0 "Probability of random shotgun spawning as loot."
+set g_random_loot_weapon_machinegun_probability 1 "Probability of random machinegun spawning as loot."
+set g_random_loot_weapon_mortar_probability 1 "Probability of random mortar spawning as loot."
+set g_random_loot_weapon_electro_probability 1 "Probability of random electro spawning as loot."
+set g_random_loot_weapon_crylink_probability 1 "Probability of random crylink spawning as loot."
+set g_random_loot_weapon_vortex_probability 1 "Probability of random vortex spawning as loot."
+set g_random_loot_weapon_hagar_probability 1 "Probability of random hagar spawning as loot."
+set g_random_loot_weapon_devastator_probability 1 "Probability of random devastator spawning as loot."
+set g_random_loot_weapon_shockwave_probability 0 "Probability of random shockwave spawning as loot."
+set g_random_loot_weapon_arc_probability 0 "Probability of random arc spawning as loot."
+set g_random_loot_weapon_hook_probability 0 "Probability of random hook spawning as loot."
+set g_random_loot_weapon_tuba_probability 0 "Probability of random tuba spawning as loot."
+set g_random_loot_weapon_porto_probability 0 "Probability of random port-o-launch spawning as loot."
+set g_random_loot_weapon_fireball_probability 0 "Probability of random fireball spawning as loot."
+set g_random_loot_weapon_minelayer_probability 0 "Probability of random mine layer spawning as loot."
+set g_random_loot_weapon_hlac_probability 0 "Probability of random HLAC spawning as loot."
+set g_random_loot_weapon_rifle_probability 0 "Probability of random rifle spawning as loot."
+set g_random_loot_weapon_seeker_probability 0 "Probability of random TAG seeker spawning as loot."
+set g_random_loot_weapon_vaporizer_probability 0 "Probability of random vaporizer spawning as loot."
+set g_random_loot_item_strength_probability 1 "Probability of random strength spawning as loot."
+set g_random_loot_item_shield_probability 1 "Probability of random shield spawning as loot."
+set g_random_loot_item_fuel_regen_probability 0 "Probability of random fuel regeneration spawning as loot."
+set g_random_loot_item_jetpack_probability 0 "Probability of random jetpack spawning as loot."
+set g_random_loot_item_vaporizer_cells_probability 20 "Probability of random vaporizer cells spawning as loot."
+set g_random_loot_item_invisibility_probability 1 "Probability of random invisibility spawning as loot."
+set g_random_loot_item_extralife_probability 1 "Probability of random extra life spawning as loot."
+set g_random_loot_item_speed_probability 1 "Probability of random speed spawning as loot."
+set g_random_loot_overkill_item_health_mega_probability 1 "Probability of random mega health spawning as loot during overkill."
+set g_random_loot_overkill_item_armor_small_probability 10 "Probability of random small armor spawning as loot during overkill."
+set g_random_loot_overkill_item_armor_medium_probability 4 "Probability of random medium armor spawning as loot during overkill."
+set g_random_loot_overkill_item_armor_big_probability 2 "Probability of random big armor spawning as loot during overkill."
+set g_random_loot_overkill_item_armor_mega_probability 1 "Probability of random mega armor spawning as loot during overkill."
+set g_random_loot_overkill_weapon_hmg_probability 1 "Probability of random HMG spawning as loot during overkill."
+set g_random_loot_overkill_weapon_rpc_probability 1 "Probability of random RPC spawning as loot during overkill."