]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/fruitiex/animations'
authorRudolf Polzer <divverent@xonotic.org>
Sun, 9 Oct 2011 14:18:34 +0000 (16:18 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Sun, 9 Oct 2011 14:18:34 +0000 (16:18 +0200)
80 files changed:
balance25.cfg
balanceFruit.cfg
balanceLeeStricklin.cfg
balanceXonotic.cfg
balancetZork.cfg
defaultXonotic.cfg
effectinfo.txt
models/gibs/chunk.mdl_0.tga [new file with mode: 0644]
models/gibs/gib1.md3 [deleted file]
models/gibs/gib1.mdl [deleted file]
models/gibs/gib2.md3 [deleted file]
models/gibs/gib2.mdl [deleted file]
models/gibs/gib3.md3 [deleted file]
models/gibs/gib3.mdl [deleted file]
models/gibs/gib4.md3 [deleted file]
models/gibs/gib5.md3 [deleted file]
models/gibs/gib6.md3 [deleted file]
qcsrc/Makefile
qcsrc/client/Main.qc
qcsrc/client/csqc_builtins.qc
qcsrc/client/csqc_constants.qc
qcsrc/client/hud.qc
qcsrc/client/hud_config.qc
qcsrc/client/projectile.qc
qcsrc/client/tuba.qc
qcsrc/common/constants.qh
qcsrc/common/gamecommand.qc
qcsrc/common/urllib.qc
qcsrc/common/urllib.qh
qcsrc/menu/mbuiltin.qh
qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c
qcsrc/menu/xonotic/dialog_settings_audio.c
qcsrc/menu/xonotic/serverlist.c
qcsrc/menu/xonotic/util.qc
qcsrc/menu/xonotic/util.qh
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/cl_weapons.qc
qcsrc/server/cl_weaponsystem.qc
qcsrc/server/defs.qh
qcsrc/server/extensions.qh
qcsrc/server/g_hook.qc
qcsrc/server/g_triggers.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/monsters/m_monsters.qc
qcsrc/server/mutators/mutator_invincibleproj.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator_nix.qc
qcsrc/server/mutators/mutators.qh
qcsrc/server/playerstats.qc
qcsrc/server/playerstats.qh
qcsrc/server/progs.src
qcsrc/server/scores.qc
qcsrc/server/sv_main.qc
qcsrc/server/t_teleporters.qc
qcsrc/server/tturrets/units/unit_ewheel.qc
qcsrc/server/tturrets/units/unit_walker.qc
qcsrc/server/vehicles/vehicles.qc
qcsrc/server/w_common.qc
qcsrc/server/w_crylink.qc
qcsrc/server/w_electro.qc
qcsrc/server/w_fireball.qc
qcsrc/server/w_grenadelauncher.qc
qcsrc/server/w_hagar.qc
qcsrc/server/w_hlac.qc
qcsrc/server/w_hook.qc
qcsrc/server/w_minelayer.qc
qcsrc/server/w_minstanex.qc
qcsrc/server/w_nex.qc
qcsrc/server/w_rifle.qc
qcsrc/server/w_rocketlauncher.qc
qcsrc/server/w_seeker.qc
qcsrc/server/w_shotgun.qc
qcsrc/server/w_tuba.qc
qcsrc/server/w_uzi.qc
qcsrc/warpzonelib/server.qc
scripts/gibs.shader [new file with mode: 0644]
scripts/nutsandbolts.shader [deleted file]
update-cvarcount.sh

index 81381f4638cbc21084ac14e196e476554331e121..91db8f2386099ce8bd131b13cb2ce1d602fc87be 100644 (file)
@@ -155,6 +155,13 @@ set g_balance_firetransfer_time 0.9
 set g_balance_firetransfer_damage 0.8
 set g_throughfloor_damage 1
 set g_throughfloor_force 1
+set g_projectiles_damage 2
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions 
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
 set g_projectiles_newton_style 2
 // possible values:
 // 0: absolute velocity projectiles (like Quake)
@@ -179,6 +186,13 @@ set g_balance_falldamage_minspeed 1400
 set g_balance_falldamage_factor 0.15
 set g_balance_falldamage_maxdamage 25
 set g_balance_damagepush_speedfactor 0
+set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
+set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
+set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
+set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
+set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
+set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
 // }}}
 
 // {{{ powerups
@@ -209,6 +223,7 @@ set g_balance_grapplehook_length_min 50
 set g_balance_grapplehook_stretch 50
 set g_balance_grapplehook_airfriction 0.2
 set g_balance_grapplehook_health 130
+set g_balance_grapplehook_damagedbycontents 0
 // }}}
 
 // {{{ weapon properties
@@ -258,11 +273,15 @@ set g_balance_shotgun_primary_ammo 1
 set g_balance_shotgun_primary_speed 12000
 set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
 set g_balance_shotgun_secondary 1
-set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
-set g_balance_shotgun_secondary_melee_range 60
-set g_balance_shotgun_secondary_melee_swing 50
-set g_balance_shotgun_secondary_melee_time 0.1
+set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
+set g_balance_shotgun_secondary_melee_range 120
+set g_balance_shotgun_secondary_melee_swing_side 120
+set g_balance_shotgun_secondary_melee_swing_up 30
+set g_balance_shotgun_secondary_melee_time 0.15
+set g_balance_shotgun_secondary_melee_traces 10
 set g_balance_shotgun_secondary_melee_no_doubleslap 1
+set g_balance_shotgun_secondary_melee_nonplayerdamage 0
+set g_balance_shotgun_secondary_melee_multihit 1
 set g_balance_shotgun_secondary_damage 115
 set g_balance_shotgun_secondary_force 150
 set g_balance_shotgun_secondary_refire 1.1
@@ -406,6 +425,7 @@ set g_balance_electro_secondary_animtime 0.3
 set g_balance_electro_secondary_ammo 2
 set g_balance_electro_secondary_health 5
 set g_balance_electro_secondary_damageforcescale 4
+set g_balance_electro_secondary_damagedbycontents 0
 set g_balance_electro_secondary_count 1
 set g_balance_electro_secondary_bouncefactor 0.5
 set g_balance_electro_secondary_bouncestop 0.075
@@ -512,7 +532,7 @@ set g_balance_nex_charge_rate 0.1
 set g_balance_nex_charge_animlimit 0.5
 set g_balance_nex_charge_limit 0.5
 set g_balance_nex_charge_rot_rate 0
-set g_balance_nex_charge_rot_pause 0 // Dont rot down untill this long after release of charge button
+set g_balance_nex_charge_rot_pause 0 // Dont rot down until this long after release of charge button
 set g_balance_nex_charge_shot_multiplier 0.5
 set g_balance_nex_charge_velocity_rate 0.2
 set g_balance_nex_charge_minspeed 400
@@ -533,6 +553,8 @@ set g_balance_minstanex_reload_time 2
 set g_balance_hagar_primary_damage 37
 set g_balance_hagar_primary_edgedamage 15
 set g_balance_hagar_primary_force 100
+set g_balance_hagar_primary_health 0
+set g_balance_hagar_primary_damageforcescale 0
 set g_balance_hagar_primary_radius 65
 set g_balance_hagar_primary_spread 0.010
 set g_balance_hagar_primary_speed 3000
@@ -548,9 +570,13 @@ set g_balance_hagar_secondary_load_max 4
 set g_balance_hagar_secondary_load_hold 0
 set g_balance_hagar_secondary_load_releasedeath 1
 set g_balance_hagar_secondary_load_abort 1
+set g_balance_hagar_secondary_load_linkexplode 0
+set g_balance_hagar_secondary_load_animtime 0.2
 set g_balance_hagar_secondary_damage 37
 set g_balance_hagar_secondary_edgedamage 15
 set g_balance_hagar_secondary_force 100
+set g_balance_hagar_secondary_health 0
+set g_balance_hagar_secondary_damageforcescale 0
 set g_balance_hagar_secondary_radius 65
 set g_balance_hagar_secondary_spread 0.015
 set g_balance_hagar_secondary_speed 1400
@@ -615,6 +641,8 @@ set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
 set g_balance_hook_secondary_animtime 0.3 // good shoot anim
 set g_balance_hook_secondary_power 3 // effect behaves like a square function
 set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+set g_balance_hook_secondary_health 0
+set g_balance_hook_secondary_damageforcescale 0 
 // }}}
 // {{{ hlac
 set g_balance_hlac_primary_spread_min 0.01
index 9e73743e9d6bf5a695c860dad883467d0c4ad8f3..fac3faa206b66788ade62a556840ddd1075e4167 100644 (file)
@@ -155,6 +155,13 @@ set g_balance_firetransfer_time 0.9
 set g_balance_firetransfer_damage 0.8
 set g_throughfloor_damage 0.7
 set g_throughfloor_force 0.8
+set g_projectiles_damage 2
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions 
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
 set g_projectiles_newton_style 2
 // possible values:
 // 0: absolute velocity projectiles (like Quake)
@@ -179,6 +186,13 @@ set g_balance_falldamage_minspeed 800
 set g_balance_falldamage_factor 0.20
 set g_balance_falldamage_maxdamage 15
 set g_balance_damagepush_speedfactor 2.5
+set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
+set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
+set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
+set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
+set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
+set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
 // }}}
 
 // {{{ powerups
@@ -209,6 +223,7 @@ set g_balance_grapplehook_length_min 50
 set g_balance_grapplehook_stretch 50
 set g_balance_grapplehook_airfriction 0.2
 set g_balance_grapplehook_health 130
+set g_balance_grapplehook_damagedbycontents 0
 // }}}
 
 // {{{ weapon properties
@@ -258,11 +273,15 @@ set g_balance_shotgun_primary_ammo 1
 set g_balance_shotgun_primary_speed 12000
 set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
 set g_balance_shotgun_secondary 1
-set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
-set g_balance_shotgun_secondary_melee_range 85
-set g_balance_shotgun_secondary_melee_swing 50
-set g_balance_shotgun_secondary_melee_time 0.1
-set g_balance_shotgun_secondary_melee_no_doubleslap 0
+set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
+set g_balance_shotgun_secondary_melee_range 120
+set g_balance_shotgun_secondary_melee_swing_side 120
+set g_balance_shotgun_secondary_melee_swing_up 30
+set g_balance_shotgun_secondary_melee_time 0.15
+set g_balance_shotgun_secondary_melee_traces 10
+set g_balance_shotgun_secondary_melee_no_doubleslap 1
+set g_balance_shotgun_secondary_melee_nonplayerdamage 0
+set g_balance_shotgun_secondary_melee_multihit 1
 set g_balance_shotgun_secondary_damage 110
 set g_balance_shotgun_secondary_force 150
 set g_balance_shotgun_secondary_refire 1.1
@@ -406,6 +425,7 @@ set g_balance_electro_secondary_animtime 0.2
 set g_balance_electro_secondary_ammo 2
 set g_balance_electro_secondary_health 10
 set g_balance_electro_secondary_damageforcescale 4
+set g_balance_electro_secondary_damagedbycontents 0
 set g_balance_electro_secondary_count 3
 set g_balance_electro_secondary_bouncefactor 0.5
 set g_balance_electro_secondary_bouncestop 0.075
@@ -533,6 +553,8 @@ set g_balance_minstanex_reload_time 2
 set g_balance_hagar_primary_damage 14
 set g_balance_hagar_primary_edgedamage 6
 set g_balance_hagar_primary_force 70
+set g_balance_hagar_primary_health 0
+set g_balance_hagar_primary_damageforcescale 0
 set g_balance_hagar_primary_radius 110
 set g_balance_hagar_primary_spread 0.1
 set g_balance_hagar_primary_speed 1800
@@ -548,9 +570,13 @@ set g_balance_hagar_secondary_load_max 4
 set g_balance_hagar_secondary_load_hold 0
 set g_balance_hagar_secondary_load_releasedeath 1
 set g_balance_hagar_secondary_load_abort 1
+set g_balance_hagar_secondary_load_linkexplode 0
+set g_balance_hagar_secondary_load_animtime 0.2
 set g_balance_hagar_secondary_damage 14 // default for _load: 32
 set g_balance_hagar_secondary_edgedamage 6 // default for _load: 10
 set g_balance_hagar_secondary_force 70 // default for _load: 160
+set g_balance_hagar_secondary_health 0
+set g_balance_hagar_secondary_damageforcescale 0
 set g_balance_hagar_secondary_radius 125
 set g_balance_hagar_secondary_spread 0.15 // default for _load: 0.08
 set g_balance_hagar_secondary_speed 1800
@@ -615,6 +641,8 @@ set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
 set g_balance_hook_secondary_animtime 0.2 // good shoot anim
 set g_balance_hook_secondary_power 3 // effect behaves like a square function
 set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+set g_balance_hook_secondary_health 0
+set g_balance_hook_secondary_damageforcescale 0 
 // }}}
 // {{{ hlac
 set g_balance_hlac_primary_spread_min 0.01
index b73360f204f479af25598a4ecb83559a3abd4a94..57af50893caa74aa1b5d08b26694be026ffebb27 100644 (file)
@@ -155,6 +155,13 @@ set g_balance_firetransfer_time 0.9
 set g_balance_firetransfer_damage 0.8
 set g_throughfloor_damage 0.4
 set g_throughfloor_force 0.7
+set g_projectiles_damage 2
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions 
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
 set g_projectiles_newton_style 2
 // possible values:
 // 0: absolute velocity projectiles (like Quake)
@@ -179,6 +186,13 @@ set g_balance_falldamage_minspeed 1400
 set g_balance_falldamage_factor 0.15
 set g_balance_falldamage_maxdamage 25
 set g_balance_damagepush_speedfactor 0
+set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
+set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
+set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
+set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
+set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
+set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
 // }}}
 
 // {{{ powerups
@@ -209,6 +223,7 @@ set g_balance_grapplehook_length_min 50
 set g_balance_grapplehook_stretch 50
 set g_balance_grapplehook_airfriction 0.2
 set g_balance_grapplehook_health 130
+set g_balance_grapplehook_damagedbycontents 0
 // }}}
 
 // {{{ weapon properties
@@ -258,11 +273,15 @@ set g_balance_shotgun_primary_ammo 1
 set g_balance_shotgun_primary_speed 12000
 set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
 set g_balance_shotgun_secondary 1
-set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
-set g_balance_shotgun_secondary_melee_range 85
-set g_balance_shotgun_secondary_melee_swing 50
-set g_balance_shotgun_secondary_melee_time 0.1
+set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
+set g_balance_shotgun_secondary_melee_range 120
+set g_balance_shotgun_secondary_melee_swing_side 120
+set g_balance_shotgun_secondary_melee_swing_up 30
+set g_balance_shotgun_secondary_melee_time 0.15
+set g_balance_shotgun_secondary_melee_traces 10
 set g_balance_shotgun_secondary_melee_no_doubleslap 1
+set g_balance_shotgun_secondary_melee_nonplayerdamage 0
+set g_balance_shotgun_secondary_melee_multihit 1
 set g_balance_shotgun_secondary_damage 84
 set g_balance_shotgun_secondary_force 147
 set g_balance_shotgun_secondary_refire 1.1
@@ -406,6 +425,7 @@ set g_balance_electro_secondary_animtime 0.3
 set g_balance_electro_secondary_ammo 2
 set g_balance_electro_secondary_health 10
 set g_balance_electro_secondary_damageforcescale 4
+set g_balance_electro_secondary_damagedbycontents 0
 set g_balance_electro_secondary_count 3
 set g_balance_electro_secondary_bouncefactor 0.5
 set g_balance_electro_secondary_bouncestop 0.075
@@ -512,7 +532,7 @@ set g_balance_nex_charge_rate 0.1
 set g_balance_nex_charge_animlimit 0.5
 set g_balance_nex_charge_limit 0.5
 set g_balance_nex_charge_rot_rate 0
-set g_balance_nex_charge_rot_pause 0 // Dont rot down untill this long after release of charge button
+set g_balance_nex_charge_rot_pause 0 // Dont rot down until this long after release of charge button
 set g_balance_nex_charge_shot_multiplier 0
 set g_balance_nex_charge_velocity_rate 0.2
 set g_balance_nex_charge_minspeed ""
@@ -533,6 +553,8 @@ set g_balance_minstanex_reload_time 2
 set g_balance_hagar_primary_damage 43
 set g_balance_hagar_primary_edgedamage 15
 set g_balance_hagar_primary_force 94
+set g_balance_hagar_primary_health 0
+set g_balance_hagar_primary_damageforcescale 0
 set g_balance_hagar_primary_radius 70
 set g_balance_hagar_primary_spread 0.010
 set g_balance_hagar_primary_speed 3000
@@ -548,9 +570,13 @@ set g_balance_hagar_secondary_load_max 4
 set g_balance_hagar_secondary_load_hold 0
 set g_balance_hagar_secondary_load_releasedeath 1
 set g_balance_hagar_secondary_load_abort 1
+set g_balance_hagar_secondary_load_linkexplode 0
+set g_balance_hagar_secondary_load_animtime 0.2
 set g_balance_hagar_secondary_damage 43
 set g_balance_hagar_secondary_edgedamage 15
 set g_balance_hagar_secondary_force 100
+set g_balance_hagar_secondary_health 0
+set g_balance_hagar_secondary_damageforcescale 0
 set g_balance_hagar_secondary_radius 70
 set g_balance_hagar_secondary_spread 0.015
 set g_balance_hagar_secondary_speed 1400
@@ -615,6 +641,8 @@ set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
 set g_balance_hook_secondary_animtime 0.3 // good shoot anim
 set g_balance_hook_secondary_power 3 // effect behaves like a square function
 set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+set g_balance_hook_secondary_health 0
+set g_balance_hook_secondary_damageforcescale 0 
 // }}}
 // {{{ hlac
 set g_balance_hlac_primary_spread_min 0.01
index 182e66cb1ccb486be92967163d2036a128321033..86e36f8278992a71af6658a4b85624e0a400931b 100644 (file)
@@ -153,8 +153,15 @@ set g_weaponforcefactor 1 "weapon force multiplier"
 set g_weaponspreadfactor 1 "weapon spread multiplier"
 set g_balance_firetransfer_time 0.9
 set g_balance_firetransfer_damage 0.8
-set g_throughfloor_damage 0.4
-set g_throughfloor_force 0.7
+set g_throughfloor_damage 0.75
+set g_throughfloor_force 0.75
+set g_projectiles_damage 2
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions 
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
 set g_projectiles_newton_style 2
 // possible values:
 // 0: absolute velocity projectiles (like Quake)
@@ -179,6 +186,13 @@ set g_balance_falldamage_minspeed 900
 set g_balance_falldamage_factor 0.20
 set g_balance_falldamage_maxdamage 40
 set g_balance_damagepush_speedfactor 2.5
+set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
+set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
+set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
+set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
+set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
+set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
 // }}}
 
 // {{{ powerups
@@ -208,14 +222,15 @@ set g_balance_grapplehook_force_rubber_overstretch 1000
 set g_balance_grapplehook_length_min 50
 set g_balance_grapplehook_stretch 50
 set g_balance_grapplehook_airfriction 0.2
-set g_balance_grapplehook_health 130
+set g_balance_grapplehook_health 50
+set g_balance_grapplehook_damagedbycontents 1
 // }}}
 
 // {{{ weapon properties
 // {{{ laser
 set g_balance_laser_primary_damage 25
 set g_balance_laser_primary_edgedamage 12.5
-set g_balance_laser_primary_force 250
+set g_balance_laser_primary_force 300
 set g_balance_laser_primary_radius 70
 set g_balance_laser_primary_speed 6000
 set g_balance_laser_primary_spread 0
@@ -225,7 +240,7 @@ set g_balance_laser_primary_lifetime 5
 set g_balance_laser_primary_shotangle 0
 set g_balance_laser_primary_delay 0
 set g_balance_laser_primary_gauntlet 0
-set g_balance_laser_primary_force_zscale 1.5
+set g_balance_laser_primary_force_zscale 1.25
 set g_balance_laser_primary_force_velocitybias 0
 set g_balance_laser_primary_force_other_scale 1
 set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
@@ -260,12 +275,16 @@ set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
 set g_balance_shotgun_secondary 1
 set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
 set g_balance_shotgun_secondary_melee_range 120
-set g_balance_shotgun_secondary_melee_swing 50
-set g_balance_shotgun_secondary_melee_time 0.1
+set g_balance_shotgun_secondary_melee_swing_side 120
+set g_balance_shotgun_secondary_melee_swing_up 30
+set g_balance_shotgun_secondary_melee_time 0.15
+set g_balance_shotgun_secondary_melee_traces 10
 set g_balance_shotgun_secondary_melee_no_doubleslap 1
-set g_balance_shotgun_secondary_damage 110
+set g_balance_shotgun_secondary_melee_nonplayerdamage 40
+set g_balance_shotgun_secondary_melee_multihit 1
+set g_balance_shotgun_secondary_damage 100
 set g_balance_shotgun_secondary_force 200
-set g_balance_shotgun_secondary_refire 1.1
+set g_balance_shotgun_secondary_refire 1.25
 set g_balance_shotgun_secondary_animtime 1
 set g_balance_shotgun_reload_ammo 0 //default: 5
 set g_balance_shotgun_reload_time 2
@@ -273,14 +292,14 @@ set g_balance_shotgun_reload_time 2
 // {{{ uzi
 set g_balance_uzi_mode 1                               // Activates varible spread for sustained & burst mode secondary
 set g_balance_uzi_spread_min 0.02
-set g_balance_uzi_spread_max 0.06
+set g_balance_uzi_spread_max 0.05
 set g_balance_uzi_spread_add 0.012
 
 set g_balance_uzi_burst 3                              // # of bullets in a burst (if set to 2 or more)
 set g_balance_uzi_burst_animtime 0.3
 set g_balance_uzi_burst_refire 0.06            // refire between burst bullets
 set g_balance_uzi_burst_refire2 0.45   // refire after burst
-set g_balance_uzi_burst_spread 0.03
+set g_balance_uzi_burst_spread 0.02
 set g_balance_uzi_burst_damage 25              
 set g_balance_uzi_burst_force 20
 set g_balance_uzi_burst_ammo 3
@@ -289,12 +308,12 @@ set g_balance_uzi_first 1
 set g_balance_uzi_first_damage 14
 set g_balance_uzi_first_force 5
 set g_balance_uzi_first_spread 0.03
-set g_balance_uzi_first_refire 0.4
+set g_balance_uzi_first_refire 0.2
 set g_balance_uzi_first_ammo 1
 
-set g_balance_uzi_sustained_damage 12
+set g_balance_uzi_sustained_damage 10 // 100 dps
 set g_balance_uzi_sustained_force 5
-set g_balance_uzi_sustained_spread 0.04
+set g_balance_uzi_sustained_spread 0.03
 set g_balance_uzi_sustained_refire 0.1
 set g_balance_uzi_sustained_ammo 1
 
@@ -319,7 +338,7 @@ set g_balance_grenadelauncher_primary_lifetime2 1
 set g_balance_grenadelauncher_primary_refire 0.8
 set g_balance_grenadelauncher_primary_animtime 0.3
 set g_balance_grenadelauncher_primary_ammo 2
-set g_balance_grenadelauncher_primary_health 0
+set g_balance_grenadelauncher_primary_health 15
 set g_balance_grenadelauncher_primary_damageforcescale 0
 set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
 
@@ -338,7 +357,7 @@ set g_balance_grenadelauncher_secondary_lifetime_stick 0
 set g_balance_grenadelauncher_secondary_refire 0.7
 set g_balance_grenadelauncher_secondary_animtime 0.3
 set g_balance_grenadelauncher_secondary_ammo 2
-set g_balance_grenadelauncher_secondary_health 0
+set g_balance_grenadelauncher_secondary_health 30
 set g_balance_grenadelauncher_secondary_damageforcescale 4
 set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
 
@@ -375,8 +394,8 @@ set g_balance_minelayer_reload_time 2
 // }}}
 // {{{ electro
 set g_balance_electro_lightning 0
-set g_balance_electro_primary_damage 55
-set g_balance_electro_primary_edgedamage 27.5
+set g_balance_electro_primary_damage 40
+set g_balance_electro_primary_edgedamage 20
 set g_balance_electro_primary_force 200
 set g_balance_electro_primary_force_up 0
 set g_balance_electro_primary_radius 100
@@ -406,11 +425,12 @@ set g_balance_electro_secondary_animtime 0.2
 set g_balance_electro_secondary_ammo 2
 set g_balance_electro_secondary_health 5
 set g_balance_electro_secondary_damageforcescale 4
+set g_balance_electro_secondary_damagedbycontents 1
 set g_balance_electro_secondary_count 3
 set g_balance_electro_secondary_bouncefactor 0.4
 set g_balance_electro_secondary_bouncestop 0.05
-set g_balance_electro_combo_damage 40
-set g_balance_electro_combo_edgedamage 20
+set g_balance_electro_combo_damage 50
+set g_balance_electro_combo_edgedamage 25
 set g_balance_electro_combo_force 120
 set g_balance_electro_combo_radius 175
 set g_balance_electro_combo_comboradius 275
@@ -512,7 +532,7 @@ set g_balance_nex_charge_rate 0.4
 set g_balance_nex_charge_animlimit 0.5
 set g_balance_nex_charge_limit 1
 set g_balance_nex_charge_rot_rate 0
-set g_balance_nex_charge_rot_pause 0 // Dont rot down untill this long after release of charge button
+set g_balance_nex_charge_rot_pause 0 // Dont rot down until this long after release of charge button
 set g_balance_nex_charge_shot_multiplier 0
 set g_balance_nex_charge_velocity_rate 0
 set g_balance_nex_charge_minspeed 400
@@ -532,12 +552,14 @@ set g_balance_minstanex_reload_time 2
 // {{{ hagar
 set g_balance_hagar_primary_damage 25
 set g_balance_hagar_primary_edgedamage 12.5
-set g_balance_hagar_primary_force 50
-set g_balance_hagar_primary_radius 60
+set g_balance_hagar_primary_force 100
+set g_balance_hagar_primary_health 15
+set g_balance_hagar_primary_damageforcescale 0
+set g_balance_hagar_primary_radius 65
 set g_balance_hagar_primary_spread 0.04
-set g_balance_hagar_primary_speed 2000
+set g_balance_hagar_primary_speed 2200
 set g_balance_hagar_primary_lifetime 5
-set g_balance_hagar_primary_refire 0.15
+set g_balance_hagar_primary_refire 0.16667 // 6 rockets per second
 set g_balance_hagar_primary_ammo 1
 set g_balance_hagar_secondary 1
 set g_balance_hagar_secondary_load 1
@@ -545,14 +567,18 @@ set g_balance_hagar_secondary_load_speed 0.5
 set g_balance_hagar_secondary_load_spread 0.075
 set g_balance_hagar_secondary_load_spread_bias 0.5
 set g_balance_hagar_secondary_load_max 4
-set g_balance_hagar_secondary_load_hold 1
+set g_balance_hagar_secondary_load_hold 4
 set g_balance_hagar_secondary_load_releasedeath 0
 set g_balance_hagar_secondary_load_abort 1
+set g_balance_hagar_secondary_load_linkexplode 0
+set g_balance_hagar_secondary_load_animtime 0.2
 set g_balance_hagar_secondary_damage 40
 set g_balance_hagar_secondary_edgedamage 20
-set g_balance_hagar_secondary_force 50
+set g_balance_hagar_secondary_force 75
+set g_balance_hagar_secondary_health 15
+set g_balance_hagar_secondary_damageforcescale 0
 set g_balance_hagar_secondary_radius 80
-set g_balance_hagar_secondary_spread 0.06
+set g_balance_hagar_secondary_spread 0.05
 set g_balance_hagar_secondary_speed 2000
 set g_balance_hagar_secondary_lifetime_min 10
 set g_balance_hagar_secondary_lifetime_rand 0
@@ -573,7 +599,7 @@ set g_balance_rocketlauncher_lifetime 10
 set g_balance_rocketlauncher_refire 1.1
 set g_balance_rocketlauncher_animtime 0.3
 set g_balance_rocketlauncher_ammo 4
-set g_balance_rocketlauncher_health 0 // 30 // 5 hitpoints above maximum laser value -- this way lasers can't blow it up, but grenadelauncher still can most the time.
+set g_balance_rocketlauncher_health 30 // 30 // 5 hitpoints above maximum laser value -- this way lasers can't blow it up, but grenadelauncher still can most the time.
 set g_balance_rocketlauncher_damageforcescale 1 // low damage force scale so that it can still be affected by other hits, but not so much that it does a 90 degree turn
 set g_balance_rocketlauncher_detonatedelay 0.05 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
 set g_balance_rocketlauncher_guiderate 110 // max degrees per second
@@ -591,7 +617,7 @@ set g_balance_rocketlauncher_reload_time 2
 // {{{ porto
 set g_balance_porto_primary_refire 1.5
 set g_balance_porto_primary_animtime 0.3
-set g_balance_porto_primary_speed 5000
+set g_balance_porto_primary_speed 1000
 set g_balance_porto_primary_lifetime 5
 set g_balance_portal_health 200 // these get recharged whenever the portal is used
 set g_balance_portal_lifetime 15 // these get recharged whenever the portal is used
@@ -607,7 +633,7 @@ set g_balance_hook_secondary_damage 25 // not much
 set g_balance_hook_secondary_edgedamage 5 // not much
 set g_balance_hook_secondary_radius 500 // LOTS
 set g_balance_hook_secondary_force -2000 // LOTS
-set g_balance_hook_secondary_ammo 50 // a whole pack
+set g_balance_hook_secondary_ammo 30 // a whole pack
 set g_balance_hook_secondary_lifetime 5 // infinite
 set g_balance_hook_secondary_speed 0 // not much throwing
 set g_balance_hook_secondary_gravity 5 // fast falling
@@ -615,6 +641,8 @@ set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
 set g_balance_hook_secondary_animtime 0.3 // good shoot anim
 set g_balance_hook_secondary_power 3 // effect behaves like a square function
 set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+set g_balance_hook_secondary_health 15
+set g_balance_hook_secondary_damageforcescale 0 
 // }}}
 // {{{ hlac // TO BE REMOVED
 set g_balance_hlac_primary_spread_min 0.01
index fd229feb9f394aa8157e749d210ab8cd0b751e57..b7fd9641db5d765729f1c7b86e8f76d225e2e43b 100644 (file)
@@ -155,6 +155,13 @@ set g_balance_firetransfer_time 0.9
 set g_balance_firetransfer_damage 0.8
 set g_throughfloor_damage 0.5
 set g_throughfloor_force 0.7
+set g_projectiles_damage 2
+// possible values:
+// -2: absolutely no damage to projectiles (no exceptions)
+// -1: no damage other than the exceptions (electro combo, hagar join explode, minelayer mines)
+// 0: only damage from contents (lava/slime) or exceptions 
+// 1: only self damage or damage from contents or exceptions
+// 2: allow all damage to projectiles normally
 set g_projectiles_newton_style 2
 // possible values:
 // 0: absolute velocity projectiles (like Quake)
@@ -179,6 +186,13 @@ set g_balance_falldamage_minspeed 800
 set g_balance_falldamage_factor 0.02 // maxspeed = minspeed + maxdamage / factor = 4550
 set g_balance_falldamage_maxdamage 75
 set g_balance_damagepush_speedfactor 0
+set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
+set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
+set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning 
+set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
+set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
+set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
 // }}}
 
 // {{{ powerups
@@ -209,6 +223,7 @@ set g_balance_grapplehook_length_min 50
 set g_balance_grapplehook_stretch 50
 set g_balance_grapplehook_airfriction 0.2
 set g_balance_grapplehook_health 130
+set g_balance_grapplehook_damagedbycontents 0
 // }}}
 
 // {{{ weapon properties
@@ -258,11 +273,15 @@ set g_balance_shotgun_primary_ammo 1
 set g_balance_shotgun_primary_speed 12000
 set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
 set g_balance_shotgun_secondary 1
-set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
-set g_balance_shotgun_secondary_melee_range 85
-set g_balance_shotgun_secondary_melee_swing 50
-set g_balance_shotgun_secondary_melee_time 0.1
+set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
+set g_balance_shotgun_secondary_melee_range 120
+set g_balance_shotgun_secondary_melee_swing_side 120
+set g_balance_shotgun_secondary_melee_swing_up 30
+set g_balance_shotgun_secondary_melee_time 0.15
+set g_balance_shotgun_secondary_melee_traces 10
 set g_balance_shotgun_secondary_melee_no_doubleslap 1
+set g_balance_shotgun_secondary_melee_nonplayerdamage 0
+set g_balance_shotgun_secondary_melee_multihit 1
 set g_balance_shotgun_secondary_damage 110
 set g_balance_shotgun_secondary_force 150
 set g_balance_shotgun_secondary_refire 1.1
@@ -406,6 +425,7 @@ set g_balance_electro_secondary_animtime 0.15
 set g_balance_electro_secondary_ammo 2
 set g_balance_electro_secondary_health 10
 set g_balance_electro_secondary_damageforcescale 2
+set g_balance_electro_secondary_damagedbycontents 0
 set g_balance_electro_secondary_count 3
 set g_balance_electro_secondary_bouncefactor 0.5
 set g_balance_electro_secondary_bouncestop 0.075
@@ -511,7 +531,7 @@ set g_balance_nex_charge_rate 0.35
 set g_balance_nex_charge_animlimit 0.5
 set g_balance_nex_charge_limit 0.5
 set g_balance_nex_charge_rot_rate 0.1
-set g_balance_nex_charge_rot_pause 1 // Dont rot down untill this long after release of charge button
+set g_balance_nex_charge_rot_pause 1 // Dont rot down until this long after release of charge button
 set g_balance_nex_charge_shot_multiplier 0
 set g_balance_nex_charge_velocity_rate 0
 set g_balance_nex_charge_minspeed 400
@@ -532,6 +552,8 @@ set g_balance_minstanex_reload_time 2
 set g_balance_hagar_primary_damage 25
 set g_balance_hagar_primary_edgedamage 5
 set g_balance_hagar_primary_force 70
+set g_balance_hagar_primary_health 0
+set g_balance_hagar_primary_damageforcescale 0
 set g_balance_hagar_primary_radius 60
 set g_balance_hagar_primary_spread 0.010
 set g_balance_hagar_primary_speed 2500
@@ -547,9 +569,13 @@ set g_balance_hagar_secondary_load_max 4
 set g_balance_hagar_secondary_load_hold 0
 set g_balance_hagar_secondary_load_releasedeath 1
 set g_balance_hagar_secondary_load_abort 1
+set g_balance_hagar_secondary_load_linkexplode 0
+set g_balance_hagar_secondary_load_animtime 0.2
 set g_balance_hagar_secondary_damage 30
 set g_balance_hagar_secondary_edgedamage 15
 set g_balance_hagar_secondary_force 50
+set g_balance_hagar_secondary_health 0
+set g_balance_hagar_secondary_damageforcescale 0
 set g_balance_hagar_secondary_radius 65
 set g_balance_hagar_secondary_spread 0.015
 set g_balance_hagar_secondary_speed 1400
@@ -614,6 +640,8 @@ set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
 set g_balance_hook_secondary_animtime 0.3 // good shoot anim
 set g_balance_hook_secondary_power 3 // effect behaves like a square function
 set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+set g_balance_hook_secondary_health 0
+set g_balance_hook_secondary_damageforcescale 0 
 // }}}
 // {{{ hlac
 set g_balance_hlac_primary_spread_min 0.01
index 3f1ca3f53b0066fe2e1d3461f6faeb3218ad12ce..8ac7df977426a0fad078977301ddd4fee0f89559 100644 (file)
@@ -53,6 +53,8 @@ alias asay_drop "say_team (%l) dropped %w ; impulse 17"
 alias +hook +button6
 alias -hook -button6
 alias use "impulse 21"
+alias +use use // always send that impulse AND press the key (+use is engine internal command and executes anyway)
+set cl_newusekeysupported 1 // indicates that we always send the use impulse too, so they do not need to be synthesized
 alias ready "cmd ready"
 alias lockteams "sv_cmd lockteams"
 alias unlockteams "sv_cmd unlockteams"
@@ -536,7 +538,6 @@ seta g_maplist_selectrandom 0       "if 1, a random map will be chosen as next map - D
 seta g_maplist_shuffle 1       "new randomization method: like selectrandom, but avoid playing the same maps in short succession. This works by taking out the first element and inserting it into g_maplist with a bias to the end of the list"
 set g_maplist_check_waypoints 0        "when 1, maps are skipped if there currently are bots, but the map has no waypoints"
 set samelevel 0 "when 1, always play the same level over and over again"
-set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
 
 set g_cloaked 0 "display all players mostly invisible"
 set g_player_alpha 1
@@ -552,6 +553,7 @@ alias clearmap "disconnect"
 
 set g_grappling_hook 0 "let players spawn with the grappling hook which allows them to pull themselves up"
 
+set g_invincible_projectiles 0 "set to 1 to disable any damage to projectiles in all balance configs, regardless of g_projectiles_damage"
 set g_dodging 0 "set to 1 to enable dodging in games"
 set g_rocket_flying 0 "set to 1 to enable rocket flying in all balance configs"
 
@@ -1039,8 +1041,7 @@ bind MWHEELDOWN weapprev
 bind r reload
 bind BACKSPACE dropweapon
 bind g dropweapon
-// TODO change this to "use" once we can
-bind f +use
+bind f use
 
 // misc
 bind e +hook
@@ -2160,11 +2161,20 @@ set g_playerstats_debug 0 "when 1, player stats are dumped to the console too"
 
 // create this cvar in case the engine did not
 set snd_soundradius 1200
+seta menu_snd_attenuation_method 1 "Use exponential instead of linear falloff for sound attenuation"
+alias snd_attenuation_method_0 "set menu_snd_attenuation_method 0; set snd_soundradius 1200; set snd_attenuation_exponent 1; set snd_attenuation_decibel 0" // Quake default
+alias snd_attenuation_method_1 "set menu_snd_attenuation_method 1; set snd_soundradius 2400; set snd_attenuation_exponent 4; set snd_attenuation_decibel 0" // nice approximation for method 2
+alias snd_attenuation_method_2 "set menu_snd_attenuation_method 2; set snd_soundradius 1200; set snd_attenuation_exponent 0; set snd_attenuation_decibel 10" // warning: plays sounds within up to 6000qu
+snd_attenuation_method_1
 
 // declare the channels we use
 seta snd_channel8volume 1 "QuakeC controlled background music volume"
 seta snd_channel9volume 1 "QuakeC controlled ambient sound volume"
 
+// sound randomization
+snd_identicalsoundrandomization_time -0.1
+snd_identicalsoundrandomization_tics    1
+
 // loading screen
 scr_loadingscreen_background 0
 scr_loadingscreen_barcolor "0 0.5 1"
index bf631fb254197ed732145f2538180345fddaea2d..70f5fbb4c6f8fd7f03468ae16cc2e9e7bd80399d 100644 (file)
@@ -1225,7 +1225,7 @@ trailspacing 4
 type static
 color 0xffdf72 0x811200
 tex 48 55
-size 1 2
+size 5 2
 sizeincrease -15
 alpha 100 144 988
 airfriction 8
diff --git a/models/gibs/chunk.mdl_0.tga b/models/gibs/chunk.mdl_0.tga
new file mode 100644 (file)
index 0000000..4f4dd29
Binary files /dev/null and b/models/gibs/chunk.mdl_0.tga differ
diff --git a/models/gibs/gib1.md3 b/models/gibs/gib1.md3
deleted file mode 100644 (file)
index 276982d..0000000
Binary files a/models/gibs/gib1.md3 and /dev/null differ
diff --git a/models/gibs/gib1.mdl b/models/gibs/gib1.mdl
deleted file mode 100644 (file)
index 8f8501c..0000000
Binary files a/models/gibs/gib1.mdl and /dev/null differ
diff --git a/models/gibs/gib2.md3 b/models/gibs/gib2.md3
deleted file mode 100644 (file)
index f5a2f73..0000000
Binary files a/models/gibs/gib2.md3 and /dev/null differ
diff --git a/models/gibs/gib2.mdl b/models/gibs/gib2.mdl
deleted file mode 100644 (file)
index b4b7425..0000000
Binary files a/models/gibs/gib2.mdl and /dev/null differ
diff --git a/models/gibs/gib3.md3 b/models/gibs/gib3.md3
deleted file mode 100644 (file)
index 8a38b42..0000000
Binary files a/models/gibs/gib3.md3 and /dev/null differ
diff --git a/models/gibs/gib3.mdl b/models/gibs/gib3.mdl
deleted file mode 100644 (file)
index 17279df..0000000
Binary files a/models/gibs/gib3.mdl and /dev/null differ
diff --git a/models/gibs/gib4.md3 b/models/gibs/gib4.md3
deleted file mode 100644 (file)
index dd4c5b5..0000000
Binary files a/models/gibs/gib4.md3 and /dev/null differ
diff --git a/models/gibs/gib5.md3 b/models/gibs/gib5.md3
deleted file mode 100644 (file)
index 6a51eb2..0000000
Binary files a/models/gibs/gib5.md3 and /dev/null differ
diff --git a/models/gibs/gib6.md3 b/models/gibs/gib6.md3
deleted file mode 100644 (file)
index 956c902..0000000
Binary files a/models/gibs/gib6.md3 and /dev/null differ
index de44b785c6579a4138b830c447a787b9e3451e38..e2be8a841bac1d411537784bfdcfc01b263a6217 100644 (file)
@@ -27,17 +27,17 @@ qc-recursive: ../menu.dat ../progs.dat ../csprogs.dat
 clean:
        rm -f ../progs.dat ../menu.dat ../csprogs.dat
 
-FILES_CSPROGS = $(shell find client common warpzonelib -type f -not -name fteqcc.log -not -name qc.asm) server/w_*.qc
+FILES_CSPROGS = $(shell find client common warpzonelib -type f -not -name fteqcc.log -not -name qc.asm) $(wildcard server/w_*.qc)
 ../csprogs.dat: $(FILES_CSPROGS)
        @echo make[1]: Entering directory \`$(PWD)/client\'
        cd client && $(FTEQCC) $(FTEQCCFLAGS) $(FTEQCCFLAGS_CSPROGS)
 
-FILES_PROGS = $(shell find server common warpzonelib -type f -not -name fteqcc.log -not -name qc.asm) server/w_*.qc
+FILES_PROGS = $(shell find server common warpzonelib -type f -not -name fteqcc.log -not -name qc.asm) $(wildcard server/w_*.qc)
 ../progs.dat: $(FILES_PROGS)
        @echo make[1]: Entering directory \`$(PWD)/server\'
        cd server && $(FTEQCC) $(FTEQCCFLAGS) $(FTEQCCFLAGS_PROGS)
 
-FILES_MENU = $(shell find menu common warpzonelib -type f -not -name fteqcc.log -not -name qc.asm) server/w_*.qc
+FILES_MENU = $(shell find menu common warpzonelib -type f -not -name fteqcc.log -not -name qc.asm) $(wildcard server/w_*.qc)
 ../menu.dat: $(FILES_MENU)
        @echo make[1]: Entering directory \`$(PWD)/menu\'
        cd menu && $(FTEQCC) $(FTEQCCFLAGS) $(FTEQCCFLAGS_MENU)
index 606123ad1c1d2c2ba4696b3f792bc8eb05a65e89..606bbc92bd6d8d9f0492aed55398d454af10111c 100644 (file)
@@ -595,7 +595,7 @@ void GameCommand(string msg)
         {
             vote_active = 0; // force the panel to disappear right as we have selected the value (to prevent it from fading out in the normal vote panel pos)
             vote_prev = 0;
-            cvar_set("cl_allow_uid2name", "1");
+            localcmd("setreport cl_allow_uid2name 1\n");
             vote_change = -9999;
                        uid2name_dialog = 0;
         }
@@ -610,7 +610,7 @@ void GameCommand(string msg)
         {
             vote_active = 0;
             vote_prev = 0;
-            cvar_set("cl_allow_uid2name", "0");
+            localcmd("setreport cl_allow_uid2name 0\n");
             vote_change = -9999;
                        uid2name_dialog = 0;
         }
index 48012e7a4ccf4a4c4fcd56dac92109dc095dd33f..6ef34f35eab5fa8109e2eda628b889ace10a431d 100644 (file)
@@ -336,3 +336,15 @@ float trace_dphitcontents;
 float trace_networkentity;
 
 string(string search, string replace, string subject) strreplace = #484;
+
+//DP_QC_DIGEST
+//idea: motorsep, Spike
+//DarkPlaces implementation: divVerent
+//builtin definitions:
+string(string digest, string data, ...) digest_hex = #639;
+//description:
+//returns a given hex digest of given data
+//the returned digest is always encoded in hexadecimal
+//only the "MD4" digest is always supported!
+//if the given digest is not supported, string_null is returned
+//the digest string is matched case sensitively, use "MD4", not "md4"!
index e82f4399bdb0ce9921ceabe7bf059ab9ff8673fd..f6e04e7b322e04a87f910c497f0b31a53a167b7b 100644 (file)
@@ -1,4 +1,4 @@
-const entity   NULL                                                    = world;
+#define NULL world
 
 // Mask Constants (set .drawmask on entities; use R_AddEntities to add all entities based on mask)
 const float            MASK_ENGINE                                             = 1;
index 043b5ea98a957b60fd2b32ae7a343b81773102ed..fb47d959858b1bca87eab296b767f860173e8202 100644 (file)
@@ -2471,19 +2471,20 @@ void HUD_Score_Rankings(vector pos, vector mySize, entity me, float team_count)
        entity tm, pl;
 #define SCOREPANEL_MAX_ENTRIES 6
 #define SCOREPANEL_ASPECTRATIO 2
-       const float entries = bound(1, floor(SCOREPANEL_MAX_ENTRIES * mySize_y/mySize_x * SCOREPANEL_ASPECTRATIO), SCOREPANEL_MAX_ENTRIES);
-       const vector fontsize = '1 1 0' * (mySize_y/entries);
+       float entries = bound(1, floor(SCOREPANEL_MAX_ENTRIES * mySize_y/mySize_x * SCOREPANEL_ASPECTRATIO), SCOREPANEL_MAX_ENTRIES);
+       vector fontsize = '1 1 0' * (mySize_y/entries);
 
        vector rgb, score_color;
        rgb = '1 1 1';
        score_color = '1 1 1';
 
-       const float name_size = mySize_x*0.75;
-       const float spacing_size = mySize_x*0.04;
+       float name_size = mySize_x*0.75;
+       float spacing_size = mySize_x*0.04;
        const float highlight_alpha = 0.2;
        float i, me_printed, first_pl;
        string s;
-       i, first_pl = 0;
+       i = 0;
+       first_pl = 0;
        if (autocvar__hud_configure)
        {
                float players_per_team;
@@ -2928,7 +2929,7 @@ float vote_change; // "time" when vote_active changed
 
 void HUD_VoteWindow(void) 
 {
-       if(autocvar_cl_allow_uid2name == -1 && (gametype == GAME_CTS || gametype == GAME_RACE))
+       if(autocvar_cl_allow_uid2name == -1 && (gametype == GAME_CTS || gametype == GAME_RACE || (serverflags & SERVERFLAG_PLAYERSTATS)))
        {
                vote_active = 1;
                if (autocvar__hud_configure)
@@ -2938,6 +2939,8 @@ void HUD_VoteWindow(void)
                        print(_("^1You must answer before entering hud configure mode\n"));
                        cvar_set("_hud_configure", "0");
                }
+               if(vote_called_vote)
+                       strunzone(vote_called_vote);
                vote_called_vote = strzone(_("^2Name ^7instead of \"^1Unregistered player^7\" in stats"));
                uid2name_dialog = 1;
        }
index 109a9cf54a239b17e7280f2aa15823c06c3614f6..f26f65ea54b53d3c7a5d8cd564457416d81755d7 100644 (file)
@@ -680,7 +680,7 @@ float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
                float k, level, start_pos_x;
                vector candidate_pos;
                const float LEVELS_NUM = 4;
-               const float level_height = vid_conheight / LEVELS_NUM;
+               float level_height = vid_conheight / LEVELS_NUM;
 :find_tab_panel
                level = floor(tab_panel_pos_y / level_height) * level_height; //starting level
                candidate_pos_x = (!tab_backward) ? vid_conwidth : 0;
index 31fecfaee2287e81131ebb5e5319c33983a02f7b..37ad89da52676ac4412fa0f60879658fed1e363c 100644 (file)
@@ -283,14 +283,14 @@ void Ent_Projectile()
                        case PROJECTILE_ELECTRO_BEAM: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
                        case PROJECTILE_GRENADE: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
                        case PROJECTILE_GRENADE_BOUNCING: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
-                       case PROJECTILE_MINE: setmodel(self, "models/mine.md3");self.traileffect = particleeffectnum(""); break;
+                       case PROJECTILE_MINE: setmodel(self, "models/mine.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
                        case PROJECTILE_LASER: setmodel(self, "models/laser.mdl");self.traileffect = particleeffectnum(""); break;
                        case PROJECTILE_HLAC: setmodel(self, "models/hlac_bullet.md3");self.traileffect = particleeffectnum(""); break;
                        case PROJECTILE_PORTO_RED: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_WIZSPIKE"); self.scale = 4; break;
                        case PROJECTILE_PORTO_BLUE: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_WIZSPIKE"); self.scale = 4; break;
                        case PROJECTILE_HOOKBOMB: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_KNIGHTSPIKE"); break;
-                       case PROJECTILE_HAGAR: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("TR_GRENADE"); self.scale = 0.4; break;
-                       case PROJECTILE_HAGAR_BOUNCING: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("TR_GRENADE"); self.scale = 0.4; break;
+                       case PROJECTILE_HAGAR: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("TR_GRENADE"); self.scale = 0.75; break;
+                       case PROJECTILE_HAGAR_BOUNCING: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("TR_GRENADE"); self.scale = 0.75; break;
                        case PROJECTILE_FIREBALL: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("fireball"); break; // particle effect is good enough
                        case PROJECTILE_FIREMINE: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("firemine"); break; // particle effect is good enough
                        case PROJECTILE_TAG: setmodel(self, "models/laser.mdl"); self.traileffect = particleeffectnum("TR_ROCKET"); break;
index 7a29154d66827c88bad2d7a70d54e225b22acd88..6e1c1f9bd78b2ab3480a1054020fbec475edbc86 100644 (file)
@@ -1,11 +1,13 @@
 #define TUBA_MIN -18
 #define TUBA_MAX  27
+#define TUBA_INSTRUMENTS 1
 
-#define TUBA_STARTNOTE(n) strcat("weapons/tuba_loopnote", ftos(n), ".wav")
+#define TUBA_STARTNOTE(i,n) strcat("weapons/tuba", (i ? ftos(i) : ""), "_loopnote", ftos(n), ".wav")
 .float note; // note
 .float attenuate; // if set, attenuate it
 .float cnt; // current volume
 .float count; // initial volume
+.float tuba_instrument;
 
 float Tuba_PitchStep;
 
@@ -34,23 +36,23 @@ void tubasound(entity e, float restart)
                        if(e.note - m < TUBA_MIN)
                        {
                                if(restart)
-                                       snd1 = TUBA_STARTNOTE(e.note - m + Tuba_PitchStep);
+                                       snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
                                p1 = pow(2.0, (m - Tuba_PitchStep) / 12.0);
                        }
                        else if(e.note - m + Tuba_PitchStep > TUBA_MAX)
                        {
                                if(restart)
-                                       snd1 = TUBA_STARTNOTE(e.note - m);
+                                       snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
                                p1 = pow(2.0, m / 12.0);
                        }
                        else
                        {
                                if(restart)
-                                       snd1 = TUBA_STARTNOTE(e.note - m);
+                                       snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m);
                                f1 = cos(M_PI_2 * m / Tuba_PitchStep);
                                p1 = pow(2.0, m / 12.0);
                                if(restart)
-                                       snd2 = TUBA_STARTNOTE(e.note - m + Tuba_PitchStep);
+                                       snd2 = TUBA_STARTNOTE(e.tuba_instrument, e.note - m + Tuba_PitchStep);
                                f2 = sin(M_PI_2 * m / Tuba_PitchStep);
                                p2 = pow(2.0, (m - Tuba_PitchStep) / 12.0);
                        }
@@ -58,7 +60,7 @@ void tubasound(entity e, float restart)
                else
                {
                        if(restart)
-                               snd1 = TUBA_STARTNOTE(e.note);
+                               snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
                }
 
                sound7(e, CH_TUBA, snd1, e.cnt * f1, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p1, 0);
@@ -68,7 +70,7 @@ void tubasound(entity e, float restart)
        else
        {
                if(restart)
-                       snd1 = TUBA_STARTNOTE(e.note);
+                       snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
                sound(e, CH_TUBA, snd1, e.cnt, e.attenuate * autocvar_g_balance_tuba_attenuation);
        }
 }
@@ -103,6 +105,7 @@ void Ent_TubaNote_UpdateSound()
        self.enemy.cnt = bound(0, VOL_BASE * autocvar_g_balance_tuba_volume, 1);
        self.enemy.count = self.enemy.cnt;
        self.enemy.note = self.note;
+       self.enemy.tuba_instrument = self.tuba_instrument;
        tubasound(self.enemy, 1);
 }
 
@@ -114,47 +117,63 @@ void Ent_TubaNote_StopSound()
 
 void Ent_TubaNote(float bIsNew)
 {
-       float f, n;
+       float f, n, i, att;
        f = ReadByte();
-       n = floor(f / 2) - 42;
-       if(n != self.note || bIsNew)
-               if(self.enemy)
-                       Ent_TubaNote_StopSound();
-       if(!self.enemy)
+
+       if(f & 1)
        {
-               self.enemy = spawn();
-               self.enemy.classname = "tuba_note";
-               if(Tuba_PitchStep)
+               n = ReadChar();
+               i = ReadByte();
+               att = (i & 1);
+               i = floor(i / 2);
+
+               if(n != self.note || i != self.tuba_instrument || bIsNew)
+               {
+                       if(self.enemy)
+                               Ent_TubaNote_StopSound();
+               }
+
+               if(!self.enemy)
+               {
+                       self.enemy = spawn();
+                       self.enemy.classname = "tuba_note";
+                       if(Tuba_PitchStep)
+                       {
+                               self.enemy.enemy = spawn();
+                               self.enemy.enemy.classname = "tuba_note_2";
+                       }
+                       bIsNew = TRUE;
+               }
+
+               self.enemy.attenuate = att;
+
+               if(bIsNew)
                {
-                       self.enemy.enemy = spawn();
-                       self.enemy.enemy.classname = "tuba_note_2";
+                       self.note = n;
+                       self.tuba_instrument = i;
+                       Ent_TubaNote_UpdateSound();
                }
-               bIsNew = TRUE;
        }
-       if(f & 1)
+
+       if(f & 2)
        {
                self.enemy.origin_x = ReadCoord();
                self.enemy.origin_y = ReadCoord();
                self.enemy.origin_z = ReadCoord();
                setorigin(self.enemy, self.enemy.origin);
-               self.enemy.attenuate = ReadByte();
                if(self.enemy.enemy)
                        setorigin(self.enemy.enemy, self.enemy.origin);
        }
+
        self.think = Ent_TubaNote_StopSound;
        self.entremove = Ent_TubaNote_StopSound;
        self.enemy.think = Ent_TubaNote_Think;
        self.enemy.nextthink = time + 10;
-       if(bIsNew)
-       {
-               self.note = n;
-               Ent_TubaNote_UpdateSound();
-       }
 }
 
 void Tuba_Precache()
 {
-       float i;
+       float i, n;
        Tuba_PitchStep = autocvar_g_balance_tuba_pitchstep;
        if(Tuba_PitchStep)
        {
@@ -164,9 +183,12 @@ void Tuba_Precache()
                        Tuba_PitchStep = 0;
                }
        }
-       for(i = TUBA_MIN; i <= TUBA_MAX; ++i)
+       for(n = TUBA_MIN; n <= TUBA_MAX; ++n)
        {
-               if(!Tuba_PitchStep || (mod(i, Tuba_PitchStep) == 0))
-                       precache_sound(TUBA_STARTNOTE(i));
+               if(!Tuba_PitchStep || (mod(n, Tuba_PitchStep) == 0))
+               {
+                       for(i = 0; i < TUBA_INSTRUMENTS; ++i)
+                               precache_sound(TUBA_STARTNOTE(i, n));
+               }
        }
 }
index 9c40578739b3ae00744a63dc3fd0e14bd827a250..c59901b21475b5c7e505aee04a4167dcca0d0cbd 100644 (file)
@@ -715,3 +715,4 @@ float HUD_MENU_ENABLE               = 0;
 
 #define SERVERFLAG_ALLOW_FULLBRIGHT 1
 #define SERVERFLAG_TEAMPLAY 2
+#define SERVERFLAG_PLAYERSTATS 4
index 518cf74971a645dde3c412c1a1eaabee9b5ae1b8..c2b986bb889a9ebd3afb64a87cd2bd325f9f92ba 100644 (file)
@@ -191,6 +191,8 @@ float GameCommand_Generic(string command)
                print("    s localtime -----------------------> s   : formats the current local time\n");
                print("    s gmtime --------------------------> s   : formats the current UTC time\n");
                print("    time ------------------------------> f   : seconds since VM start\n");
+               print("    s /MD4 digest ---------------------> s   : MD4 digest\n");
+               print("    s /SHA256 digest ------------------> s   : SHA256 digest\n");
                print("    Set operations operate on 'such''strings'.\n");
                print("    Unknown tokens insert their cvar value.\n");
                print("  maplist add map\n");
@@ -790,6 +792,9 @@ float GameCommand_Generic(string command)
                                        rpn_set(strftime(FALSE, rpn_get()));
                                } else if(rpncmd == "time") {
                                        rpn_pushf(time);
+                               } else if(rpncmd == "digest") {
+                                       s = rpn_pop();
+                                       rpn_set(digest_hex(s, rpn_get()));
                                } else {
                                        rpn_push(cvar_string(rpncmd));
                                }
index 0ab17f34a4eebed25e7dee028c104c7d5fb25602..2f7d0ee3ab4211609c20257b0f360b0021dee1bb 100644 (file)
@@ -1,5 +1,7 @@
-// files (-1 for URL)
+// files
 .float url_fh;
+#define URL_FH_CURL   -1
+#define URL_FH_STDOUT -2
 
 // URLs
 .string url_url;
@@ -35,7 +37,7 @@ float url_URI_Get_Callback(float id, float status, string data)
        url_fromid[id] = world;
 
        // if we get here, we MUST have both buffers cleared
-       if(e.url_rbuf != -1 || e.url_wbuf != -1 || e.url_fh != -1)
+       if(e.url_rbuf != -1 || e.url_wbuf != -1 || e.url_fh != URL_FH_CURL)
                error("url_URI_Get_Callback: not a request waiting for data");
 
        if(status == 0)
@@ -76,7 +78,7 @@ float url_URI_Get_Callback(float id, float status, string data)
        }
 }
 
-void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
+void url_single_fopen(string url, float mode, url_ready_func rdy, entity pass)
 {
        entity e;
        float i;
@@ -91,13 +93,13 @@ void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
 
                                // create a writing end that does nothing yet
                                e = spawn();
-                               e.classname = "url_fopen_file";
+                               e.classname = "url_single_fopen_file";
                                e.url_url = strzone(url);
-                               e.url_fh = -1;
+                               e.url_fh = URL_FH_CURL;
                                e.url_wbuf = buf_create();
                                if(e.url_wbuf < 0)
                                {
-                                       print("url_fopen: out of memory in buf_create\n");
+                                       print("url_single_fopen: out of memory in buf_create\n");
                                        rdy(e, pass, URL_READY_ERROR);
                                        strunzone(e.url_url);
                                        remove(e);
@@ -105,6 +107,8 @@ void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
                                }
                                e.url_wbufpos = 0;
                                e.url_rbuf = -1;
+                               e.url_ready = rdy;
+                               e.url_ready_pass = pass;
                                rdy(e, pass, URL_READY_CANWRITE);
                                break;
 
@@ -122,7 +126,7 @@ void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
                                                        break;
                                        if(i >= autocvar__urllib_nextslot)
                                        {
-                                               print("url_fopen: too many concurrent requests\n");
+                                               print("url_single_fopen: too many concurrent requests\n");
                                                rdy(world, pass, URL_READY_ERROR);
                                                return;
                                        }
@@ -131,7 +135,7 @@ void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
                                // GET the data
                                if(!crypto_uri_postbuf(url, i + MIN_URL_ID, string_null, string_null, -1, 0))
                                {
-                                       print("url_fopen: failure in crypto_uri_postbuf\n");
+                                       print("url_single_fopen: failure in crypto_uri_postbuf\n");
                                        rdy(world, pass, URL_READY_ERROR);
                                        return;
                                }
@@ -140,9 +144,9 @@ void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
                                // all). Wait for data to come from the
                                // server, then call the callback
                                e = spawn();
-                               e.classname = "url_fopen_file";
+                               e.classname = "url_single_fopen_file";
                                e.url_url = strzone(url);
-                               e.url_fh = -1;
+                               e.url_fh = URL_FH_CURL;
                                e.url_rbuf = -1;
                                e.url_wbuf = -1;
                                e.url_ready = rdy;
@@ -155,6 +159,25 @@ void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
                                break;
                }
        }
+       else if(url == "-")
+       {
+               switch(mode)
+               {
+                       case FILE_WRITE:
+                       case FILE_APPEND:
+                               e = spawn();
+                               e.classname = "url_single_fopen_stdout";
+                               e.url_fh = URL_FH_STDOUT;
+                               e.url_ready = rdy;
+                               e.url_ready_pass = pass;
+                               rdy(e, pass, URL_READY_CANWRITE);
+                               break;
+                       case FILE_READ:
+                               print("url_single_fopen: cannot open '-' for reading\n");
+                               rdy(world, pass, URL_READY_ERROR);
+                               break;
+               }
+       }
        else
        {
                float fh;
@@ -167,8 +190,10 @@ void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
                else
                {
                        e = spawn();
-                       e.classname = "url_fopen_file";
+                       e.classname = "url_single_fopen_file";
                        e.url_fh = fh;
+                       e.url_ready = rdy;
+                       e.url_ready_pass = pass;
                        if(mode == FILE_READ)
                                rdy(e, pass, URL_READY_CANREAD);
                        else
@@ -178,11 +203,11 @@ void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
 }
 
 // close a file
-void url_fclose(entity e, url_ready_func rdy, entity pass)
+void url_fclose(entity e)
 {
        float i;
 
-       if(e.url_fh < 0)
+       if(e.url_fh == URL_FH_CURL)
        {
                if(e.url_rbuf == -1 || e.url_wbuf != -1) // not(post GET/POST request)
                if(e.url_rbuf != -1 || e.url_wbuf == -1) // not(pre POST request)
@@ -205,7 +230,7 @@ void url_fclose(entity e, url_ready_func rdy, entity pass)
                                if(i >= autocvar__urllib_nextslot)
                                {
                                        print("url_fclose: too many concurrent requests\n");
-                                       rdy(e, pass, URL_READY_ERROR);
+                                       e.url_ready(e,e.url_ready_pass, URL_READY_ERROR);
                                        buf_del(e.url_wbuf);
                                        strunzone(e.url_url);
                                        remove(e);
@@ -217,7 +242,7 @@ void url_fclose(entity e, url_ready_func rdy, entity pass)
                        if(!crypto_uri_postbuf(e.url_url, i + MIN_URL_ID, "text/plain", "", e.url_wbuf, 0))
                        {
                                print("url_fclose: failure in crypto_uri_postbuf\n");
-                               rdy(e, pass, URL_READY_ERROR);
+                               e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
                                buf_del(e.url_wbuf);
                                strunzone(e.url_url);
                                remove(e);
@@ -229,8 +254,6 @@ void url_fclose(entity e, url_ready_func rdy, entity pass)
                        // call the callback
                        buf_del(e.url_wbuf);
                        e.url_wbuf = -1;
-                       e.url_ready = rdy;
-                       e.url_ready_pass = pass;
                        e.url_id = i;
                        url_fromid[i] = e;
 
@@ -240,17 +263,22 @@ void url_fclose(entity e, url_ready_func rdy, entity pass)
                else
                {
                        // we have READ all data, just close
-                       rdy(e, pass, URL_READY_CLOSED);
+                       e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED);
                        buf_del(e.url_rbuf);
                        strunzone(e.url_url);
                        remove(e);
                }
        }
+       else if(e.url_fh == URL_FH_STDOUT)
+       {
+               e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
+               remove(e);
+       }
        else
        {
                // file
                fclose(e.url_fh);
-               rdy(e, pass, URL_READY_CLOSED); // closing creates no reading handle
+               e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
                remove(e);
        }
 }
@@ -258,7 +286,7 @@ void url_fclose(entity e, url_ready_func rdy, entity pass)
 // with \n (blame FRIK_FILE)
 string url_fgets(entity e)
 {
-       if(e.url_fh < 0)
+       if(e.url_fh == URL_FH_CURL)
        {
                if(e.url_rbuf == -1)
                        error("url_fgets: not readable in current state");
@@ -268,6 +296,11 @@ string url_fgets(entity e)
                e.url_rbufpos += 1;
                return s;
        }
+       else if(e.url_fh == URL_FH_STDOUT)
+       {
+               // stdout
+               return string_null;
+       }
        else
        {
                // file
@@ -278,7 +311,7 @@ string url_fgets(entity e)
 // without \n (blame FRIK_FILE)
 void url_fputs(entity e, string s)
 {
-       if(e.url_fh < 0)
+       if(e.url_fh == URL_FH_CURL)
        {
                if(e.url_wbuf == -1)
                        error("url_fputs: not writable in current state");
@@ -286,9 +319,56 @@ void url_fputs(entity e, string s)
                bufstr_set(e.url_wbuf, e.url_wbufpos, s);
                e.url_wbufpos += 1;
        }
+       else if(e.url_fh == URL_FH_STDOUT)
+       {
+               // stdout
+               print(s);
+       }
        else
        {
                // file
                fputs(e.url_fh, s);
        }
 }
+
+// multi URL object, tries URLs separated by space in sequence
+void url_multi_ready(entity fh, entity me, float status)
+{
+       float n;
+       if(status == URL_READY_ERROR)
+       {
+               me.cnt += 1;
+               n = tokenize_console(me.url_url);
+               if(n <= me.cnt)
+               {
+                       me.url_ready(fh, me.url_ready_pass, status);
+                       strunzone(me.url_url);
+                       remove(me);
+                       return;
+               }
+               url_single_fopen(argv(me.cnt), me.lip, url_multi_ready, me);
+               return;
+       }
+       me.url_ready(fh, me.url_ready_pass, status);
+}
+void url_multi_fopen(string url, float mode, url_ready_func rdy, entity pass)
+{
+       float n;
+       n = tokenize_console(url);
+       if(n <= 0)
+       {
+               print("url_multi_fopen: need at least one URL\n");
+               rdy(world, pass, URL_READY_ERROR);
+               return;
+       }
+
+       entity me;
+       me = spawn();
+       me.classname = "url_multi";
+       me.url_url = strzone(url);
+       me.cnt = 0;
+       me.lip = mode;
+       me.url_ready = rdy;
+       me.url_ready_pass = pass;
+       url_single_fopen(argv(0), mode, url_multi_ready, me);
+}
index a7735ed4f3f9ee1b05d279366125e7dfe0dd4a05..f92178b2f6f6a6569b72af048fbba23811c0e69f 100644 (file)
@@ -5,8 +5,8 @@ float URL_READY_CANREAD  =  2;
 // errors: -1, or negative HTTP status code
 typedef void(entity handle, entity pass, float status) url_ready_func;
 
-void url_fopen(string url, float mode, url_ready_func rdy, entity pass);
-void url_fclose(entity e, url_ready_func rdy, entity pass);
+void url_single_fopen(string url, float mode, url_ready_func rdy, entity pass);
+void url_fclose(entity e);
 string url_fgets(entity e);
 void url_fputs(entity e, string s);
 
@@ -14,3 +14,5 @@ void url_fputs(entity e, string s);
 float url_URI_Get_Callback(float id, float status, string data);
 #define MIN_URL_ID 128
 #define NUM_URL_ID 64
+
+void url_multi_fopen(string url, float mode, url_ready_func rdy, entity pass);
index e5d366eb7049cd92ea883e24444c0dcc5c441230..ffdc1bb91d60f9f559de74190102a916c422b1c2 100644 (file)
@@ -341,3 +341,15 @@ string crypto_getidfp(string serveraddress) = #634; // retrieves the cached host
 string crypto_getencryptlevel(string serveraddress) = #635; // 0 if never encrypting, 1 supported, 2 requested, 3 required, appended by list of allowed methods in order of preference ("AES128"), preceded by a space each
 float(string url, float id, string content_type, string delim, float buf, float keyid) crypto_uri_postbuf = #513;
 //description:
+
+//DP_QC_DIGEST
+//idea: motorsep, Spike
+//DarkPlaces implementation: divVerent
+//builtin definitions:
+string(string digest, string data, ...) digest_hex = #639;
+//description:
+//returns a given hex digest of given data
+//the returned digest is always encoded in hexadecimal
+//only the "MD4" digest is always supported!
+//if the given digest is not supported, string_null is returned
+//the digest string is matched case sensitively, use "MD4", not "md4"!
index 6b14d1446de07fe5019b94f84aa7ac8591efd087..2711c57e7f1eb53789d075a560557c870e5fdddc 100644 (file)
@@ -72,6 +72,8 @@ string XonoticMutatorsDialog_toString(entity me)
                s = strcat(s, ", ", _("NIX"));
        if(cvar("g_rocket_flying"))
                s = strcat(s, ", ", _("Rocket Flying"));
+       if(cvar("g_invincible_projectiles"))
+               s = strcat(s, ", ", _("Invincible Projectiles"));
        if(cvar_string("g_weaponarena") != "0")
                s = strcat(s, ", ", WeaponArenaString());
        if(cvar("g_start_weapon_laser") == 0)
@@ -191,7 +193,6 @@ void XonoticMutatorsDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.4);
                me.TD(me, 1, 1.8, s);
-       me.TR(me);
        me.TR(me);
                me.TD(me, 1, 2, makeXonoticTextLabel(0, _("Weapon & item mutators:")));
        me.TR(me);
@@ -200,6 +201,9 @@ void XonoticMutatorsDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "g_jetpack", _("Jet pack")));
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "g_invincible_projectiles", _("Invincible Projectiles")));
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "g_rocket_flying", _("Rocket Flying")));
index f85c2877cc6f8c82e44be48ed91582eb634eea20..bf3406142c4c91f188a09f2c98e66267adfcdb80 100644 (file)
@@ -127,6 +127,8 @@ void XonoticAudioSettingsTab_fill(entity me)
                me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "snd_spatialization_control", _("Headphone friendly mode")));
                setDependent(e, "snd_channels", 1.5, 0.5);
        me.TR(me);
+       me.TR(me);
+               me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "menu_snd_attenuation_method", _("New style sound attenuation")));
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Spatial voices:")));
                me.TD(me, 1, 2/3, e = makeXonoticRadioButton(1, "cl_voice_directional", "0", ZCTX(_("VOCS^None"))));
@@ -170,6 +172,6 @@ void XonoticAudioSettingsTab_fill(entity me)
                me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 0, "menu_sounds", _("Menu sounds")));
 
        me.gotoRC(me, me.rows - 1, 0);
-               me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "snd_restart; sendcvar cl_hitsound; sendcvar cl_autotaunt; sendcvar cl_voice_directional; sendcvar cl_voice_directional_taunt_attenuation", COMMANDBUTTON_APPLY));
+               me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "snd_restart; snd_attenuation_method_$menu_snd_attenuation_method; sendcvar cl_hitsound; sendcvar cl_autotaunt; sendcvar cl_voice_directional; sendcvar cl_voice_directional_taunt_attenuation", COMMANDBUTTON_APPLY));
 }
 #endif
index 6e9bf1790751764bd48bf9007c5e519106fa08ee..f02d747cc91f1f0e229c56074c217dc2609e2c5e 100644 (file)
@@ -238,7 +238,7 @@ void XonoticServerList_refreshServerList(entity me, float mode)
        }
        else */
        {
-               float m, o;
+               float m, o, i, n; // moin moin
                string s, typestr, modstr;
                s = me.filterString;
 
@@ -261,15 +261,22 @@ void XonoticServerList_refreshServerList(entity me, float mode)
                // ping: reject negative ping (no idea why this happens in the first place, engine bug)
                sethostcachemasknumber(++m, SLIST_FIELD_PING, 0, SLIST_TEST_GREATEREQUAL);
 
+               // show full button
                if(!me.filterShowFull)
                {
                        sethostcachemasknumber(++m, SLIST_FIELD_FREESLOTS, 1, SLIST_TEST_GREATEREQUAL); // legacy
                        sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, ":S0:", SLIST_TEST_NOTCONTAIN); // g_maxplayers support
                }
+
+               // show empty button
                if(!me.filterShowEmpty)
                        sethostcachemasknumber(++m, SLIST_FIELD_NUMHUMANS, 1, SLIST_TEST_GREATEREQUAL);
+
+               // gametype filtering
                if(typestr != "")
                        sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(typestr, ":"), SLIST_TEST_STARTSWITH);
+
+               // mod filtering
                if(modstr != "")
                {
                        if(substring(modstr, 0, 1) == "!")
@@ -277,6 +284,13 @@ void XonoticServerList_refreshServerList(entity me, float mode)
                        else
                                sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(modstr), SLIST_TEST_EQUAL);
                }
+
+               // server banning
+               n = tokenizebyseparator(_Nex_ExtResponseSystem_BannedServers, " ");
+               for(i = 0; i < n; ++i)
+                       if(argv(i) != "")
+                               sethostcachemaskstring(++m, SLIST_FIELD_CNAME, argv(i), SLIST_TEST_NOTSTARTSWITH);
+
                m = SLIST_MASK_OR - 1;
                if(s != "")
                {
@@ -308,6 +322,13 @@ void XonoticServerList_draw(entity me)
 {
        float i, found, owned;
 
+       if(_Nex_ExtResponseSystem_BannedServersNeedsRefresh)
+       {
+               if(!me.needsRefresh)
+                       me.needsRefresh = 2;
+               _Nex_ExtResponseSystem_BannedServersNeedsRefresh = 0;
+       }
+
        if(me.currentSortField == -1)
        {
                me.setSortOrder(me, SLIST_FIELD_PING, +1);
@@ -469,17 +490,17 @@ void ServerList_ShowFull_Click(entity box, entity me)
        me.ipAddressBox.cursorPos = 0;
        me.ipAddressBoxFocused = -1;
 }
-void XonoticServerList_setSortOrder(entity me, float field, float direction)
+void XonoticServerList_setSortOrder(entity me, float fld, float direction)
 {
-       if(me.currentSortField == field)
+       if(me.currentSortField == fld)
                direction = -me.currentSortOrder;
        me.currentSortOrder = direction;
-       me.currentSortField = field;
-       me.sortButton1.forcePressed = (field == SLIST_FIELD_PING);
-       me.sortButton2.forcePressed = (field == SLIST_FIELD_NAME);
-       me.sortButton3.forcePressed = (field == SLIST_FIELD_MAP);
+       me.currentSortField = fld;
+       me.sortButton1.forcePressed = (fld == SLIST_FIELD_PING);
+       me.sortButton2.forcePressed = (fld == SLIST_FIELD_NAME);
+       me.sortButton3.forcePressed = (fld == SLIST_FIELD_MAP);
        me.sortButton4.forcePressed = 0;
-       me.sortButton5.forcePressed = (field == SLIST_FIELD_NUMHUMANS);
+       me.sortButton5.forcePressed = (fld == SLIST_FIELD_NUMHUMANS);
        me.selectedItem = 0;
        if(me.selectedServer)
                strunzone(me.selectedServer);
index 65a5d3e71a60fad721cddb189660e0489891c6ab..b8215d52cac6c97150ea863fa05c7dd885d02a25 100644 (file)
@@ -325,6 +325,12 @@ void UpdateNotification_URI_Get_Callback(float id, float status, string data)
                }
 
                _Nex_ExtResponseSystem_UpdateTo = strzone(_Nex_ExtResponseSystem_UpdateTo);
+
+               if(n >= 4)
+               {
+                       _Nex_ExtResponseSystem_BannedServers = strzone(argv(3));
+                       _Nex_ExtResponseSystem_BannedServersNeedsRefresh = 1;
+               }
        }
 }
 
index 1720710d2c44de09db39110aa93b9a84578ebb5d..d8f66f4e967ec242cafb3da865da541619a2ac9f 100644 (file)
@@ -47,3 +47,6 @@ void dialog_hudpanel_common_notoggle(entity me, string panelname);
        me.TR(me); \
                me.TD(me, 1, 4, e = makeXonoticCheckBox(0, strzone(strcat("hud_panel_", panelname)), _("Enable panel"))); \
        DIALOG_HUDPANEL_COMMON_NOTOGGLE()
+
+string _Nex_ExtResponseSystem_BannedServers;
+float _Nex_ExtResponseSystem_BannedServersNeedsRefresh;
index 6ccaf71d4c52053a96a6651bd6829f0d66754786..777284841943826c8515597a68a09d0d760f1209 100644 (file)
@@ -120,6 +120,12 @@ float autocvar_g_balance_rifle_secondary_tracer;
 float autocvar_g_balance_rifle_reload_ammo;
 float autocvar_g_balance_rifle_reload_time;
 float autocvar_g_balance_cloaked_alpha;
+float autocvar_g_balance_contents_damagerate;
+float autocvar_g_balance_contents_drowndelay;
+float autocvar_g_balance_contents_playerdamage_drowning;
+float autocvar_g_balance_contents_playerdamage_lava;
+float autocvar_g_balance_contents_playerdamage_slime;
+float autocvar_g_balance_contents_projectiledamage;
 float autocvar_g_balance_crylink_primary_ammo;
 float autocvar_g_balance_crylink_primary_animtime;
 float autocvar_g_balance_crylink_primary_bouncedamagefactor;
@@ -215,6 +221,7 @@ float autocvar_g_balance_electro_secondary_bouncestop;
 float autocvar_g_balance_electro_secondary_count;
 float autocvar_g_balance_electro_secondary_damage;
 float autocvar_g_balance_electro_secondary_damageforcescale;
+float autocvar_g_balance_electro_secondary_damagedbycontents;
 float autocvar_g_balance_electro_secondary_edgedamage;
 float autocvar_g_balance_electro_secondary_force;
 float autocvar_g_balance_electro_secondary_health;
@@ -280,6 +287,7 @@ float autocvar_g_balance_grapplehook_length_min;
 float autocvar_g_balance_grapplehook_speed_fly;
 float autocvar_g_balance_grapplehook_speed_pull;
 float autocvar_g_balance_grapplehook_stretch;
+float autocvar_g_balance_grapplehook_damagedbycontents;
 float autocvar_g_balance_grenadelauncher_bouncefactor;
 float autocvar_g_balance_grenadelauncher_bouncestop;
 float autocvar_g_balance_grenadelauncher_primary_ammo;
@@ -318,6 +326,8 @@ float autocvar_g_balance_hagar_primary_ammo;
 float autocvar_g_balance_hagar_primary_damage;
 float autocvar_g_balance_hagar_primary_edgedamage;
 float autocvar_g_balance_hagar_primary_force;
+float autocvar_g_balance_hagar_primary_health;
+float autocvar_g_balance_hagar_primary_damageforcescale;
 float autocvar_g_balance_hagar_primary_lifetime;
 float autocvar_g_balance_hagar_primary_radius;
 float autocvar_g_balance_hagar_primary_refire;
@@ -331,10 +341,14 @@ float autocvar_g_balance_hagar_secondary_load_max;
 float autocvar_g_balance_hagar_secondary_load_hold;
 float autocvar_g_balance_hagar_secondary_load_releasedeath;
 float autocvar_g_balance_hagar_secondary_load_abort;
+float autocvar_g_balance_hagar_secondary_load_linkexplode;
+float autocvar_g_balance_hagar_secondary_load_animtime;
 float autocvar_g_balance_hagar_secondary_ammo;
 float autocvar_g_balance_hagar_secondary_damage;
 float autocvar_g_balance_hagar_secondary_edgedamage;
 float autocvar_g_balance_hagar_secondary_force;
+float autocvar_g_balance_hagar_secondary_health;
+float autocvar_g_balance_hagar_secondary_damageforcescale;
 float autocvar_g_balance_hagar_secondary_lifetime_min;
 float autocvar_g_balance_hagar_secondary_lifetime_rand;
 float autocvar_g_balance_hagar_secondary_radius;
@@ -397,6 +411,8 @@ float autocvar_g_balance_hook_secondary_power;
 float autocvar_g_balance_hook_secondary_radius;
 float autocvar_g_balance_hook_secondary_refire;
 float autocvar_g_balance_hook_secondary_speed;
+float autocvar_g_balance_hook_secondary_health;
+float autocvar_g_balance_hook_secondary_damageforcescale;
 float autocvar_g_balance_keyhunt_damageforcescale;
 float autocvar_g_balance_keyhunt_delay_collect;
 float autocvar_g_balance_keyhunt_delay_return;
@@ -655,9 +671,13 @@ float autocvar_g_balance_shotgun_secondary_damage;
 float autocvar_g_balance_shotgun_secondary_force;
 float autocvar_g_balance_shotgun_secondary_melee_delay;
 float autocvar_g_balance_shotgun_secondary_melee_range;
-float autocvar_g_balance_shotgun_secondary_melee_swing;
+float autocvar_g_balance_shotgun_secondary_melee_swing_side;
+float autocvar_g_balance_shotgun_secondary_melee_swing_up;
 float autocvar_g_balance_shotgun_secondary_melee_time;
+float autocvar_g_balance_shotgun_secondary_melee_traces;
 float autocvar_g_balance_shotgun_secondary_melee_no_doubleslap;
+float autocvar_g_balance_shotgun_secondary_melee_nonplayerdamage;
+float autocvar_g_balance_shotgun_secondary_melee_multihit;
 float autocvar_g_balance_shotgun_secondary_refire;
 float autocvar_g_balance_shotgun_reload_ammo;
 float autocvar_g_balance_shotgun_reload_time;
@@ -925,6 +945,7 @@ float autocvar_g_playerstats_debug;
 float autocvar_g_powerup_shield;
 float autocvar_g_powerup_strength;
 float autocvar_g_powerup_superhealth;
+float autocvar_g_projectiles_damage;
 float autocvar_g_projectiles_newton_style;
 float autocvar_g_projectiles_newton_style_2_maxfactor;
 float autocvar_g_projectiles_newton_style_2_minfactor;
@@ -1195,3 +1216,4 @@ float autocvar_welcome_message_time;
 float autocvar_sv_gameplayfix_gravityunaffectedbyticrate;
 float autocvar_g_trueaim_minrange;
 float autocvar_g_debug_defaultsounds;
+float autocvar_g_loituma;
index 58d25b0e73474761c2a3d53797a31903456bb44e..34a0cee02c70776f19b97ce24a229680e7d7b045 100644 (file)
@@ -662,6 +662,7 @@ void PutObserverInServer (void)
        
        self.classname = "observer";
        self.iscreature = FALSE;
+       self.damagedbycontents = FALSE;
        self.health = -666;
        self.takedamage = DAMAGE_NO;
        self.solid = SOLID_NOT;
@@ -899,6 +900,7 @@ void PutClientInServer (void)
                self.classname = "player";
                self.wasplayer = TRUE;
                self.iscreature = TRUE;
+               self.damagedbycontents = TRUE;
                self.movetype = MOVETYPE_WALK;
                self.solid = SOLID_SLIDEBOX;
                self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
@@ -1091,7 +1093,7 @@ void PutClientInServer (void)
                        entity e;
                        e = get_weaponinfo(j);
                        if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
-                               self.weapon_load[j] = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
+                               self.(weapon_load[j]) = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
                }
 
                oldself = self;
@@ -2774,9 +2776,12 @@ void PlayerPreThink (void)
 
        MUTATOR_CALLHOOK(PlayerPreThink);
 
-       if(self.BUTTON_USE && !self.usekeypressed)
-               PlayerUseKey();
-       self.usekeypressed = self.BUTTON_USE;
+       if(!self.cvar_cl_newusekeysupported)
+       {
+               if(self.BUTTON_USE && !self.usekeypressed)
+                       PlayerUseKey();
+               self.usekeypressed = self.BUTTON_USE;
+       }
 
        PrintWelcomeMessage();
 
index 05a809dd371b8bb96bcf1f72498fbd6240cdc2fa..15bb65262416f298cbc356e9054c94acf9ed87a3 100644 (file)
@@ -21,7 +21,7 @@ void WeaponStats_ready(entity fh, entity pass, float status)
        switch(status)
        {
                case URL_READY_CANWRITE:
-                       // url_fopen returned, we can write
+                       // we can write
                        prefix = strcat(autocvar_hostname, "\t", GetGametype(), "_", GetMapname(), "\t");
                        url_fputs(fh, "#begin statsfile\n");
                        url_fputs(fh, strcat("#date ", strftime(TRUE, "%a %b %e %H:%M:%S %Z %Y"), "\n"));
@@ -46,9 +46,7 @@ void WeaponStats_ready(entity fh, entity pass, float status)
                                        }
                                }
                        url_fputs(fh, "#end\n\n");
-                       url_fclose(fh, WeaponStats_ready, world);
-                       buf_del(weaponstats_buffer);
-                       weaponstats_buffer = -1;
+                       url_fclose(fh);
                        break;
                case URL_READY_CANREAD:
                        // url_fclose is processing, we got a response for writing the data
@@ -57,15 +55,19 @@ void WeaponStats_ready(entity fh, entity pass, float status)
                        while((s = url_fgets(fh)))
                                print("  ", s, "\n");
                        print("End of response.\n");
-                       url_fclose(fh, WeaponStats_ready, world);
+                       url_fclose(fh);
                        break;
                case URL_READY_CLOSED:
                        // url_fclose has finished
                        print("Weapon stats written\n");
+                       buf_del(weaponstats_buffer);
+                       weaponstats_buffer = -1;
                        break;
                case URL_READY_ERROR:
                default:
                        print("Weapon stats writing failed: ", ftos(status), "\n");
+                       buf_del(weaponstats_buffer);
+                       weaponstats_buffer = -1;
                        break;
        }
 }
@@ -76,7 +78,7 @@ void WeaponStats_Shutdown()
                return;
        if(autocvar_sv_weaponstats_file != "")
        {
-               url_fopen(autocvar_sv_weaponstats_file, FILE_APPEND, WeaponStats_ready, world);
+               url_multi_fopen(autocvar_sv_weaponstats_file, FILE_APPEND, WeaponStats_ready, world);
        }
        else
        {
@@ -134,6 +136,7 @@ void CopyBody(float keepvelocity)
        self.colormap = oldself.colormap;
        self.glowmod = oldself.glowmod;
        self.iscreature = oldself.iscreature;
+       self.damagedbycontents = oldself.damagedbycontents;
        self.angles = oldself.angles;
        self.avelocity = oldself.avelocity;
        self.classname = "body";
index f0981f5e29cac8bc88e73893d7cf3579b3c2de63..4a333934ae84a5ddc83f4281e2f7406daff1ef9a 100644 (file)
@@ -233,10 +233,10 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto
                                        s = strcat(s, " and ", ftos(thisammo), " ", Item_CounterFieldName(j));
 
                                        // if our weapon is loaded, give its load back to the player
-                                       if(self.weapon_load[self.weapon] > 0)
+                                       if(self.(weapon_load[self.weapon]) > 0)
                                        {
-                                               own.ammofield += self.weapon_load[self.weapon];
-                                               self.weapon_load[self.weapon] = -1; // schedule the weapon for reloading
+                                               own.ammofield += self.(weapon_load[self.weapon]);
+                                               self.(weapon_load[self.weapon]) = -1; // schedule the weapon for reloading
                                        }
                                }
                        }
@@ -368,7 +368,7 @@ void W_WeaponFrame()
                        e = get_weaponinfo(self.switchweapon);
                        if(e.spawnflags & WEP_FLAG_RELOADABLE && cvar(strcat("g_balance_", e.netname, "_reload_ammo"))) // prevent accessing undefined cvars
                        {
-                               self.clip_load = self.weapon_load[self.switchweapon];
+                               self.clip_load = self.(weapon_load[self.switchweapon]);
                                self.clip_size = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
                        }
                        else
index 21a9bc9428a71d6ec6d9bab9acc51a3db464a105..b3b0e6ea06f6d81123acf8ebb0ce60d06412f4e0 100644 (file)
@@ -127,11 +127,24 @@ vector w_shotorg;
 vector w_shotdir;
 vector w_shotend;
 
+.float prevstrengthsound;
+.float prevstrengthsoundattempt;
+void W_PlayStrengthSound(entity player) // void W_PlayStrengthSound
+{
+               if((!g_minstagib)
+                       && (player.items & IT_STRENGTH)
+                       && ((time > player.prevstrengthsound + autocvar_sv_strengthsound_antispam_time) // prevent insane sound spam
+                       || (time > player.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)))
+               {
+                       sound(player, CH_TRIGGER, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM);
+                       player.prevstrengthsound = time;
+               }
+               player.prevstrengthsoundattempt = time;
+}
+
 // this function calculates w_shotorg and w_shotdir based on the weapon model
 // offset, trueaim and antilag, and won't put w_shotorg inside a wall.
 // make sure you call makevectors first (FIXME?)
-.float prevstrengthsound;
-.float prevstrengthsoundattempt;
 void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float chan, float maxdamage, float range)
 {
        float nudge = 1; // added to traceline target and subtracted from result
@@ -241,20 +254,10 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m
                ent.punchangle_x = recoil * -1;
 
        if (snd != "")
-               sound (ent, chan, snd, VOL_BASE, ATTN_NORM);
-
-       if(ent.items & IT_STRENGTH)
-       if(!g_minstagib)
-       if(
-               (time > ent.prevstrengthsound + autocvar_sv_strengthsound_antispam_time)
-               ||
-               (time > ent.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)
-       ) // prevent insane sound spam
        {
-               sound(ent, CH_TRIGGER, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM);
-               ent.prevstrengthsound = time;
+               sound (ent, chan, snd, VOL_BASE, ATTN_NORM);
+               W_PlayStrengthSound(ent);
        }
-       ent.prevstrengthsoundattempt = time;
 
        // nudge w_shotend so a trace to w_shotend hits
        w_shotend = w_shotend + normalize(w_shotend - w_shotorg) * nudge;
@@ -853,6 +856,27 @@ void CL_ExteriorWeaponentity_Think()
                        ang_x = -/* don't ask */ang_x;
                        self.angles = ang;
                }
+
+               if(autocvar_g_loituma)
+               {
+                       vector moddir, modup;
+                       vector modangles;
+                       float t;
+
+                       t = time * autocvar_g_loituma;
+
+                       modangles_x = t * 360;
+                       modangles_y = 90;
+                       modangles_z = 0;
+
+                       self.angles =
+                               AnglesTransform_ToAngles(
+                                       AnglesTransform_Multiply(
+                                               AnglesTransform_FromAngles(self.angles),
+                                               AnglesTransform_FromAngles(modangles)
+                                       )
+                               );
+               }
        }
 
        self.glowmod = self.owner.weaponentity_glowmod;
@@ -1639,7 +1663,7 @@ void W_DecreaseAmmo(.float ammo_type, float ammo_use, float ammo_reload)
        if(ammo_reload)
        {
                self.clip_load -= ammo_use;
-               self.weapon_load[self.weapon] = self.clip_load;
+               self.(weapon_load[self.weapon]) = self.clip_load;
        }
        else
                self.(self.current_ammo) -= ammo_use;
@@ -1668,7 +1692,7 @@ void W_ReloadedAndReady()
                        self.(self.current_ammo) -= 1;
                }
        }
-       self.weapon_load[self.weapon] = self.clip_load;
+       self.(weapon_load[self.weapon]) = self.clip_load;
 
        // do not set ATTACK_FINISHED in reload code any more. This causes annoying delays if eg: You start reloading a weapon,
        // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there,
@@ -1751,5 +1775,5 @@ void W_Reload(float sent_ammo_min, float sent_ammo_amount, float sent_time, stri
        if(self.clip_load < 0)
                self.clip_load = 0;
        self.old_clip_load = self.clip_load;
-       self.clip_load = self.weapon_load[self.weapon] = -1;
+       self.clip_load = self.(weapon_load[self.weapon]) = -1;
 }
index bc05d1b04849b05ced40ef7b3ae1a20f0f7c36c8..9c2e843d1a6089fe4640134128232b46ac2d4840 100644 (file)
@@ -189,6 +189,7 @@ void setanim(entity e, vector anim, float looping, float override, float restart
 
 .float watersound_finished;
 .float iscreature;
+.float damagedbycontents;
 .vector oldvelocity;
 
 .float pauseregen_finished;
@@ -315,6 +316,7 @@ float default_weapon_alpha;
 .float cvar_cl_playerdetailreduction;
 .float cvar_cl_clippedspectating;
 .float cvar_cl_movement_track_canjump;
+.float cvar_cl_newusekeysupported;
 
 .string cvar_g_xonoticversion;
 .string cvar_cl_weaponpriority;
index 8422cf5df8d7b73294b0b18cf6061e4f7730ee41..57d943438e5a2f36caf3c9c37dfad4b7cb4ff34d 100644 (file)
@@ -621,6 +621,13 @@ void(entity from, entity to) copyentity = #400;
 //description:
 //copies all data in the entity to another entity.
 
+//DP_QC_CRC16
+//idea: divVerent
+//darkplaces implementation: divVerent
+//Some hash function to build hash tables with. This has to be be the CRC-16-CCITT that is also required for the QuakeWorld download protocol.
+//When caseinsensitive is set, the CRC is calculated of the lower cased string.
+float(float caseinsensitive, string s, ...) crc16 = #494;
+
 //DP_QC_CVAR_DEFSTRING
 //idea: id Software (Doom3), LordHavoc
 //darkplaces implementation: LordHavoc
@@ -657,6 +664,24 @@ float CVAR_TYPEFLAG_ENGINE = 8;
 float CVAR_TYPEFLAG_HASDESCRIPTION = 16;
 float CVAR_TYPEFLAG_READONLY = 32;
 
+//DP_QC_DIGEST
+//idea: motorsep, Spike
+//DarkPlaces implementation: divVerent
+//builtin definitions:
+string(string digest, string data, ...) digest_hex = #639;
+//description:
+//returns a given hex digest of given data
+//the returned digest is always encoded in hexadecimal
+//only the "MD4" digest is always supported!
+//if the given digest is not supported, string_null is returned
+//the digest string is matched case sensitively, use "MD4", not "md4"!
+
+//DP_QC_DIGEST_SHA256
+//idea: motorsep, Spike
+//DarkPlaces implementation: divVerent
+//description:
+//"SHA256" is also an allowed digest type
+
 //DP_QC_EDICT_NUM
 //idea: 515
 //DarkPlaces implementation: LordHavoc
@@ -882,6 +907,30 @@ float GETTIME_CDTRACK = 4;
 //returns the playing time of the current cdtrack when passed to gettime()
 //see DP_END_GETSOUNDTIME for similar functionality but for entity sound channels
 
+//DP_QC_I18N
+//idea: divVerent
+//darkplaces implementation: divVerent
+//description:
+//
+//The engine supports translating by gettext compatible .po files.
+//progs.dat uses progs.dat.<LANGUAGE>.po
+//menu.dat uses menu.dat.<LANGUAGE>.po
+//csprogs.dat uses csprogs.dat.<LANGUAGE>.po
+//
+//To create a string that can be translated, define it as
+//  string dotranslate_FILENOTFOUND = "File not found";
+//Note: if the compiler does constant folding, this will only work if there is
+//no other "File not found" string in the progs!
+//
+//Alternatively, if using the Xonotic patched fteqcc compiler, you can simplify
+//this by using _("File not found") directly in the source code.
+//
+//The language is set by the "prvm_language" cvar: if prvm_language is set to
+//"de", it will read progs.dat.de.po for translating strings in progs.dat.
+//
+//If prvm_language is set to to the special name "dump", progs.dat.pot which is
+//a translation template to be edited by filling out the msgstr entries.
+
 //DP_QC_LOG
 //darkplaces implementation: divVerent
 //builtin definitions:
@@ -1209,12 +1258,14 @@ float(string name, string value) registercvar = #93;
 
 //DP_SND_FAKETRACKS
 //idea: requested
+
 //darkplaces implementation: Elric
 //description:
 //the engine plays sound/cdtracks/track001.wav instead of cd track 1 and so on if found, this allows games and mods to have music tracks without using ambientsound.
 //Note: also plays .ogg with DP_SND_OGGVORBIS extension.
 
 //DP_SND_SOUND7_WIP1
+//DP_SND_SOUND7_WIP2
 //idea: divVerent
 //darkplaces implementation: divVerent
 //builtin definitions:
@@ -1225,8 +1276,9 @@ float SOUNDFLAG_RELIABLE = 1;
 //extensions to sound():
 //- channel may be in the range from -128 to 127; channels -128 to 0 are "auto",
 //  i.e. support multiple sounds at once, but cannot be stopped/restarted
-//- a speed parameter has been reserved for later addition of pitch shifting.
-//  it MUST be set to 0 for now, meaning "no pitch change"
+//- a value 0 in the speed parameter means no change; otherwise, it is a
+//  percentage of playback speed ("pitch shifting"). 100 is normal pitch, 50 is
+//  half speed, 200 is double speed, etc. (DP_SND_SOUND7_WIP2)
 //- the flag SOUNDFLAG_RELIABLE can be specified, which makes the sound send
 //  to MSG_ALL (reliable) instead of MSG_BROADCAST (unreliable, default);
 //  similarily, SOUNDFLAG_RELIABLE_TO_ONE sends to MSG_ONE
@@ -1614,6 +1666,8 @@ const float MOVETYPE_PHYSICS = 32; // need to be set before any physics_* builti
 const float SOLID_PHYSICS_BOX = 32;
 const float SOLID_PHYSICS_SPHERE = 33;
 const float SOLID_PHYSICS_CAPSULE = 34;
+const float SOLID_PHYSICS_TRIMESH = 35;
+const float SOLID_PHYSICS_CYLINDER = 36;
 //SOLID_BSP;
 //joint types:
 const float JOINTTYPE_POINT = 1;
@@ -1636,6 +1690,8 @@ const float JOINTTYPE_FIXED = -1;
 //   note that ODE does not support both in one anyway
 //field definitions:
 .float mass; // ODE mass, standart value is 1
+.vector massofs; // offsets a mass center out of object center, if not set a center of model bounds is used
+.float friction;
 .float bouncefactor;
 .float bouncestop;
 .float jointtype;
@@ -1646,7 +1702,6 @@ void(entity e, vector torque) physics_addtorque = #542; // add relative torque
 //description: provides Open Dynamics Engine support, requires extenal dll to be present or engine compiled with statical link option
 //be sure to checkextension for it to know if library is loaded and ready, also to enable physics set "physics_ode" cvar to 1
 //note: this extension is highly experimental and may be unstable
-//note: use SOLID_BSP on entities to get a trimesh collision models on them
 
 //DP_SV_PRINT
 //idea: id Software (QuakeWorld Server)
@@ -2397,13 +2452,6 @@ string(string search, string replace, string subject) strireplace = #485;
 //description:
 //strreplace replaces all occurrences of 'search' with 'replace' in the string 'subject', and returns the result as a tempstring.
 //strireplace does the same but uses case-insensitive matching of the 'search' term
-//
-//DP_QC_CRC16
-//idea: divVerent
-//darkplaces implementation: divVerent
-//Some hash function to build hash tables with. This has to be be the CRC-16-CCITT that is also required for the QuakeWorld download protocol.
-//When caseinsensitive is set, the CRC is calculated of the lower cased string.
-float(float caseinsensitive, string s, ...) crc16 = #494;
 
 //DP_SV_SHUTDOWN
 //idea: divVerent
index 4f655ca5738220c1dc75da1c95849f347b2cef68..5561c2df93ffa1bfea9b27361feab4f51c7507ca 100644 (file)
@@ -271,18 +271,22 @@ void GrapplingHookTouch (void)
 
 void GrapplingHook_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
-       if(self.health > 0)
+       if(self.health <= 0)
+               return;
+               
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
+               return; // g_balance_projectiledamage says to halt
+                       
+       self.health = self.health - damage;
+               
+       if (self.health <= 0)
        {
-               self.health = self.health - damage;
-               if (self.health <= 0)
+               if(attacker != self.realowner)
                {
-                       if(attacker != self.realowner)
-                       {
-                               self.realowner.pusher = attacker;
-                               self.realowner.pushltime = time + autocvar_g_maxpushtime;
-                       }
-                       RemoveGrapplingHook(self.realowner);
+                       self.realowner.pusher = attacker;
+                       self.realowner.pushltime = time + autocvar_g_maxpushtime;
                }
+               RemoveGrapplingHook(self.realowner);
        }
 }
 
@@ -324,6 +328,7 @@ void FireGrapplingHook (void)
        self.hook = missile;
        missile.reset = GrapplingHookReset;
        missile.classname = "grapplinghook";
+       missile.flags = FL_PROJECTILE;
 
        missile.movetype = MOVETYPE_FLY;
        PROJECTILE_MAKETRIGGER(missile);
@@ -349,6 +354,7 @@ void FireGrapplingHook (void)
        missile.event_damage = GrapplingHook_Damage;
        missile.takedamage = DAMAGE_AIM;
        missile.damageforcescale = 0;
+       missile.damagedbycontents = (autocvar_g_balance_grapplehook_damagedbycontents);
 
        missile.hook_start = missile.hook_end = missile.origin;
 
index 6407cefaa901351ada791a7e5e2dffb084d0fb18..19442cd6c23fbc9a40ec3b36154bba27faa8d157 100644 (file)
@@ -1642,7 +1642,7 @@ void spawnfunc_trigger_multivibrator()
        self.state = 0;
        self.use = multivibrator_toggle;
        self.think = multivibrator_send;
-       self.nextthink = time;
+       self.nextthink = max(1, time);
 
        IFTARGETED
                multivibrator_reset();
index 09daa245ac8c368016acb84ede41df05764c8f86..93157819efe8f6685c7594ba38e0f35942d0fe2a 100644 (file)
@@ -1356,7 +1356,7 @@ void IntermissionThink()
                return;
 
        if(!mapvote_initialized)
-               if (time < intermission_exittime + 10 && !self.BUTTON_ATCK && !self.BUTTON_JUMP && !self.BUTTON_ATCK2 && !self.BUTTON_HOOK && !self.BUTTON_USE)
+               if (time < intermission_exittime + 10 && !(self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE))
                        return;
 
        MapVote_Start();
index 9a848fa46ebbe7eda5bc4b49735165f1e8573f84..c80e9ca03e26f52a6c41aad5ae355ebd27f82393 100644 (file)
@@ -617,6 +617,7 @@ void GetCvars(float f)
        GetCvars_handleFloat(s, f, cvar_cl_allow_uid2name, "cl_allow_uid2name");
        GetCvars_handleFloat(s, f, cvar_cl_allow_uidtracking, "cl_allow_uidtracking");
        GetCvars_handleFloat(s, f, cvar_cl_movement_track_canjump, "cl_movement_track_canjump");
+       GetCvars_handleFloat(s, f, cvar_cl_newusekeysupported, "cl_newusekeysupported");
 
        // fixup of switchweapon (needed for LMS or when spectating is disabled, as PutClientInServer comes too early)
        if (f > 0)
@@ -1121,6 +1122,8 @@ string GetGametype(); // g_world.qc
 void readlevelcvars(void)
 {
        // first load all the mutators
+       if(cvar("g_invincible_projectiles"))
+               MUTATOR_ADD(mutator_invincibleprojectiles);
        if(cvar("g_nix"))
                MUTATOR_ADD(mutator_nix);
        if(cvar("g_dodging"))
@@ -2042,7 +2045,6 @@ float MAX_IPBAN_URIS           = 16;
 float URI_GET_DISCARD          = 0;
 float URI_GET_IPBAN            = 1;
 float URI_GET_IPBAN_END        = 16;
-float URI_GET_PLAYERSTATS_SENT = 17;
 
 void URI_Get_Callback(float id, float status, string data)
 {
@@ -2063,10 +2065,6 @@ void URI_Get_Callback(float id, float status, string data)
         // online ban list
         OnlineBanList_URI_Get_Callback(id, status, data);
     }
-    else if (id == URI_GET_PLAYERSTATS_SENT)
-    {
-        PlayerStats_Sent_URI_Get_Callback(id, status, data);
-    }
     else
     {
         print("Received HTTP request data for an invalid id ", ftos(id), ".\n");
index ceb3f207cc45d59c3f50d218a1c6ad61af75dc94..ee77b544597dcb7a345ef8ae3aa58ecc21907ac7 100644 (file)
@@ -259,6 +259,7 @@ void() walkmonster_start_go =
 // spread think times so they don't all happen at same time
        self.nextthink = self.nextthink + random()*0.5 + 0.1;
        self.iscreature = TRUE;
+       self.damagedbycontents = TRUE;
 
        force_retouch = 2; // mainly to detect teleports
 
@@ -352,6 +353,7 @@ void() flymonster_start_go =
                }
        }
        self.iscreature = TRUE;
+       self.damagedbycontents = TRUE;
 
        force_retouch = 2; // mainly to detect teleports
 
@@ -440,6 +442,7 @@ void() swimmonster_start_go =
                }
        }
        self.iscreature = TRUE;
+       self.damagedbycontents = TRUE;
 
        force_retouch = 2; // mainly to detect teleports
 
diff --git a/qcsrc/server/mutators/mutator_invincibleproj.qc b/qcsrc/server/mutators/mutator_invincibleproj.qc
new file mode 100644 (file)
index 0000000..d1ab520
--- /dev/null
@@ -0,0 +1,30 @@
+MUTATOR_HOOKFUNCTION(invincibleprojectiles_EditProjectile)
+{
+       if(other.health)
+       {
+               // disable health which in effect disables damage calculations
+               other.health = 0;
+       }
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(invincibleprojectiles_BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":InvincibleProjectiles");
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(invincibleprojectiles_BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Invincible Projectiles");
+       return 0;
+}
+
+MUTATOR_DEFINITION(mutator_invincibleprojectiles)
+{
+       MUTATOR_HOOK(EditProjectile, invincibleprojectiles_EditProjectile, CBC_ORDER_ANY);
+       MUTATOR_HOOK(BuildMutatorsString, invincibleprojectiles_BuildMutatorsString, CBC_ORDER_ANY);
+       MUTATOR_HOOK(BuildMutatorsPrettyString, invincibleprojectiles_BuildMutatorsPrettyString, CBC_ORDER_ANY);
+
+       return 0;
+}
index 6e85e7aff695290dfd75e2a9609ea06b233b4a84..519d51daa2510edd8f23ecef335e454127bd4f9c 100644 (file)
@@ -109,7 +109,7 @@ void NIX_GiveCurrentWeapon()
                entity e;
                e = get_weaponinfo(nix_weapon);
                if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
-                       self.weapon_load[nix_weapon] = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
+                       self.(weapon_load[nix_weapon]) = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
 
                // nex too
                if(autocvar_g_balance_nex_charge)
index d9fff4490467b77fd2f146dd68ec4a416882d6bb..1ae28abe54ff961700c030d9e305119aa51bd5ec 100644 (file)
@@ -2,6 +2,7 @@ MUTATOR_DECLARATION(gamemode_keyhunt);
 MUTATOR_DECLARATION(gamemode_freezetag);
 MUTATOR_DECLARATION(gamemode_keepaway);
 
+MUTATOR_DECLARATION(mutator_invincibleprojectiles);
 MUTATOR_DECLARATION(mutator_nix);
 MUTATOR_DECLARATION(mutator_dodging);
 MUTATOR_DECLARATION(mutator_rocketflying);
index 9f40a453ead2bfdad1a40fc0a4829e6051e8165b..c6e7701e0c0bfa6e4c3543e1eca7bcbafdc0ef2f 100644 (file)
@@ -17,7 +17,9 @@ void PlayerStats_Init()
        playerstats_db = db_create();
        if(playerstats_db >= 0)
                playerstats_waitforme = FALSE; // must wait for it at match end
-       
+
+       serverflags |= SERVERFLAG_PLAYERSTATS;  
+
        PlayerStats_AddEvent(PLAYERSTATS_ALIVETIME);
        PlayerStats_AddEvent(PLAYERSTATS_WINS);
        PlayerStats_AddEvent(PLAYERSTATS_MATCHES);
@@ -154,12 +156,6 @@ void PlayerStats_TeamScore(float t, string event_id, float value) // TODO: doesn
        db_put(playerstats_db, key, ftos(val));
 }
 
-void PlayerStats_Sent_URI_Get_Callback(float id, float status, string data)
-{
-       if(playerstats_requested)
-               playerstats_waitforme = TRUE;
-}
-
 /*
        format spec:
 
@@ -241,9 +237,7 @@ void PlayerStats_ready(entity fh, entity pass, float status)
                                }
                        }
                        url_fputs(fh, "\n");
-                       db_close(playerstats_db);
-                       playerstats_db = -1;
-                       url_fclose(fh, PlayerStats_ready, world);
+                       url_fclose(fh);
                        break;
                case URL_READY_CANREAD:
                        // url_fclose is processing, we got a response for writing the data
@@ -252,12 +246,14 @@ void PlayerStats_ready(entity fh, entity pass, float status)
                        while((s = url_fgets(fh)))
                                print("  ", s, "\n");
                        print("End of response.\n");
-                       url_fclose(fh, PlayerStats_ready, world);
+                       url_fclose(fh);
                        break;
                case URL_READY_CLOSED:
                        // url_fclose has finished
                        print("Player stats written\n");
                        playerstats_waitforme = TRUE;
+                       db_close(playerstats_db);
+                       playerstats_db = -1;
                        break;
                case URL_READY_ERROR:
                default:
@@ -283,8 +279,8 @@ void PlayerStats_Shutdown()
        uri = autocvar_g_playerstats_uri;
        if(uri != "")
        {
-               url_fopen(uri, FILE_APPEND, PlayerStats_ready, world);
                playerstats_waitforme = FALSE;
+               url_multi_fopen(uri, FILE_APPEND, PlayerStats_ready, world);
        }
        else
        {
@@ -295,6 +291,26 @@ void PlayerStats_Shutdown()
 }
 //#NO AUTOCVARS END
 
+void PlayerStats_Accuracy(entity p)
+{
+    entity a, w;
+    a = p.accuracy;
+    float i;
+
+    for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+    {
+        w = get_weaponinfo(i);
+
+        PlayerStats_Event(p, strcat("acc-", w.netname, "-hit"), a.(accuracy_hit[i-1]));
+        PlayerStats_Event(p, strcat("acc-", w.netname, "-fired"), a.(accuracy_fired[i-1]));
+
+        PlayerStats_Event(p, strcat("acc-", w.netname, "-cnt-hit"), a.(accuracy_cnt_hit[i-1]));
+        PlayerStats_Event(p, strcat("acc-", w.netname, "-cnt-fired"), a.(accuracy_cnt_fired[i-1]));
+
+        PlayerStats_Event(p, strcat("acc-", w.netname, "-frags"), a.(accuracy_frags[i-1]));
+    }
+}
+
 void PlayerStats_AddGlobalInfo(entity p)
 {
        if(playerstats_db < 0)
@@ -321,30 +337,12 @@ void PlayerStats_AddGlobalInfo(entity p)
        if(stof(db_get(playerstats_db, sprintf("%d:%s", p.playerstats_id, PLAYERSTATS_ALIVETIME))) > 0)
                PlayerStats_Event(p, PLAYERSTATS_JOINS, 1);
 
+       PlayerStats_Accuracy(p);
+
        strunzone(p.playerstats_id);
        p.playerstats_id = string_null;
 }
 
-void PlayerStats_Accuracy(entity p)
-{
-    entity a, w;
-    a = p.accuracy;
-    float i;
-
-    for(i = WEP_FIRST; i <= WEP_LAST; ++i)
-    {
-        w = get_weaponinfo(i);
-
-        PlayerStats_Event(p, strcat("acc-", w.netname, "-hit"), a.accuracy_hit[i-1]);
-        PlayerStats_Event(p, strcat("acc-", w.netname, "-fired"), a.accuracy_fired[i-1]);
-
-        PlayerStats_Event(p, strcat("acc-", w.netname, "-cnt-hit"), a.accuracy_cnt_hit[i-1]);
-        PlayerStats_Event(p, strcat("acc-", w.netname, "-cnt-fired"), a.accuracy_cnt_fired[i-1]);
-
-        PlayerStats_Event(p, strcat("acc-", w.netname, "-frags"), a.accuracy_frags[i-1]);
-    }
-}
-
 void PlayerStats_EndMatch(float finished)
 {
        entity p, winner;
index f546e560590025c124a4615905e07a2c15252a3e..b99366434b9e214bbeff607a333dc81f1d6271b6 100644 (file)
@@ -44,9 +44,6 @@ void PlayerStats_TeamScore(float t, string event_id, float value);
 // call at game over
 void PlayerStats_Shutdown(); // send stats to the server
 
-// URI GET callback
-void PlayerStats_Sent_URI_Get_Callback(float id, float status, string data);
-
 // call this whenever a player leaves
 void PlayerStats_AddGlobalInfo(entity p);
 
index c78b9f2fa5908c650ba76fd71cb0298146764599..3ad4de20c528c97cf48473f2ae2e58066a9279f0 100644 (file)
@@ -188,6 +188,7 @@ mutators/base.qc
 mutators/gamemode_keyhunt.qc
 mutators/gamemode_freezetag.qc
 mutators/gamemode_keepaway.qc
+mutators/mutator_invincibleproj.qc
 mutators/mutator_nix.qc
 mutators/mutator_dodging.qc
 mutators/mutator_rocketflying.qc
index 8d5fa100c92eec6bdc2f34a793ed917ccd7e5a92..782c567ceb09ab92b9c94cf5a00522a0aec71ed0 100644 (file)
@@ -56,7 +56,7 @@ float TeamScore_SendEntity(entity to, float sendflags)
 
        longflags = 0;
        for(i = 0, p = 1; i < MAX_TEAMSCORE; ++i, p *= 2)
-               if(self.teamscores[i] > 127 || self.teamscores[i] <= -128)
+               if(self.(teamscores[i]) > 127 || self.(teamscores[i]) <= -128)
                        longflags |= p;
 
 #if MAX_TEAMSCORE <= 8
@@ -70,9 +70,9 @@ float TeamScore_SendEntity(entity to, float sendflags)
                if(sendflags & p)
                {
                        if(longflags & p)
-                               WriteInt24_t(MSG_ENTITY, self.teamscores[i]);
+                               WriteInt24_t(MSG_ENTITY, self.(teamscores[i]));
                        else
-                               WriteChar(MSG_ENTITY, self.teamscores[i]);
+                               WriteChar(MSG_ENTITY, self.(teamscores[i]));
                }
 
        return TRUE;
@@ -222,7 +222,7 @@ float PlayerScore_SendEntity(entity to, float sendflags)
 
        longflags = 0;
        for(i = 0, p = 1; i < MAX_SCORE; ++i, p *= 2)
-               if(self.scores[i] > 127 || self.scores[i] <= -128)
+               if(self.(scores[i]) > 127 || self.(scores[i]) <= -128)
                        longflags |= p;
 
 #if MAX_SCORE <= 8
@@ -236,9 +236,9 @@ float PlayerScore_SendEntity(entity to, float sendflags)
                if(sendflags & p)
                {
                        if(longflags & p)
-                               WriteInt24_t(MSG_ENTITY, self.scores[i]);
+                               WriteInt24_t(MSG_ENTITY, self.(scores[i]));
                        else
-                               WriteChar(MSG_ENTITY, self.scores[i]);
+                               WriteChar(MSG_ENTITY, self.(scores[i]));
                }
 
        return TRUE;
index 15f43ad9eb730f980a1c40827213b13106c84a55..ce5828affc0194d1c051cf26b3412b6ff2688c61 100644 (file)
@@ -1,28 +1,31 @@
-
 void CreatureFrame (void)
 {
-       local entity oldself;
-       local float dm;
+       entity oldself;
+       float dm;
+       
        oldself = self;
-       for(self = world; (self = findfloat(self, iscreature, TRUE)); )
+       for(self = world; (self = findfloat(self, damagedbycontents, TRUE)); )
        {
-               if (self.movetype == MOVETYPE_NOCLIP)
-                       continue;
+               if (self.movetype == MOVETYPE_NOCLIP) { continue; }
+               
                float vehic = (self.vehicle_flags & VHF_ISVEHICLE);
-               if (self.waterlevel)
+               float projectile = (self.flags & FL_PROJECTILE);
+               
+               if (self.watertype <= CONTENT_WATER && self.waterlevel > 0) // workaround a retarded bug made by id software :P (yes, it's that old of a bug)
                {
                        if (!(self.flags & FL_INWATER))
                        {
                                self.flags |= FL_INWATER;
                                self.dmgtime = 0;
                        }
-                       if(!vehic) // vehicles don't drown
+
+                       if(!vehic && !projectile) // vehicles and projectiles don't drown
                        {
                                if (self.waterlevel != WATERLEVEL_SUBMERGED)
                                {
-                                       if(self.air_finished < time + 9)
+                                       if(self.air_finished < time)
                                                PlayerSound(playersound_gasp, CH_PLAYER, VOICETYPE_PLAYERSOUND);
-                                       self.air_finished = time + 12;
+                                       self.air_finished = time + autocvar_g_balance_contents_drowndelay;
                                        self.dmg = 2;
                                }
                                else if (self.air_finished < time)
@@ -30,31 +33,40 @@ void CreatureFrame (void)
                                        if (!self.deadflag)
                                        if (self.pain_finished < time)
                                        {
-                                               Damage (self, world, world, 5, DEATH_DROWN, self.origin, '0 0 0');
+                                               Damage (self, world, world, autocvar_g_balance_contents_playerdamage_drowning * autocvar_g_balance_contents_damagerate, DEATH_DROWN, self.origin, '0 0 0');
                                                self.pain_finished = time + 0.5;
                                        }
                                }
                        }
+                       
                        if (self.dmgtime < time)
                        {
-                               self.dmgtime = time + 0.2;
-                               if (self.watertype == CONTENT_LAVA)
+                               self.dmgtime = time + autocvar_g_balance_contents_damagerate; 
+                               
+                               if (!projectile)
                                {
-                                       if (self.watersound_finished < time)
+                                       if (self.watertype == CONTENT_LAVA)
                                        {
-                                               self.watersound_finished = time + 0.5;
-                                               sound (self, CH_PLAYER, "player/lava.wav", VOL_BASE, ATTN_NORM);
+                                               if (self.watersound_finished < time)
+                                               {
+                                                       self.watersound_finished = time + 0.5;
+                                                       sound (self, CH_PLAYER, "player/lava.wav", VOL_BASE, ATTN_NORM);
+                                               }
+                                               Damage (self, world, world, autocvar_g_balance_contents_playerdamage_lava * autocvar_g_balance_contents_damagerate * self.waterlevel, DEATH_LAVA, self.origin, '0 0 0');
                                        }
-                                       Damage (self, world, world, 6 * self.waterlevel, DEATH_LAVA, self.origin, '0 0 0');
-                               }
-                               else if (self.watertype == CONTENT_SLIME)
-                               {
-                                       if (self.watersound_finished < time)
+                                       else if (self.watertype == CONTENT_SLIME)
                                        {
-                                               self.watersound_finished = time + 0.5;
-                                               sound (self, CH_PLAYER, "player/slime.wav", VOL_BASE, ATTN_NORM);
+                                               if (self.watersound_finished < time)
+                                               {
+                                                       self.watersound_finished = time + 0.5;
+                                                       sound (self, CH_PLAYER, "player/slime.wav", VOL_BASE, ATTN_NORM);
+                                               }
+                                               Damage (self, world, world, autocvar_g_balance_contents_playerdamage_slime * autocvar_g_balance_contents_damagerate * self.waterlevel, DEATH_SLIME, self.origin, '0 0 0');
                                        }
-                                       Damage (self, world, world, 2 * self.waterlevel, DEATH_SLIME, self.origin, '0 0 0');
+                               }
+                               else if ((self.watertype == CONTENT_LAVA) || (self.watertype == CONTENT_SLIME))
+                               {
+                                       Damage (self, world, world, autocvar_g_balance_contents_projectiledamage * autocvar_g_balance_contents_damagerate * self.waterlevel, DEATH_SLIME, self.origin, '0 0 0');
                                }
                        }
                }
@@ -70,7 +82,7 @@ void CreatureFrame (void)
                        self.dmg = 2;
                }
 
-               if(!vehic) // vehicles don't get falling damage
+               if(!vehic && !projectile) // vehicles don't get falling damage
                {
                        // check for falling damage
                        float velocity_len = vlen(self.velocity);
index e069aec9f3d7e18c1d2f9af5cfecc21aa745cd80..02c15fb158bd0792533a2714dfbf38eaeb0d5ee2 100644 (file)
@@ -324,7 +324,11 @@ void WarpZone_PostTeleportPlayer_Callback(entity pl)
        UpdateCSQCProjectileAfterTeleport(pl);
        // "disown" projectiles after teleport
        if(pl.owner == pl.realowner)
+       {
+               if(!(pl.flags & FL_PROJECTILE))
+                       print("A non-projectile got through a warpzone and its owner cleared. It's a \n", pl.classname, ".\n");
                pl.owner = world;
+       }
        if(pl.classname == "player")
        {
                // reset tracking of oldvelocity for impact damage (sudden velocity changes)
index 86f5c44021ba6f987c8333e7fa5f3d456b82f8a4..4858cafc6ed549b950ba4498cfa439914898d896 100644 (file)
@@ -287,6 +287,7 @@ void turret_ewheel_dinit()
     self.damage_flags          |= TFL_DMG_DEATH_NOGIBS;
 
     self.iscreature = TRUE;
+    self.damagedbycontents = TRUE;
     self.movetype   = MOVETYPE_WALK;
     self.solid      = SOLID_SLIDEBOX;
     self.takedamage = DAMAGE_AIM;
index a438229cf5df53d264e077bebec549fa0c4970fc..feb4b1f67536bdf8ed3fc879d8db5a498a8809fa 100644 (file)
@@ -604,6 +604,7 @@ void turret_walker_dinit()
     self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
 
     self.iscreature = TRUE;
+    self.damagedbycontents = TRUE;
     self.movetype   = MOVETYPE_WALK;
     self.solid      = SOLID_SLIDEBOX;
     self.takedamage = DAMAGE_AIM;
index 6006dcf92edb6f0e2acf0bf3094211e1e4756e39..c4e2875380486575ed766684f7def98d1053ff28 100644 (file)
@@ -42,7 +42,7 @@ void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id)
     entity axh;
 
     axh_id = bound(0, axh_id, MAX_AXH);
-    axh = own.AuxiliaryXhair[axh_id];
+    axh = own.(AuxiliaryXhair[axh_id]);
 
     if(axh == world || wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
     {
@@ -56,7 +56,7 @@ void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id)
     setorigin(axh, loc);
     axh.colormod            = clr;
     axh.SendFlags           = 0x01;
-    own.AuxiliaryXhair[axh_id] = axh;
+    own.(AuxiliaryXhair[axh_id]) = axh;
 }
 
 /*
@@ -339,6 +339,7 @@ void vehicles_spawn()
     self.touch              = vehicles_touch;
     self.event_damage       = vehicles_damage;
     self.iscreature         = TRUE;
+    self.damagedbycontents     = TRUE;
     self.movetype           = MOVETYPE_WALK;
     self.solid              = SOLID_SLIDEBOX;
     self.takedamage         = DAMAGE_AIM;
@@ -974,6 +975,7 @@ float vehicle_initialize(string  net_name,
     self.takedamage         = DAMAGE_AIM;
     self.bot_attack         = TRUE;
     self.iscreature         = TRUE;
+    self.damagedbycontents     = TRUE;
     self.hud                = vhud;
 
     self.vehicle_die         = dieproc;
index f1e33ec968aec26b989f22dd29c7c98786ac0242..d0dd6eca6b3ae7bb19d2b3e62c009639b8c15d97 100644 (file)
@@ -541,6 +541,48 @@ void fireBullet (vector start, vector dir, float spread, float damage, float for
        trace_endpos = end;
 }
 
+float W_CheckProjectileDamage(entity inflictor, entity projowner, float deathtype, float exception)
+{
+       float is_from_contents = (deathtype == DEATH_SLIME || deathtype == DEATH_LAVA);
+       float is_from_owner = (inflictor == projowner);
+       float is_from_exception = (exception != -1);
+       
+       //print(strcat("from_contents ", ftos(is_from_contents), " : from_owner ", ftos(is_from_owner), " : exception ", strcat(ftos(is_from_exception), " (", ftos(exception), "). \n")));
+
+       if(autocvar_g_projectiles_damage <= -2)
+       {
+               return FALSE; // no damage to projectiles at all, not even with the exceptions
+       }
+       else if(autocvar_g_projectiles_damage == -1)
+       {
+               if(is_from_exception)
+                       return (exception); // if exception is detected, allow it to override
+               else
+                       return FALSE; // otherwise, no other damage is allowed
+       }
+       else if(autocvar_g_projectiles_damage == 0)
+       {
+               if(is_from_exception)
+                       return (exception); // if exception is detected, allow it to override
+               else if not(is_from_contents)
+                       return FALSE; // otherwise, only allow damage from contents
+       }       
+       else if(autocvar_g_projectiles_damage == 1)
+       {
+               if(is_from_exception)
+                       return (exception); // if exception is detected, allow it to override
+               else if not(is_from_contents || is_from_owner)
+                       return FALSE; // otherwise, only allow self damage and damage from contents
+       }
+       else if(autocvar_g_projectiles_damage == 2) // allow any damage, but override for exceptions
+       {
+               if(is_from_exception)
+                       return (exception); // if exception is detected, allow it to override
+       }
+
+       return TRUE; // if none of these return, then allow damage anyway.
+}
+
 void W_PrepareExplosionByDamage(entity attacker, void() explode)
 {
        self.takedamage = DAMAGE_NO;
index 3866284a4c2007efeb3c0e55c99ec32044a2bc6e..aa72d8ec1736590dc0c1bb42b8f2489d289a7bea 100644 (file)
@@ -616,7 +616,7 @@ float w_crylink(float req)
                        return TRUE;
 
                ammo_amount = self.ammo_cells >= autocvar_g_balance_crylink_primary_ammo;
-               ammo_amount += self.weapon_load[WEP_CRYLINK] >= autocvar_g_balance_crylink_primary_ammo;
+               ammo_amount += self.(weapon_load[WEP_CRYLINK]) >= autocvar_g_balance_crylink_primary_ammo;
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
@@ -626,7 +626,7 @@ float w_crylink(float req)
                        return TRUE;
 
                ammo_amount = self.ammo_cells >= autocvar_g_balance_crylink_secondary_ammo;
-               ammo_amount += self.weapon_load[WEP_CRYLINK] >= autocvar_g_balance_crylink_secondary_ammo;
+               ammo_amount += self.(weapon_load[WEP_CRYLINK]) >= autocvar_g_balance_crylink_secondary_ammo;
                return ammo_amount;
        }
        else if (req == WR_RELOAD)
index 526d4cd32d6253ff11f5b07022f8e76bd0b369f7..b127f5cbac8523d41e5059b84e2d34243181236a 100644 (file)
@@ -83,13 +83,19 @@ void W_Plasma_Damage (entity inflictor, entity attacker, float damage, float dea
 {
        if(self.health <= 0)
                return;
+
        // note: combos are usually triggered by W_Plasma_TriggerCombo, not damage
+       float is_combo = (inflictor.classname == "plasma_chain" || inflictor.classname == "plasma_prim");
+       
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, (is_combo ? 1 : -1)))
+               return; // g_projectiles_damage says to halt    
+       
        self.health = self.health - damage;
        if (self.health <= 0)
        {
                self.takedamage = DAMAGE_NO;
                self.nextthink = time;
-               if (inflictor.classname == "plasma_chain" || inflictor.classname == "plasma_prim")
+               if (is_combo)
                {
                        // change owner to whoever caused the combo explosion
                        self.realowner = inflictor.realowner;
@@ -175,6 +181,7 @@ void W_Electro_Attack2()
        proj.health = autocvar_g_balance_electro_secondary_health;
        proj.event_damage = W_Plasma_Damage;
        proj.flags = FL_PROJECTILE;
+       proj.damagedbycontents = (autocvar_g_balance_electro_secondary_damagedbycontents);
 
        proj.bouncefactor = autocvar_g_balance_electro_secondary_bouncefactor;
        proj.bouncestop = autocvar_g_balance_electro_secondary_bouncestop;
@@ -268,7 +275,7 @@ void lgbeam_think()
                        {
                                dt = min(dt, owner_player.clip_load / autocvar_g_balance_electro_primary_ammo);
                                owner_player.clip_load = max(0, owner_player.clip_load - autocvar_g_balance_electro_primary_ammo * frametime);
-                               owner_player.weapon_load[WEP_ELECTRO] = owner_player.clip_load;
+                               owner_player.(weapon_load[WEP_ELECTRO]) = owner_player.clip_load;
                        }
                        else
                        {
@@ -507,19 +514,19 @@ float w_electro(float req)
                                ammo_amount = 1;
                        else
                                ammo_amount = self.ammo_cells > 0;
-                       ammo_amount += self.weapon_load[WEP_ELECTRO] > 0;
+                       ammo_amount += self.(weapon_load[WEP_ELECTRO]) > 0;
                }
                else
                {
                        ammo_amount = self.ammo_cells >= autocvar_g_balance_electro_primary_ammo;
-                       ammo_amount += self.weapon_load[WEP_ELECTRO] >= autocvar_g_balance_electro_primary_ammo;
+                       ammo_amount += self.(weapon_load[WEP_ELECTRO]) >= autocvar_g_balance_electro_primary_ammo;
                }
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
        {
                ammo_amount = self.ammo_cells >= autocvar_g_balance_electro_secondary_ammo;
-               ammo_amount += self.weapon_load[WEP_ELECTRO] >= autocvar_g_balance_electro_secondary_ammo;
+               ammo_amount += self.(weapon_load[WEP_ELECTRO]) >= autocvar_g_balance_electro_secondary_ammo;
                return ammo_amount;
        }
        else if (req == WR_RESETPLAYER)
index d916edd9f60e18005a6700223f5256f88cbc1d5d..31e5b6a02ebaf8d125bd3c57f3752e06aa37640a 100644 (file)
@@ -115,6 +115,10 @@ void W_Fireball_Damage (entity inflictor, entity attacker, float damage, float d
 {
        if(self.health <= 0)
                return;
+               
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
+               return; // g_projectiles_damage says to halt
+               
        self.health = self.health - damage;
        if (self.health <= 0)
        {
@@ -365,13 +369,13 @@ float w_fireball(float req)
        else if (req == WR_CHECKAMMO1)
        {
                ammo_amount = self.ammo_fuel >= autocvar_g_balance_fireball_primary_ammo;
-               ammo_amount += self.weapon_load[WEP_FIREBALL] >= autocvar_g_balance_fireball_primary_ammo;
+               ammo_amount += self.(weapon_load[WEP_FIREBALL]) >= autocvar_g_balance_fireball_primary_ammo;
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
        {
                ammo_amount = self.ammo_fuel >= autocvar_g_balance_fireball_secondary_ammo;
-               ammo_amount += self.weapon_load[WEP_FIREBALL] >= autocvar_g_balance_fireball_secondary_ammo;
+               ammo_amount += self.(weapon_load[WEP_FIREBALL]) >= autocvar_g_balance_fireball_secondary_ammo;
                return ammo_amount;
        }
        else if (req == WR_RESETPLAYER)
index 1d2ee93b9a2cfb8778d290f69f5071b0491b55ed..223d89fda8472da66066175f6fb66135b5279f98 100644 (file)
@@ -49,11 +49,14 @@ void W_Grenade_Damage (entity inflictor, entity attacker, float damage, float de
 {
        if (self.health <= 0)
                return;
+               
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
+               return; // g_projectiles_damage says to halt
+               
        self.health = self.health - damage;
+       
        if (self.health <= 0)
-       {
-               W_PrepareExplosionByDamage(attacker, self.think);
-       }
+               W_PrepareExplosionByDamage(attacker, self.use);
 }
 
 void W_Grenade_Think1 (void)
@@ -196,6 +199,7 @@ void W_Grenade_Attack (void)
        gren.health = autocvar_g_balance_grenadelauncher_primary_health;
        gren.damageforcescale = autocvar_g_balance_grenadelauncher_primary_damageforcescale;
        gren.event_damage = W_Grenade_Damage;
+       gren.damagedbycontents = TRUE;
        W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_primary);
 
        gren.angles = vectoangles (gren.velocity);
@@ -242,6 +246,7 @@ void W_Grenade_Attack2 (void)
        gren.health = autocvar_g_balance_grenadelauncher_secondary_health;
        gren.damageforcescale = autocvar_g_balance_grenadelauncher_secondary_damageforcescale;
        gren.event_damage = W_Grenade_Damage;
+       gren.damagedbycontents = TRUE;
        W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_secondary);
 
        gren.angles = vectoangles (gren.velocity);
@@ -346,13 +351,13 @@ float w_glauncher(float req)
        else if (req == WR_CHECKAMMO1)
        {
                ammo_amount = self.ammo_rockets >= autocvar_g_balance_grenadelauncher_primary_ammo;
-               ammo_amount += self.weapon_load[WEP_GRENADE_LAUNCHER] >= autocvar_g_balance_grenadelauncher_primary_ammo;
+               ammo_amount += self.(weapon_load[WEP_GRENADE_LAUNCHER]) >= autocvar_g_balance_grenadelauncher_primary_ammo;
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
        {
                ammo_amount = self.ammo_rockets >= autocvar_g_balance_grenadelauncher_secondary_ammo;
-               ammo_amount += self.weapon_load[WEP_GRENADE_LAUNCHER] >= autocvar_g_balance_grenadelauncher_secondary_ammo;
+               ammo_amount += self.(weapon_load[WEP_GRENADE_LAUNCHER]) >= autocvar_g_balance_grenadelauncher_secondary_ammo;
                return ammo_amount;
        }
        else if (req == WR_RELOAD)
index 080eea39e453fe7ed7a7704bc1d6d8aae3321e45..7d9db5c39fb67f9aeb00031712997cbd1fa0a85a 100644 (file)
@@ -20,6 +20,30 @@ void W_Hagar_Explode2 (void)
        remove (self);
 }
 
+void W_Hagar_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+       if (self.health <= 0)
+               return;
+               
+       float is_linkexplode = ((inflictor.realowner == self.realowner) 
+               && (inflictor.projectiledeathtype & HITTYPE_SECONDARY) 
+               && (self.projectiledeathtype & HITTYPE_SECONDARY));
+       
+       if(is_linkexplode)
+               is_linkexplode = (is_linkexplode && autocvar_g_balance_hagar_secondary_load_linkexplode);
+       else
+               is_linkexplode = -1; // not secondary load, so continue as normal without exception.
+               
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, is_linkexplode))
+               return; // g_projectiles_damage says to halt
+
+       self.health = self.health - damage;
+       self.angles = vectoangles(self.velocity);
+       
+       if (self.health <= 0)
+               W_PrepareExplosionByDamage(attacker, self.think);
+}
+
 void W_Hagar_Touch (void)
 {
        PROJECTILE_TOUCH;
@@ -56,6 +80,13 @@ void W_Hagar_Attack (void)
        missile.classname = "missile";
        missile.bot_dodge = TRUE;
        missile.bot_dodgerating = autocvar_g_balance_hagar_primary_damage;
+       
+       missile.takedamage = DAMAGE_YES;
+       missile.health = autocvar_g_balance_hagar_primary_health;
+       missile.damageforcescale = autocvar_g_balance_hagar_primary_damageforcescale;
+       missile.event_damage = W_Hagar_Damage;
+       missile.damagedbycontents = TRUE;
+       
        missile.touch = W_Hagar_Touch;
        missile.use = W_Hagar_Explode;
        missile.think = adaptor_think2use_hittype_splash;
@@ -91,6 +122,13 @@ void W_Hagar_Attack2 (void)
        missile.classname = "missile";
        missile.bot_dodge = TRUE;
        missile.bot_dodgerating = autocvar_g_balance_hagar_secondary_damage;
+       
+       missile.takedamage = DAMAGE_YES;
+       missile.health = autocvar_g_balance_hagar_secondary_health;
+       missile.damageforcescale = autocvar_g_balance_hagar_secondary_damageforcescale;
+       missile.event_damage = W_Hagar_Damage;
+       missile.damagedbycontents = TRUE;
+
        missile.touch = W_Hagar_Touch2;
        missile.cnt = 0;
        missile.use = W_Hagar_Explode2;
@@ -112,7 +150,7 @@ void W_Hagar_Attack2 (void)
        other = missile; MUTATOR_CALLHOOK(EditProjectile);
 }
 
-.float hagar_loadstep, hagar_loadblock, hagar_loadbeep;
+.float hagar_loadstep, hagar_loadblock, hagar_loadbeep, hagar_warning;
 void W_Hagar_Attack2_Load_Release (void)
 {
        // time to release the rockets we've loaded
@@ -143,13 +181,19 @@ void W_Hagar_Attack2_Load_Release (void)
                missile.classname = "missile";
                missile.bot_dodge = TRUE;
                missile.bot_dodgerating = autocvar_g_balance_hagar_secondary_damage;
+               
+               missile.takedamage = DAMAGE_YES;
+               missile.health = autocvar_g_balance_hagar_secondary_health;
+               missile.damageforcescale = autocvar_g_balance_hagar_secondary_damageforcescale;
+               missile.event_damage = W_Hagar_Damage;
+               missile.damagedbycontents = TRUE;
 
                missile.touch = W_Hagar_Touch; // not bouncy
                missile.use = W_Hagar_Explode2;
                missile.think = adaptor_think2use_hittype_splash;
                missile.nextthink = time + autocvar_g_balance_hagar_secondary_lifetime_min + random() * autocvar_g_balance_hagar_secondary_lifetime_rand;
                PROJECTILE_MAKETRIGGER(missile);
-               missile.projectiledeathtype = WEP_HAGAR;
+               missile.projectiledeathtype = WEP_HAGAR | HITTYPE_SECONDARY;
                setorigin (missile, w_shotorg);
                setsize(missile, '0 0 0', '0 0 0');
                missile.movetype = MOVETYPE_FLY;
@@ -183,7 +227,7 @@ void W_Hagar_Attack2_Load_Release (void)
                counter = counter + 1;
        }
 
-       weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_hagar_secondary_refire, w_ready);
+       weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_hagar_secondary_load_animtime, w_ready);
        self.hagar_loadstep = time + autocvar_g_balance_hagar_secondary_refire * W_WeaponRateFactor();
        self.hagar_load = 0;
 }
@@ -197,7 +241,7 @@ void W_Hagar_Attack2_Load (void)
 
        // this is different than WR_CHECKAMMO when it comes to reloading
        if(autocvar_g_balance_hagar_reload_ammo)
-               enough_ammo = self.weapon_load[WEP_HAGAR] >= autocvar_g_balance_hagar_secondary_ammo;
+               enough_ammo = self.(weapon_load[WEP_HAGAR]) >= autocvar_g_balance_hagar_secondary_ammo;
        else
                enough_ammo = self.ammo_rockets >= autocvar_g_balance_hagar_secondary_ammo;
 
@@ -230,9 +274,12 @@ void W_Hagar_Attack2_Load (void)
                                        W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_hagar_secondary_ammo, autocvar_g_balance_hagar_reload_ammo);
                                        self.weaponentity.state = WS_INUSE;
                                        self.hagar_load += 1;
-                                       sound(self, CH_WEAPON_B, "weapons/hagar_load.wav", VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_WEAPON_B, "weapons/hagar_load.wav", VOL_BASE * 0.8, ATTN_NORM); // sound is too loud according to most
 
-                                       self.hagar_loadstep = time + autocvar_g_balance_hagar_secondary_load_speed * W_WeaponRateFactor();
+                                       if (self.hagar_load >= autocvar_g_balance_hagar_secondary_load_max)
+                                               self.hagar_loadstep = time + autocvar_g_balance_hagar_secondary_load_hold * W_WeaponRateFactor();
+                                       else
+                                               self.hagar_loadstep = time + autocvar_g_balance_hagar_secondary_load_speed * W_WeaponRateFactor();
                                }
                        }
                        else if(!self.hagar_loadbeep && self.hagar_load) // prevents the beep from playing each frame
@@ -251,7 +298,19 @@ void W_Hagar_Attack2_Load (void)
 
        if(self.hagar_load)
        {
-               if(!self.BUTTON_ATCK2 || ((loaded || !enough_ammo) && self.hagar_loadstep < time && !autocvar_g_balance_hagar_secondary_load_hold))
+               // play warning sound if we're about to release
+               if((loaded || !enough_ammo) && self.hagar_loadstep - 0.5 < time && autocvar_g_balance_hagar_secondary_load_hold >= 0)
+               {
+                       if(!self.hagar_warning && self.hagar_load) // prevents the beep from playing each frame
+                       {
+                               // we're about to automatically release after holding time, play a beep sound to notify the player
+                               sound(self, CH_WEAPON_A, "weapons/hagar_beep.wav", VOL_BASE, ATTN_NORM);
+                               self.hagar_warning = TRUE;
+                       }
+               }
+               
+               // release if player let go of button or if they've held it in too long
+               if(!self.BUTTON_ATCK2 || ((loaded || !enough_ammo) && self.hagar_loadstep < time && autocvar_g_balance_hagar_secondary_load_hold >= 0))
                {
                        self.weaponentity.state = WS_READY;
                        W_Hagar_Attack2_Load_Release();
@@ -260,6 +319,7 @@ void W_Hagar_Attack2_Load (void)
        else
        {
                self.hagar_loadbeep = FALSE;
+               self.hagar_warning = FALSE;
        }
 
        // we aren't checking ammo during an attack, so we must do it here
@@ -347,13 +407,13 @@ float w_hagar(float req)
        else if (req == WR_CHECKAMMO1)
        {
                ammo_amount = self.ammo_rockets >= autocvar_g_balance_hagar_primary_ammo;
-               ammo_amount += self.weapon_load[WEP_HAGAR] >= autocvar_g_balance_hagar_primary_ammo;
+               ammo_amount += self.(weapon_load[WEP_HAGAR]) >= autocvar_g_balance_hagar_primary_ammo;
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
        {
                ammo_amount = self.ammo_rockets >= autocvar_g_balance_hagar_secondary_ammo;
-               ammo_amount += self.weapon_load[WEP_HAGAR] >= autocvar_g_balance_hagar_secondary_ammo;
+               ammo_amount += self.(weapon_load[WEP_HAGAR]) >= autocvar_g_balance_hagar_secondary_ammo;
                return ammo_amount;
        }
        else if (req == WR_RESETPLAYER)
index 978ac5f4a4df38316360403e436aad260974183a..0a163e2f98affc699d87da07e3ddcb69b0a8dd2d 100644 (file)
@@ -205,13 +205,13 @@ float w_hlac(float req)
        else if (req == WR_CHECKAMMO1)
        {
                ammo_amount = self.ammo_cells >= autocvar_g_balance_hlac_primary_ammo;
-               ammo_amount += self.weapon_load[WEP_HLAC] >= autocvar_g_balance_hlac_primary_ammo;
+               ammo_amount += self.(weapon_load[WEP_HLAC]) >= autocvar_g_balance_hlac_primary_ammo;
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
        {
                ammo_amount = self.ammo_cells >= autocvar_g_balance_hlac_secondary_ammo;
-               ammo_amount += self.weapon_load[WEP_HLAC] >= autocvar_g_balance_hlac_secondary_ammo;
+               ammo_amount += self.(weapon_load[WEP_HLAC]) >= autocvar_g_balance_hlac_secondary_ammo;
                return ammo_amount;
        }
        else if (req == WR_RELOAD)
index 754ffff909bf1a90a75976f115e86d70f8c9bef5..b6b90f6937070490c4de6c95d775b2a5f2d07096 100644 (file)
@@ -52,6 +52,20 @@ void W_Hook_Explode2 (void)
        self.movetype = MOVETYPE_NONE;
 }
 
+void W_Hook_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+       if (self.health <= 0)
+               return;
+               
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
+               return; // g_projectiles_damage says to halt    
+       
+       self.health = self.health - damage;
+       
+       if (self.health <= 0)
+               W_PrepareExplosionByDamage(self.realowner, W_Hook_Explode2);
+}
+
 void W_Hook_Touch2 (void)
 {
        PROJECTILE_TOUCH;
@@ -80,6 +94,12 @@ void W_Hook_Attack2()
        gren.think = adaptor_think2use_hittype_splash;
        gren.use = W_Hook_Explode2;
        gren.touch = W_Hook_Touch2;
+       
+       gren.takedamage = DAMAGE_YES;
+       gren.health = autocvar_g_balance_hook_secondary_health;
+       gren.damageforcescale = autocvar_g_balance_hook_secondary_damageforcescale;
+       gren.event_damage = W_Hook_Damage;
+       gren.damagedbycontents = TRUE;
 
        gren.velocity = '0 0 1' * autocvar_g_balance_hook_secondary_speed;
        if(autocvar_g_projectiles_newton_style)
index 4e56d2d94ed99916ff21662fa019e944100785ab..1012f9a81a82ab14059516f1d858bf9c8bdb79ba 100644 (file)
@@ -38,6 +38,7 @@ void W_Mine_Stick (entity to)
        newmine.health = self.health;
        newmine.event_damage = self.event_damage;
        newmine.spawnshieldtime = self.spawnshieldtime;
+       newmine.damagedbycontents = TRUE;
 
        newmine.movetype = MOVETYPE_NONE; // lock the mine in place
        newmine.projectiledeathtype = self.projectiledeathtype;
@@ -241,8 +242,15 @@ void W_Mine_Damage (entity inflictor, entity attacker, float damage, float death
 {
        if (self.health <= 0)
                return;
+               
+       float is_from_enemy = (inflictor.realowner != self.realowner);
+               
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, (is_from_enemy ? 1 : -1)))
+               return; // g_projectiles_damage says to halt
+               
        self.health = self.health - damage;
        self.angles = vectoangles(self.velocity);
+       
        if (self.health <= 0)
                W_PrepareExplosionByDamage(attacker, W_Mine_Explode);
 }
@@ -284,6 +292,7 @@ void W_Mine_Attack (void)
        mine.damageforcescale = autocvar_g_balance_minelayer_damageforcescale;
        mine.health = autocvar_g_balance_minelayer_health;
        mine.event_damage = W_Mine_Damage;
+       mine.damagedbycontents = TRUE;
 
        mine.movetype = MOVETYPE_TOSS;
        PROJECTILE_MAKETRIGGER(mine);
@@ -486,7 +495,7 @@ float w_minelayer(float req)
                if (ATTACK_FINISHED(self) <= time || self.weapon != WEP_MINE_LAYER)
                {
                        ammo_amount = self.ammo_rockets >= autocvar_g_balance_minelayer_ammo;
-                       ammo_amount += self.weapon_load[WEP_MINE_LAYER] >= autocvar_g_balance_minelayer_ammo;
+                       ammo_amount += self.(weapon_load[WEP_MINE_LAYER]) >= autocvar_g_balance_minelayer_ammo;
                        return ammo_amount;
                }
        }
index 16cbdcded3778eb1bb7988991ecbeb39a11c54ec..10014a7e1b2fb7f794a24b6fdef0c21f79eb9d9f 100644 (file)
@@ -246,7 +246,7 @@ float w_minstanex(float req)
        else if (req == WR_CHECKAMMO1)
        {
                ammo_amount = self.ammo_cells >= minstanex_ammo;
-               ammo_amount += self.weapon_load[WEP_MINSTANEX] >= minstanex_ammo;
+               ammo_amount += self.(weapon_load[WEP_MINSTANEX]) >= minstanex_ammo;
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
@@ -254,7 +254,7 @@ float w_minstanex(float req)
                if(!autocvar_g_balance_minstanex_laser_ammo)
                        return TRUE;
                ammo_amount = self.ammo_cells >= autocvar_g_balance_minstanex_laser_ammo;
-               ammo_amount += self.weapon_load[WEP_MINSTANEX] >= autocvar_g_balance_minstanex_laser_ammo;
+               ammo_amount += self.(weapon_load[WEP_MINSTANEX]) >= autocvar_g_balance_minstanex_laser_ammo;
                return ammo_amount;
        }
        else if (req == WR_RESETPLAYER)
index f9367059555cca67c033a8311e593e9bfc152a81..802298912d96eb774796b893d222705f92eeb754 100644 (file)
@@ -161,7 +161,7 @@ float w_nex(float req)
                                                                                {
                                                                                        self.clip_load = max(autocvar_g_balance_nex_secondary_ammo, self.clip_load - autocvar_g_balance_nex_secondary_ammo * dt);
                                                                                }
-                                                                               self.weapon_load[WEP_NEX] = self.clip_load;
+                                                                               self.(weapon_load[WEP_NEX]) = self.clip_load;
                                                                        }
                                                                        else
                                                                        {
@@ -216,14 +216,14 @@ float w_nex(float req)
        else if (req == WR_CHECKAMMO1)
        {
                ammo_amount = self.ammo_cells >= autocvar_g_balance_nex_primary_ammo;
-               ammo_amount += (autocvar_g_balance_nex_reload_ammo && self.weapon_load[WEP_NEX] >= autocvar_g_balance_nex_primary_ammo);
+               ammo_amount += (autocvar_g_balance_nex_reload_ammo && self.(weapon_load[WEP_NEX]) >= autocvar_g_balance_nex_primary_ammo);
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
        {
                // don't allow charging if we don't have enough ammo
                ammo_amount = self.ammo_cells >= autocvar_g_balance_nex_secondary_ammo;
-               ammo_amount += self.weapon_load[WEP_NEX] >= autocvar_g_balance_nex_secondary_ammo;
+               ammo_amount += self.(weapon_load[WEP_NEX]) >= autocvar_g_balance_nex_secondary_ammo;
                return ammo_amount;
        }
        else if (req == WR_RELOAD)
index 02d859e0fdf854c734e8739111a8bf19aa5558b2..941a528a4b0b4fa9eac087b0222cc3c4d60b9d93 100644 (file)
@@ -183,13 +183,13 @@ float w_rifle(float req)
        else if (req == WR_CHECKAMMO1)
        {
                ammo_amount = self.ammo_nails >= autocvar_g_balance_rifle_primary_ammo;
-               ammo_amount += self.weapon_load[WEP_RIFLE] >= autocvar_g_balance_rifle_primary_ammo;
+               ammo_amount += self.(weapon_load[WEP_RIFLE]) >= autocvar_g_balance_rifle_primary_ammo;
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
        {
                ammo_amount = self.ammo_nails >= autocvar_g_balance_rifle_secondary_ammo;
-               ammo_amount += self.weapon_load[WEP_RIFLE] >= autocvar_g_balance_rifle_secondary_ammo;
+               ammo_amount += self.(weapon_load[WEP_RIFLE]) >= autocvar_g_balance_rifle_secondary_ammo;
                return ammo_amount;
        }
        else if (req == WR_RESETPLAYER)
index b4987b69f9bcf62a9729c428d35009f1024a1953..4abfa0d5000d19b173039a2c44dc8d761cf374bd 100644 (file)
@@ -238,8 +238,13 @@ void W_Rocket_Damage (entity inflictor, entity attacker, float damage, float dea
 {
        if (self.health <= 0)
                return;
+       
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
+               return; // g_projectiles_damage says to halt
+               
        self.health = self.health - damage;
        self.angles = vectoangles(self.velocity);
+       
        if (self.health <= 0)
                W_PrepareExplosionByDamage(attacker, W_Rocket_Explode);
 }
@@ -270,6 +275,7 @@ void W_Rocket_Attack (void)
        missile.damageforcescale = autocvar_g_balance_rocketlauncher_damageforcescale;
        missile.health = autocvar_g_balance_rocketlauncher_health;
        missile.event_damage = W_Rocket_Damage;
+       missile.damagedbycontents = TRUE;
 
        missile.movetype = MOVETYPE_FLY;
        PROJECTILE_MAKETRIGGER(missile);
@@ -461,7 +467,7 @@ float w_rlauncher(float req)
                {
                        if(autocvar_g_balance_rocketlauncher_reload_ammo)
                        {
-                               if(self.ammo_rockets < autocvar_g_balance_rocketlauncher_ammo && self.weapon_load[WEP_ROCKET_LAUNCHER] < autocvar_g_balance_rocketlauncher_ammo)
+                               if(self.ammo_rockets < autocvar_g_balance_rocketlauncher_ammo && self.(weapon_load[WEP_ROCKET_LAUNCHER]) < autocvar_g_balance_rocketlauncher_ammo)
                                        ammo_amount = TRUE;
                        }
                        else if(self.ammo_rockets < autocvar_g_balance_rocketlauncher_ammo)
index c108ba3cfa1707f3b69ea2135a93c4c92e58cbbd..40c119035a0fca2a7fe688d254e6c5e2cb038035 100644 (file)
@@ -124,6 +124,9 @@ void Seeker_Missile_Damage (entity inflictor, entity attacker, float damage, flo
 {
        if (self.health <= 0)
                return;
+               
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
+               return; // g_projectiles_damage says to halt
 
        if (self.realowner == attacker)
                self.health = self.health - (damage * 0.25);
@@ -189,6 +192,7 @@ void Seeker_Fire_Missile(vector f_diff, entity m_target)
        missile.takedamage      = DAMAGE_YES;
        missile.health          = autocvar_g_balance_seeker_missile_health;
        missile.damageforcescale = autocvar_g_balance_seeker_missile_damageforcescale;
+       missile.damagedbycontents = TRUE;
        //missile.think           = Seeker_Missile_Animate; // csqc projectiles.
        
        if (missile.enemy != world)
@@ -588,13 +592,13 @@ float w_seeker(float req)
        else if (req == WR_CHECKAMMO1)
        {
                ammo_amount = self.ammo_rockets >= autocvar_g_balance_seeker_missile_ammo;
-               ammo_amount += self.weapon_load[WEP_SEEKER] >= autocvar_g_balance_seeker_missile_ammo;
+               ammo_amount += self.(weapon_load[WEP_SEEKER]) >= autocvar_g_balance_seeker_missile_ammo;
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
        {
                ammo_amount = self.ammo_rockets >= autocvar_g_balance_seeker_tag_ammo;
-               ammo_amount += self.weapon_load[WEP_SEEKER] >= autocvar_g_balance_seeker_tag_ammo;
+               ammo_amount += self.(weapon_load[WEP_SEEKER]) >= autocvar_g_balance_seeker_tag_ammo;
                return ammo_amount;
        }
        else if (req == WR_RELOAD)
index a9d1ba056aca2f2691e731acccf9257161009425..b21a5f50a745581435c0012bd2fcb9605678a021 100644 (file)
@@ -46,47 +46,98 @@ void W_Shotgun_Attack (void)
        W_AttachToShotorg(flash, '5 0 0');
 }
 
-entity lgbeam_owner_ent;
+.float swing_prev;
+.entity swing_alreadyhit;
 void shotgun_meleethink (void)
 {
-       // store time when we started swinging down inside self.cnt
-       if(!self.cnt)
-               self.cnt = time;
-
-       makevectors(self.realowner.v_angle);
-       vector angle;
-       angle = v_forward;
-
-       float meleetime;
-       meleetime = autocvar_g_balance_shotgun_secondary_melee_time * W_WeaponRateFactor();
-
-       // perform trace
-       float f;
-       f = (self.cnt + meleetime - time) / meleetime * 2 - 1;
+       // declarations
+       float i, f, swing, swing_factor, swing_damage, meleetime, is_player;
        vector targpos;
-       targpos = self.realowner.origin + self.realowner.view_ofs + angle * autocvar_g_balance_shotgun_secondary_melee_range + v_right * f * autocvar_g_balance_shotgun_secondary_melee_swing + v_up * f * autocvar_g_balance_shotgun_secondary_melee_swing;
 
-       if(!lgbeam_owner_ent)
+       if(!self.cnt) // set start time of melee
        {
-               lgbeam_owner_ent = spawn();
-               lgbeam_owner_ent.classname = "lgbeam_owner_ent";
+               self.cnt = time; 
+               W_PlayStrengthSound(self.realowner);
        }
-       WarpZone_traceline_antilag(lgbeam_owner_ent, self.realowner.origin + self.realowner.view_ofs, targpos, FALSE, lgbeam_owner_ent, ANTILAG_LATENCY(self.realowner));
 
-       // apply the damage, also remove self
-       if(trace_fraction < 1 && trace_ent.takedamage == DAMAGE_AIM && (trace_ent.classname == "player" || trace_ent.classname == "body"))
+       makevectors(self.realowner.v_angle); // update values for v_* vectors
+       
+       // calculate swing percentage based on time
+       meleetime = autocvar_g_balance_shotgun_secondary_melee_time * W_WeaponRateFactor();
+       swing = bound(0, (self.cnt + meleetime - time) / meleetime, 10);
+       f = ((1 - swing) * autocvar_g_balance_shotgun_secondary_melee_traces);
+       
+       // check to see if we can still continue, otherwise give up now
+       if((self.realowner.deadflag != DEAD_NO) && autocvar_g_balance_shotgun_secondary_melee_no_doubleslap)
        {
-               vector force;
-               force = angle * autocvar_g_balance_shotgun_secondary_force;
-               if(accuracy_isgooddamage(self.realowner, trace_ent))
-                       accuracy_add(self.realowner, WEP_SHOTGUN, 0, autocvar_g_balance_shotgun_secondary_damage * min(1, f + 1));
-               Damage (trace_ent, self.realowner, self.realowner, autocvar_g_balance_shotgun_secondary_damage * min(1, f + 1), WEP_SHOTGUN | HITTYPE_SECONDARY , self.realowner.origin + self.realowner.view_ofs, force);
                remove(self);
+               return;
        }
-       else if(time >= self.cnt + meleetime || (self.realowner.deadflag != DEAD_NO && autocvar_g_balance_shotgun_secondary_melee_no_doubleslap)) // missed or owner died, remove ent
+       
+       // if okay, perform the traces needed for this frame 
+       for(i=self.swing_prev; i < f; ++i)
+       {
+               swing_factor = ((1 - (i / autocvar_g_balance_shotgun_secondary_melee_traces)) * 2 - 1);
+               
+               targpos = (self.realowner.origin + self.realowner.view_ofs 
+                       + (v_forward * autocvar_g_balance_shotgun_secondary_melee_range)
+                       + (v_up * swing_factor * autocvar_g_balance_shotgun_secondary_melee_swing_up)
+                       + (v_right * swing_factor * autocvar_g_balance_shotgun_secondary_melee_swing_side));
+
+               WarpZone_traceline_antilag(self.realowner, self.realowner.origin + self.realowner.view_ofs, targpos, FALSE, self.realowner, ANTILAG_LATENCY(self.realowner));
+
+               // draw lightning beams for debugging
+               //te_lightning2(world, targpos, self.realowner.origin + self.realowner.view_ofs + v_forward * 5 - v_up * 5); 
+               //te_customflash(targpos, 40,  2, '1 1 1');
+               
+               is_player = (trace_ent.classname == "player" || trace_ent.classname == "body");
+
+               if((trace_fraction < 1) // if trace is good, apply the damage and remove self
+                       && (trace_ent.takedamage == DAMAGE_AIM)  
+                       && (trace_ent != self.swing_alreadyhit)
+                       && (is_player || autocvar_g_balance_shotgun_secondary_melee_nonplayerdamage))
+               {       
+                       if(is_player) // this allows us to be able to nerf the non-player damage done in e.g. assault or onslaught.
+                               swing_damage = (autocvar_g_balance_shotgun_secondary_damage * min(1, swing_factor + 1));
+                       else
+                               swing_damage = (autocvar_g_balance_shotgun_secondary_melee_nonplayerdamage * min(1, swing_factor + 1));
+                       
+                       Damage(trace_ent, self.realowner, self.realowner, 
+                               swing_damage, WEP_SHOTGUN | HITTYPE_SECONDARY, 
+                               self.realowner.origin + self.realowner.view_ofs, 
+                               v_forward * autocvar_g_balance_shotgun_secondary_force);
+                               
+                       if(accuracy_isgooddamage(self.realowner, trace_ent))
+                               accuracy_add(self.realowner, WEP_SHOTGUN, 0, swing_damage);
+                               
+                       // draw large red flash for debugging
+                       //te_customflash(targpos, 200, 2, '15 0 0');
+                       
+                       if(autocvar_g_balance_shotgun_secondary_melee_multihit) // allow multiple hits with one swing, but not against the same player twice.
+                       {
+                               self.swing_alreadyhit = trace_ent;
+                               continue; // move along to next trace
+                       }
+                       else
+                       {
+                               remove(self);
+                               return;
+                       }
+               }
+       }
+       
+       if(time >= self.cnt + meleetime)
+       {
+               // melee is finished
                remove(self);
-       else // continue swinging the weapon in hope of hitting someone :)
+               return;
+       }
+       else
+       {
+               // set up next frame 
+               self.swing_prev = i;
                self.nextthink = time;
+       }
 }
 
 void W_Shotgun_Attack2 (void)
@@ -171,7 +222,7 @@ float w_shotgun(float req)
        else if (req == WR_CHECKAMMO1)
        {
                ammo_amount = self.ammo_shells >= autocvar_g_balance_shotgun_primary_ammo;
-               ammo_amount += self.weapon_load[WEP_SHOTGUN] >= autocvar_g_balance_shotgun_primary_ammo;
+               ammo_amount += self.(weapon_load[WEP_SHOTGUN]) >= autocvar_g_balance_shotgun_primary_ammo;
                return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
index 79f12f55f8a0aa4636b91df84b3887fd95cf46b1..987e7b41e2570b6480e4d141aa546fcd3dc6ccec 100644 (file)
@@ -236,6 +236,7 @@ float w_tuba(float req)
        {
                weapon_setup(WEP_TUBA);
                self.current_ammo = ammo_none;
+               self.tuba_instrument = 0;
        }
        else if (req == WR_RELOAD)
        {
index 4a10ecdf3a37610e63209edb72eaccac0a6a726f..71ea1f6f6710d33f25dd833324c15f824fbe8a79 100644 (file)
@@ -263,9 +263,9 @@ float w_uzi(float req)
                if(autocvar_g_balance_uzi_reload_ammo)
                {
                        if(autocvar_g_balance_uzi_mode == 1)
-                               ammo_amount += self.weapon_load[WEP_UZI] >= autocvar_g_balance_uzi_sustained_ammo;
+                               ammo_amount += self.(weapon_load[WEP_UZI]) >= autocvar_g_balance_uzi_sustained_ammo;
                        else
-                               ammo_amount += self.weapon_load[WEP_UZI] >= autocvar_g_balance_uzi_first_ammo;
+                               ammo_amount += self.(weapon_load[WEP_UZI]) >= autocvar_g_balance_uzi_first_ammo;
                }
                return ammo_amount;
        }
@@ -279,9 +279,9 @@ float w_uzi(float req)
                if(autocvar_g_balance_uzi_reload_ammo)
                {
                        if(autocvar_g_balance_uzi_mode == 1)
-                               ammo_amount += self.weapon_load[WEP_UZI] >= autocvar_g_balance_uzi_burst_ammo;
+                               ammo_amount += self.(weapon_load[WEP_UZI]) >= autocvar_g_balance_uzi_burst_ammo;
                        else
-                               ammo_amount += self.weapon_load[WEP_UZI] >= autocvar_g_balance_uzi_first_ammo;
+                               ammo_amount += self.(weapon_load[WEP_UZI]) >= autocvar_g_balance_uzi_first_ammo;
                }
                return ammo_amount;
        }
index 63e3e712ab84fade91945a62dc4bcd1ff0b63c9f..118b4f0f5d439017456802de601805b110a95f37 100644 (file)
@@ -326,6 +326,9 @@ float WarpZone_CheckProjectileImpact(entity player)
                return 0;
 
        print("impactfilter found something - and it even gets handled correctly - please tell divVerent that this code apparently gets triggered again\n");
+       print("Entity type: ", player.classname, "\n");
+       print("Origin: ", vtos(player.origin), "\n");
+       print("Velocity: ", vtos(player.velocity), "\n");
 
        // retry previous move
        setorigin(player, player.warpzone_oldorigin);
diff --git a/scripts/gibs.shader b/scripts/gibs.shader
new file mode 100644 (file)
index 0000000..c1c40e5
--- /dev/null
@@ -0,0 +1,111 @@
+meat
+{
+       surfaceparm nomarks
+       {
+               map textures/meat
+       }
+       {
+               map $lightmap
+       }
+}
+
+meat_alien
+{
+       surfaceparm nomarks
+       {
+               map textures/meat_alien
+       }
+       {
+               map $lightmap
+       }
+}
+
+meat_robot
+{
+       surfaceparm nomarks
+       {
+               map textures/meat_robot
+       }
+       {
+               map $lightmap
+       }
+}
+
+eyeblood
+{
+       surfaceparm nomarks
+       {
+               map textures/eyeblood
+       }
+       {
+               map $lightmap
+       }
+}
+
+nutsandbolts1
+{
+       surfaceparm nomarks
+       {
+               map textures/nutsandbolts1
+       }
+       {
+               map $lightmap
+       }
+}
+
+nutsandbolts3
+{
+       surfaceparm nomarks
+       {
+               map textures/nutsandbolts3
+       }
+       {
+               map $lightmap
+       }
+}
+
+nutsandbolts4
+{
+       surfaceparm nomarks
+       {
+               map textures/nutsandbolts4
+       }
+       {
+               map $lightmap
+       }
+}
+
+nutsandbolts5
+{
+       surfaceparm nomarks
+       {
+               map textures/nutsandbolts5
+       }
+       {
+               map $lightmap
+       }
+}
+
+nutsandboltssteel
+{
+       surfaceparm nomarks
+       {
+               map textures/nutsandbolts3
+               tcgen environment
+       }
+       {
+               map $lightmap
+       }
+}
+
+models/gibs/chunk.mdl_0
+{
+       surfaceparm nomarks
+       {
+               map models/gibs/chunk.mdl_0
+               tcgen environment
+       }
+       {
+               map $lightmap
+       }
+}
diff --git a/scripts/nutsandbolts.shader b/scripts/nutsandbolts.shader
deleted file mode 100644 (file)
index e0eb347..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-nutsandboltssteel
-{
-       {
-               map textures/nutsandbolts3
-               tcgen environment
-       }
-       {
-               map $lightmap
-       }
-}
index b7c87a34a63ff22494dbecbb418dc9fd25cd7d74..0024010420e5a06168e479f2e20046db328b3f7c 100755 (executable)
@@ -1,5 +1,6 @@
 #!/bin/sh
 
+errord=false
 countw=`awk '/^seta? g_/ { print $2; }' balanceXonotic.cfg       | sort -u | tr -d '\r' | git hash-object --stdin | cut -c 1-32`
 for b in balance*.cfg; do
        countb=`awk '/^seta? g_/ { print $2; }' "$b"  | sort -u | tr -d '\r' | git hash-object --stdin | cut -c 1-32`
@@ -14,7 +15,10 @@ for b in balance*.cfg; do
                awk '/^seta? g_/ { print $2; }' "$b"                     | sort -u | tr -d '\r' > "$B"
                diff "$A" "$B" | grep '^[<>]' | sort
                rm -f "$A" "$B"
-               echo "Please wait for 30 seconds, so you have had enough time to read this..."
-               sleep 30
+               errord=true
        fi
 done
+if $errord; then
+       echo "Please wait for 30 seconds, so you have had enough time to read this..."
+       sleep 30
+fi