From: Jakob MG Date: Tue, 28 Sep 2010 09:54:21 +0000 (+0200) Subject: Merge branch 'master' into tzork/ents-onoff X-Git-Tag: xonotic-v0.1.0preview~310^2~7 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=bc51fd3d6308269b5ad770ef62b23fe98ee2cfe1;hp=9511d71f751134e35fb136548445749449e0aaec Merge branch 'master' into tzork/ents-onoff Conflicts: qcsrc/server/defs.qh --- diff --git a/Makefile b/Makefile index 99478f084e..83abf218da 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ SCM := $(shell if [ -d .svn ]; then echo svn; elif [ -d ../.git ]; then echo git; fi) FTEQCC ?= fteqcc PERL ?= perl -PK3NAME ?= `date +../data%Y%m%d.pk3` ZIP ?= 7za a -tzip -mx=9 ZIPEXCLUDE ?= -x\!*.pk3 -xr\!\.svn -x\!qcsrc DIFF ?= diff @@ -35,23 +34,6 @@ qc-recursive: menu.dat progs.dat csprogs.dat .PHONY: skin skin: gfx/menu/default/skinvalues.txt -.PHONY: pk3 -pk3: $(PK3NAME) - -.PHONY: pk3here -pk3here: qc - $(RM) $(PK3NAME); \ - set -ex; \ - ABSPK3NAME=$(PK3NAME); \ - case $$ABSPK3NAME in \ - /*) \ - ;; \ - *) \ - ABSPK3NAME=$$PWD/$$ABSPK3NAME; \ - ;; \ - esac; \ - $(ZIP) $(ZIPEXCLUDE) $$ABSPK3NAME . - .PHONY: clean clean: rm -f progs.dat menu.dat csprogs.dat @@ -71,86 +53,6 @@ menu.dat: qcsrc/menu/*.* qcsrc/menu/*/*.* qcsrc/common/*.* gfx/menu/default/skinvalues.txt: qcsrc/menu/skin-customizables.inc $(PERL) qcsrc/menu/skin-customizables.inc > gfx/menu/default/skinvalues.txt -$(PK3NAME): qc - $(RM) $(PK3NAME) - set -ex; \ - ABSPK3NAME=$(PK3NAME); \ - case $$ABSPK3NAME in \ - /*) \ - ;; \ - *) \ - ABSPK3NAME=$$PWD/$$ABSPK3NAME; \ - ;; \ - esac; \ - TDIR=`mktemp -d -t xonoticpk3.XXXXXX`; \ - cp -v progs.dat csprogs.dat menu.dat $$TDIR/; \ - svn export --force . $$TDIR; \ - cd $$TDIR; \ - $(ZIP) $$ABSPK3NAME . - .PHONY: testcase testcase: cd qcsrc/testcase && $(FTEQCC) $(FTEQCCFLAGS) $(FTEQCCFLAGS_CSPROGS) -DTESTCASE="$$TESTCASE" - -.PHONY: update commit diff log logv logupdate logvupdate revert -update: $(SCM)-update -commit: $(SCM)-commit -diff: $(SCM)-diff -log: $(SCM)-log -logv: $(SCM)-logv -revert: $(SCM)-revert -logupdate: log update -logvupdate: logv update - -.PHONY: svn-update -svn-update: - cd .. && svn update - -.PHONY: svn-commit -svn-commit: - cd .. && svn commit - -.PHONY: svn-diff -svn-diff: - cd .. && svn diff - -.PHONY: svn-log -svn-log: - cd .. && svn log -r HEAD:BASE - -.PHONY: svn-logv -svn-logv: - cd .. && svn log -r HEAD:BASE -v - -.PHONY: svn-revert -svn-revert: - svn revert -- $(FILE) - -.PHONY: git-update -git-update: - git pull origin - -.PHONY: git-commit -git-commit: - git commit -a || true - if echo -n 'Also send to server? Hit Enter for yes, ^C for no. '; read -r L; then \ - git config svn-remote.svn.url svn://svn.icculus.org/xonotic; \ - git config svn-remote.svn.fetch trunk:refs/remotes/origin/master; \ - git svn dcommit; \ - fi - -.PHONY: git-diff -git-diff: - git diff; git diff origin/master..HEAD; true - -.PHONY: git-log -git-log: - git fetch && git log HEAD..origin/master - -.PHONY: git-logv -git-logv: - git fetch && git log -v HEAD..origin/master - -.PHONY: git-revert -git-revert: - git checkout -- $(FILE) diff --git a/_hud_descriptions.cfg b/_hud_descriptions.cfg index 09860bbfa1..ddcd45a364 100644 --- a/_hud_descriptions.cfg +++ b/_hud_descriptions.cfg @@ -28,6 +28,8 @@ seta hud_configure_grid "" "snap to grid when moving/resizing panels" seta hud_configure_grid_xsize "" "snap to X * vid_conwidth" seta hud_configure_grid_ysize "" "snap to Y * vid_conheight" +seta scr_centerpos "" "Y position of the centerprint" + seta hud_panel_weapons "" "enable/disable this panel" seta hud_panel_weapons_pos "" "position of this panel" seta hud_panel_weapons_size "" "size of this panel" diff --git a/balance25.cfg b/balance25.cfg index 0250978c3b..ec040c4cd3 100644 --- a/balance25.cfg +++ b/balance25.cfg @@ -318,8 +318,10 @@ set g_balance_electro_primary_refire 0.6 set g_balance_electro_primary_animtime 0.3 set g_balance_electro_primary_ammo 2 set g_balance_electro_primary_range 0 +set g_balance_electro_primary_falloff_mindist 255 // 0.3 * radius +set g_balance_electro_primary_falloff_maxdist 850 +set g_balance_electro_primary_falloff_halflifedist 425 set g_balance_electro_secondary_damage 50 -set g_balance_electro_secondary_spread 0.05 set g_balance_electro_secondary_edgedamage 0 set g_balance_electro_secondary_force 200 set g_balance_electro_secondary_radius 150 diff --git a/balanceLeeStricklin.cfg b/balanceLeeStricklin.cfg new file mode 100644 index 0000000000..6df076b18b --- /dev/null +++ b/balanceLeeStricklin.cfg @@ -0,0 +1,669 @@ +////2.4.2 weapons (with some tweaks) VS balanceLeeStricklin + +// {{{ weapon replacement +// NOTE: this only replaces weapons on the map +// use g_start_weapon_* to also replace the on-startup weapons! +// example: g_weaponreplace_nex "nex minstanex", then Nexes become MinstaNexes 50% of the times +// set the cvars to "0" to totally disable a weapon +set sv_q3acompat_machineshotgunswap 0 "shorthand for swapping uzi and shotgun" +// }}} + +// {{{ starting gear +set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_hlac 0 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_campingrifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_fireball 0 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" +set g_balance_health_start 200 +set g_balance_armor_start 115 +set g_start_ammo_shells 45 +set g_start_ammo_nails 0 +set g_start_ammo_rockets 0 +set g_start_ammo_cells 0 +set g_start_ammo_fuel 0 +set g_warmup_start_health 200 "starting values when being in warmup-stage" +set g_warmup_start_armor 100 "starting values when being in warmup-stage" +set g_warmup_start_ammo_shells 50 "starting values when being in warmup-stage" +set g_warmup_start_ammo_nails 150 "starting values when being in warmup-stage" +set g_warmup_start_ammo_rockets 50 "starting values when being in warmup-stage" +set g_warmup_start_ammo_cells 50 "starting values when being in warmup-stage" +set g_warmup_start_ammo_fuel 0 "starting values when being in warmup-stage" +set g_lms_start_health 200 +set g_lms_start_armor 100 +set g_lms_start_ammo_shells 50 +set g_lms_start_ammo_nails 150 +set g_lms_start_ammo_rockets 50 +set g_lms_start_ammo_cells 50 +set g_lms_start_ammo_fuel 0 +set g_balance_nix_roundtime 25 +set g_balance_nix_incrtime 1.6 +set g_balance_nix_ammo_shells 15 +set g_balance_nix_ammo_nails 45 +set g_balance_nix_ammo_rockets 15 +set g_balance_nix_ammo_cells 15 +set g_balance_nix_ammo_fuel 0 +set g_balance_nix_ammoincr_shells 2 +set g_balance_nix_ammoincr_nails 6 +set g_balance_nix_ammoincr_rockets 2 +set g_balance_nix_ammoincr_cells 2 +set g_balance_nix_ammoincr_fuel 2 +// }}} + +// {{{ pickup items +// Ammo caps copied from balanceFruit +set g_pickup_ammo_anyway 0 +set g_pickup_weapons_anyway 1 +set g_pickup_shells 20 +set g_pickup_shells_max 45 +set g_pickup_nails 120 +set g_pickup_nails_max 300 +set g_pickup_rockets 25 +set g_pickup_rockets_max 150 +set g_pickup_cells 25 +set g_pickup_cells_max 200 +set g_pickup_fuel 25 +set g_pickup_fuel_jetpack 50 +set g_pickup_fuel_max 999 +set g_pickup_armorsmall 10 +set g_pickup_armorsmall_max 250 +set g_pickup_armorsmall_anyway 1 +set g_pickup_armormedium 25 +set g_pickup_armormedium_max 250 +set g_pickup_armormedium_anyway 0 +set g_pickup_armorbig 50 +set g_pickup_armorbig_max 250 +set g_pickup_armorbig_anyway 0 +set g_pickup_armorlarge 100 +set g_pickup_armorlarge_max 250 +set g_pickup_armorlarge_anyway 0 +set g_pickup_healthsmall 10 +set g_pickup_healthsmall_max 300 +set g_pickup_healthsmall_anyway 1 +set g_pickup_healthmedium 25 +set g_pickup_healthmedium_max 300 +set g_pickup_healthmedium_anyway 0 +set g_pickup_healthlarge 50 +set g_pickup_healthlarge_max 300 +set g_pickup_healthlarge_anyway 0 +set g_pickup_healthmega 100 +set g_pickup_healthmega_max 300 +set g_pickup_healthmega_anyway 1 +set g_pickup_respawntime_short 15 +set g_pickup_respawntime_medium 20 +set g_pickup_respawntime_long 30 +set g_pickup_respawntime_powerup 120 +set g_pickup_respawntime_weapon 15 +set g_pickup_respawntime_ammo 15 +set g_pickup_respawntimejitter_short 0 +set g_pickup_respawntimejitter_medium 0 +set g_pickup_respawntimejitter_long 0 +set g_pickup_respawntimejitter_powerup 10 +set g_pickup_respawntimejitter_weapon 0 +set g_pickup_respawntimejitter_ammo 0 +// }}} + +// {{{ regen/rot +set g_balance_health_regen 0 +set g_balance_health_regenlinear 5 +set g_balance_pause_health_regen 5 +set g_balance_pause_health_regen_spawn 0 +set g_balance_health_rot 0 +set g_balance_health_rotlinear 5 +set g_balance_pause_health_rot 3 +set g_balance_pause_health_rot_spawn 1 +set g_balance_health_regenstable 100 +set g_balance_health_rotstable 100 +set g_balance_health_limit 300 +set g_balance_armor_regen 0 +set g_balance_armor_regenlinear 0 +set g_balance_armor_rot 0 +set g_balance_armor_rotlinear 4.86 +set g_balance_pause_armor_rot 1 +set g_balance_pause_armor_rot_spawn 1 +set g_balance_armor_regenstable 100 +set g_balance_armor_rotstable 200 +set g_balance_armor_limit 250 +set g_balance_armor_blockpercent 0.6 +set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)" +set g_balance_fuel_regenlinear 0 +set g_balance_pause_fuel_regen 2 // other than this, fuel uses the health regen counter +set g_balance_fuel_rot 0.05 +set g_balance_fuel_rotlinear 0 +set g_balance_pause_fuel_rot 5 +set g_balance_pause_fuel_rot_spawn 10 +set g_balance_fuel_regenstable 100 +set g_balance_fuel_rotstable 999 +set g_balance_fuel_limit 999 +// }}} + +// {{{ misc +set g_balance_selfdamagepercent 0.6 +set g_balance_weaponswitchdelay 0.15 +set g_weaponspeedfactor 1 "weapon projectile speed multiplier" +set g_weaponratefactor 1 "weapon fire rate multiplier" +set g_weapondamagefactor 1 "weapon damage multiplier" +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_projectiles_newton_style 2 +// possible values: +// 0: absolute velocity projectiles (like Quake) +// 1: relative velocity projectiles, "Newtonian" (like Tribes 2) +// 2: relative velocity projectiles, but aim is precorrected so projectiles hit the crosshair (note: strafe rockets then are SLOWER than ones shot while standing, happens in 1 too when aiming correctly which is hard) +// 3: absolute velocity + player velocity component in shot direction (note: does NOT yield the right relative velocity, but may be good enough, but it is somewhat prone to sniper rockets) +// 4: just add the player velocity length to the absolute velocity (tZork's sniper rockets) +set g_projectiles_newton_style_2_minfactor 0.8 +set g_projectiles_newton_style_2_maxfactor 1.5 +set g_projectiles_spread_style 0 +// possible values: +// 0: forward + solid sphere (like Quake) - varies velocity +// 1: forward + flattened solid sphere +// 2: forward + solid circle +// 3: forward + normal distribution 3D - varies velocity +// 4: forward + normal distribution on a plane +// 5: forward + circle with 1-r falloff +// 6: forward + circle with 1-r^2 falloff +// 7: forward + circle with (1-r)(2-r) falloff +set g_balance_falldamage_deadminspeed 150 +set g_balance_falldamage_minspeed 1400 +set g_balance_falldamage_factor 0.15 +set g_balance_falldamage_maxdamage 25 +// }}} + +// {{{ powerups +set g_balance_powerup_invincible_takedamage 0.2 +set g_balance_powerup_invincible_time 30 +set g_balance_powerup_strength_damage 3 +set g_balance_powerup_strength_force 3 +set g_balance_powerup_strength_time 30 +set g_balance_powerup_strength_selfdamage 1.5 +set g_balance_powerup_strength_selfforce 1.5 +// }}} + +// {{{ jetpack/hook +set g_jetpack_antigravity 0.8 "factor of gravity compensation of the jetpack" +set g_jetpack_acceleration_side 1200 "acceleration of the jetpack in xy direction" +set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (note: you have to factor in gravity here, if antigravity is not 1)" +set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction" +set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction" +set g_jetpack_fuel 8 "fuel per second for jetpack" +set g_jetpack_attenuation 2 "jetpack sound attenuation" + +set g_grappling_hook_tarzan 2 // 2: can also pull players +set g_balance_grapplehook_speed_fly 1800 +set g_balance_grapplehook_speed_pull 2000 +set g_balance_grapplehook_force_rubber 2000 +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 +// }}} + +// {{{ weapon properties +// {{{ laser +set g_balance_laser_primary_damage 25 +set g_balance_laser_primary_edgedamage 10 +set g_balance_laser_primary_force 258 +set g_balance_laser_primary_radius 70 +set g_balance_laser_primary_speed 12000 +set g_balance_laser_primary_spread 0 +set g_balance_laser_primary_refire 0.7 +set g_balance_laser_primary_animtime 0.3 +set g_balance_laser_primary_lifetime 30 +set g_balance_laser_primary_shotangle 0 +set g_balance_laser_primary_delay 0.03 +set g_balance_laser_primary_gauntlet 0 +set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists +set g_balance_laser_secondary_damage 25 +set g_balance_laser_secondary_edgedamage 10 +set g_balance_laser_secondary_force 375 +set g_balance_laser_secondary_radius 70 +set g_balance_laser_secondary_speed 12000 +set g_balance_laser_secondary_spread 0 +set g_balance_laser_secondary_refire 0.7 +set g_balance_laser_secondary_animtime 0.3 +set g_balance_laser_secondary_lifetime 30 +set g_balance_laser_secondary_shotangle -90 +set g_balance_laser_secondary_delay 0 +set g_balance_laser_secondary_gauntlet 0 +// }}} +// {{{ shotgun +set g_balance_shotgun_primary_bullets 5 +set g_balance_shotgun_primary_damage 12 +set g_balance_shotgun_primary_force 60 +set g_balance_shotgun_primary_spread 0.08 +set g_balance_shotgun_primary_refire 0.5 +set g_balance_shotgun_primary_animtime 0.2 +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_damage 84 +set g_balance_shotgun_secondary_force 147 +set g_balance_shotgun_secondary_refire 1.1 +set g_balance_shotgun_secondary_animtime 1 +// }}} +// {{{ uzi +set g_balance_uzi_first 1 +set g_balance_uzi_first_damage 26 +set g_balance_uzi_first_force 50 +set g_balance_uzi_first_spread 0.01 +set g_balance_uzi_first_refire 0.2 +set g_balance_uzi_first_ammo 1 +set g_balance_uzi_sustained_damage 15 +set g_balance_uzi_sustained_force 27 +set g_balance_uzi_sustained_spread 0.05 +set g_balance_uzi_sustained_refire 0.1 +set g_balance_uzi_sustained_ammo 1 +set g_balance_uzi_speed 18000 +set g_balance_uzi_bulletconstant 300 // 13.1qu +// }}} +// {{{ mortar +set g_balance_grenadelauncher_primary2secondary 0 +set g_balance_grenadelauncher_primary_sticky 0 +set g_balance_grenadelauncher_primary_damage 65 +set g_balance_grenadelauncher_primary_edgedamage 35 +set g_balance_grenadelauncher_primary_force 400 +set g_balance_grenadelauncher_primary_radius 140 +set g_balance_grenadelauncher_primary_speed 2000 +set g_balance_grenadelauncher_primary_speed_up 200 +set g_balance_grenadelauncher_primary_speed_z 0 +set g_balance_grenadelauncher_primary_spread 0 +set g_balance_grenadelauncher_primary_lifetime 30 +set g_balance_grenadelauncher_primary_lifetime2 0.65 +set g_balance_grenadelauncher_primary_refire 0.7 +set g_balance_grenadelauncher_primary_animtime 0.3 +set g_balance_grenadelauncher_primary_ammo 2 +set g_balance_grenadelauncher_primary_health 72 +set g_balance_grenadelauncher_secondary_sticky 0 +set g_balance_grenadelauncher_secondary_damage 65 +set g_balance_grenadelauncher_secondary_edgedamage 35 +set g_balance_grenadelauncher_secondary_force 400 +set g_balance_grenadelauncher_secondary_radius 140 +set g_balance_grenadelauncher_secondary_speed 1400 +set g_balance_grenadelauncher_secondary_speed_up 200 +set g_balance_grenadelauncher_secondary_speed_z 0 +set g_balance_grenadelauncher_secondary_spread 0 +set g_balance_grenadelauncher_secondary_lifetime 2.5 +set g_balance_grenadelauncher_secondary_lifetime2 1 +set g_balance_grenadelauncher_secondary_refire 0.6 +set g_balance_grenadelauncher_secondary_animtime 0.3 +set g_balance_grenadelauncher_secondary_ammo 2 +set g_balance_grenadelauncher_secondary_health 40 +set g_balance_grenadelauncher_secondary_damageforcescale 0 +set g_balance_grenadelauncher_secondary_bouncefactor 0.7 +set g_balance_grenadelauncher_secondary_bouncestop 0.12 +// }}} +// {{{ electro +set g_balance_electro_lightning 0 +set g_balance_electro_primary_damage 80 +set g_balance_electro_primary_edgedamage 0 +set g_balance_electro_primary_force 550 +set g_balance_electro_primary_force_up 125 +set g_balance_electro_primary_radius 150 +set g_balance_electro_primary_comboradius 75 +set g_balance_electro_primary_speed 2000 +set g_balance_electro_primary_spread 0 +set g_balance_electro_primary_lifetime 30 +set g_balance_electro_primary_refire 0.6 +set g_balance_electro_primary_animtime 0.74 +set g_balance_electro_primary_ammo 2 +set g_balance_electro_primary_range 800 +set g_balance_electro_primary_falloff_mindist 255 // 0.3 * radius +set g_balance_electro_primary_falloff_maxdist 850 +set g_balance_electro_primary_falloff_halflifedist 425 +set g_balance_electro_secondary_damage 60 +set g_balance_electro_secondary_edgedamage 0 +set g_balance_electro_secondary_force 200 +set g_balance_electro_secondary_radius 150 +set g_balance_electro_secondary_speed 900 +set g_balance_electro_secondary_speed_up 200 +set g_balance_electro_secondary_speed_z 0 +set g_balance_electro_secondary_lifetime 3 +set g_balance_electro_secondary_spread 0.05 +set g_balance_electro_secondary_refire 0.2 +set g_balance_electro_secondary_refire2 1 +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_count 3 +set g_balance_electro_combo_damage 70 +set g_balance_electro_combo_edgedamage 0 +set g_balance_electro_combo_force 200 +set g_balance_electro_combo_radius 250 +set g_balance_electro_combo_comboradius 70 +set g_balance_electro_combo_speed 400 +// }}} +// {{{ crylink +set g_balance_crylink_primary_damage 16 +set g_balance_crylink_primary_edgedamage 0 +set g_balance_crylink_primary_force -55 +set g_balance_crylink_primary_radius 80 +set g_balance_crylink_primary_speed 6950 +set g_balance_crylink_primary_spread 0.03 +set g_balance_crylink_primary_shots 4 +set g_balance_crylink_primary_bounces 2 +set g_balance_crylink_primary_refire 0.4 +set g_balance_crylink_primary_animtime 0.30008 +set g_balance_crylink_primary_ammo 1 +set g_balance_crylink_primary_bouncedamagefactor 0.2 + +set g_balance_crylink_primary_middle_lifetime 5 // range: 10000 full, fades to 20000 +set g_balance_crylink_primary_middle_fadetime 5 +set g_balance_crylink_primary_star_lifetime 2 // range: 800 full, fades to 1300 +set g_balance_crylink_primary_star_fadetime 0.25 +set g_balance_crylink_primary_other_lifetime 2 // range: 800 full, fades to 1300 +set g_balance_crylink_primary_other_fadetime 0.25 + +set g_balance_crylink_secondary 1 +set g_balance_crylink_secondary_damage 12 +set g_balance_crylink_secondary_edgedamage 0 +set g_balance_crylink_secondary_force -55 +set g_balance_crylink_secondary_radius 3 +set g_balance_crylink_secondary_speed 6950 +set g_balance_crylink_secondary_spread 0.08 +set g_balance_crylink_secondary_shots 7 +set g_balance_crylink_secondary_bounces 0 +set g_balance_crylink_secondary_refire 0.5 +set g_balance_crylink_secondary_animtime 0.3 +set g_balance_crylink_secondary_ammo 2 +set g_balance_crylink_secondary_bouncedamagefactor 0.5 + +set g_balance_crylink_secondary_middle_lifetime 5 // range: 10000 full, fades to 10000 +set g_balance_crylink_secondary_middle_fadetime 5 +set g_balance_crylink_secondary_line_lifetime 2 // range: 4000 full, fades to 8000 +set g_balance_crylink_secondary_line_fadetime 2 +// }}} +// {{{ nex +set g_balance_nex_primary_ammo 7 +set g_balance_nex_primary_animtime 0.3 +set g_balance_nex_primary_damage 140 +set g_balance_nex_primary_force 600 +set g_balance_nex_primary_refire 1.5 +set g_balance_nex_primary_damagefalloff_mindist 9999999 +set g_balance_nex_primary_damagefalloff_maxdist 9999999 +set g_balance_nex_primary_damagefalloff_halflife 9999999 +set g_balance_nex_primary_damagefalloff_forcehalflife 9999999 + +set g_balance_nex_secondary 0 +set g_balance_nex_secondary_damage 80 +set g_balance_nex_secondary_force -500 +set g_balance_nex_secondary_refire 1.25 +set g_balance_nex_secondary_animtime 0.75 +set g_balance_nex_secondary_ammo 5 +set g_balance_nex_secondary_damagefalloff_mindist 9999999 +set g_balance_nex_secondary_damagefalloff_maxdist 9999999 +set g_balance_nex_secondary_damagefalloff_halflife 9999999 +set g_balance_nex_secondary_damagefalloff_forcehalflife 9999999 +// }}} +// {{{ minstanex +set g_balance_minstanex_refire 1 +set g_balance_minstanex_animtime 0.278 +set g_balance_minstanex_ammo 10 +// }}} +// {{{ hagar +set g_balance_hagar_primary_damage 43 +set g_balance_hagar_primary_edgedamage 15 +set g_balance_hagar_primary_force 100 +set g_balance_hagar_primary_radius 70 +set g_balance_hagar_primary_spread 0.010 +set g_balance_hagar_primary_speed 3000 +set g_balance_hagar_primary_lifetime 30 +set g_balance_hagar_primary_refire 0.15 +set g_balance_hagar_primary_ammo 1 +set g_balance_hagar_secondary 1 +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_radius 70 +set g_balance_hagar_secondary_spread 0.015 +set g_balance_hagar_secondary_speed 1400 +set g_balance_hagar_secondary_lifetime_min 5 +set g_balance_hagar_secondary_lifetime_rand 0 +set g_balance_hagar_secondary_refire 0.15 +set g_balance_hagar_secondary_ammo 1 +// }}} +// {{{ rocketlauncher +set g_balance_rocketlauncher_damage 130 +set g_balance_rocketlauncher_edgedamage 50 +set g_balance_rocketlauncher_force 597 +set g_balance_rocketlauncher_radius 185 +set g_balance_rocketlauncher_speed 900 +set g_balance_rocketlauncher_speedaccel 0 +set g_balance_rocketlauncher_speedstart 850 +set g_balance_rocketlauncher_lifetime 30 +set g_balance_rocketlauncher_refire 1 +set g_balance_rocketlauncher_animtime 0.3 +set g_balance_rocketlauncher_ammo 3 +set g_balance_rocketlauncher_health 40 +set g_balance_rocketlauncher_damageforcescale 4 +set g_balance_rocketlauncher_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time +set g_balance_rocketlauncher_guiderate 140 // max degrees per second +set g_balance_rocketlauncher_guideratedelay 0.01 // immediate +set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic) +set g_balance_rocketlauncher_guidedelay 0.15 // delay before guiding kicks in +set g_balance_rocketlauncher_guidestop 0 // stop guiding when firing again +set g_balance_rocketlauncher_laserguided_speed 1000 //650 +set g_balance_rocketlauncher_laserguided_speedaccel 0 +set g_balance_rocketlauncher_laserguided_speedstart 1000 +set g_balance_rocketlauncher_laserguided_turnrate 0.60 //0.5 +set g_balance_rocketlauncher_laserguided_allow_steal 1 +set g_balance_rocketlauncher_remote_damage 120 +set g_balance_rocketlauncher_remote_edgedamage 46 +set g_balance_rocketlauncher_remote_radius 185 +set g_balance_rocketlauncher_remote_force 590 +// }}} +// {{{ 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_lifetime 30 +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 +// }}} +// {{{ hook +set g_balance_hook_primary_fuel 2 // hook monkeys set 0 +set g_balance_hook_primary_refire 0 // hook monkeys set 0 +set g_balance_hook_primary_animtime 0.3 // good shoot anim +set g_balance_hook_primary_hooked_time_max 0 // infinite +set g_balance_hook_primary_hooked_time_free 2 // 2s being hooked are free +set g_balance_hook_primary_hooked_fuel 3 // fuel per second hooked +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_lifetime 30 // infinite +set g_balance_hook_secondary_speed 0 // not much throwing +set g_balance_hook_secondary_gravity 5 // fast falling +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 +// }}} +// {{{ hlac +set g_balance_hlac_primary_spread_min 0.01 +set g_balance_hlac_primary_spread_max 0.25 +set g_balance_hlac_primary_spread_add 0.0045 +set g_balance_hlac_primary_spread_crouchmod 0.25 + +set g_balance_hlac_primary_damage 19 +set g_balance_hlac_primary_edgedamage 10 +set g_balance_hlac_primary_force 45 +set g_balance_hlac_primary_radius 70 +set g_balance_hlac_primary_speed 9000 +set g_balance_hlac_primary_lifetime 5 + +set g_balance_hlac_primary_refire 0.1 +set g_balance_hlac_primary_animtime 0.3 +set g_balance_hlac_primary_ammo 1 + +set g_balance_hlac_secondary 1 +set g_balance_hlac_secondary_spread 0.15 +set g_balance_hlac_secondary_spread_crouchmod 0.5 + +set g_balance_hlac_secondary_damage 18 +set g_balance_hlac_secondary_edgedamage 10 +set g_balance_hlac_secondary_force 100 +set g_balance_hlac_secondary_radius 70 +set g_balance_hlac_secondary_speed 9000 +set g_balance_hlac_secondary_lifetime 5 + +set g_balance_hlac_secondary_refire 1 +set g_balance_hlac_secondary_animtime 0.3 +set g_balance_hlac_secondary_ammo 10 +set g_balance_hlac_secondary_shots 6 +// }}} +// {{{ campingrifle +set g_balance_campingrifle_magazinecapacity 8 +set g_balance_campingrifle_reloadtime 2 // matches reload anim +set g_balance_campingrifle_auto_reload_after_changing_weapons 0 +set g_balance_campingrifle_bursttime 0.85 // 0.35 - 0.1 + 0.35 - 0.1 + 0.35 = three secondaries +set g_balance_campingrifle_tracer 1 +set g_balance_campingrifle_primary_damage 75 +set g_balance_campingrifle_primary_headshotaddeddamage 90 +set g_balance_campingrifle_primary_spread 0 +set g_balance_campingrifle_primary_force 2 +set g_balance_campingrifle_primary_speed 35000 +set g_balance_campingrifle_primary_lifetime 5 +set g_balance_campingrifle_primary_refire 0.7 +set g_balance_campingrifle_primary_animtime 0.3 +set g_balance_campingrifle_primary_ammo 10 +set g_balance_campingrifle_primary_bulletconstant 130 // 56.3qu +set g_balance_campingrifle_primary_burstcost 0 // require same cooldown as secondary, note it's smaller than primary refire time +set g_balance_campingrifle_primary_bullethail 0 // empty magazine on shot +set g_balance_campingrifle_secondary 1 +set g_balance_campingrifle_secondary_damage 40 +set g_balance_campingrifle_secondary_headshotaddeddamage 20 +set g_balance_campingrifle_secondary_spread 0.008 +set g_balance_campingrifle_secondary_force 1 +set g_balance_campingrifle_secondary_speed 20000 +set g_balance_campingrifle_secondary_lifetime 5 +set g_balance_campingrifle_secondary_refire 0.0006 +set g_balance_campingrifle_secondary_animtime 0.1 +set g_balance_campingrifle_secondary_ammo 10 +set g_balance_campingrifle_secondary_bulletconstant 130 // 18.3qu +set g_balance_campingrifle_secondary_burstcost 0 +set g_balance_campingrifle_secondary_bullethail 0 +// }}} +// {{{ tuba +set g_balance_tuba_refire 0.05 +set g_balance_tuba_animtime 0.05 +set g_balance_tuba_attenuation 0.5 +set g_balance_tuba_volume 1 +set g_balance_tuba_fadetime 0.25 +set g_balance_tuba_damage 5 +set g_balance_tuba_edgedamage 0 +set g_balance_tuba_radius 200 +set g_balance_tuba_force 40 +// }}} +// {{{ fireball +set g_balance_fireball_primary_ammo 5 +set g_balance_fireball_primary_animtime 0.3 +set g_balance_fireball_primary_bfgdamage 0 +set g_balance_fireball_primary_bfgforce 0 +set g_balance_fireball_primary_bfgradius 0 +set g_balance_fireball_primary_damage 40 +set g_balance_fireball_primary_damageforcescale 4 +set g_balance_fireball_primary_edgedamage 0 +set g_balance_fireball_primary_force 100 +set g_balance_fireball_primary_health 9999 +set g_balance_fireball_primary_laserburntime 0.5 +set g_balance_fireball_primary_laserdamage 30 +set g_balance_fireball_primary_laseredgedamage 20 +set g_balance_fireball_primary_laserradius 110 +set g_balance_fireball_primary_lifetime 7 +set g_balance_fireball_primary_radius 20 +set g_balance_fireball_primary_refire 2 +set g_balance_fireball_primary_refire2 1.5 +set g_balance_fireball_primary_speed 900 +set g_balance_fireball_primary_spread 0 +set g_balance_fireball_secondary_ammo 25 +set g_balance_fireball_secondary_animtime 0.15 +set g_balance_fireball_secondary_damage 150 +set g_balance_fireball_secondary_damageforcescale 4 +set g_balance_fireball_secondary_damagetime 3 +set g_balance_fireball_secondary_force 700 +set g_balance_fireball_secondary_laserburntime 0.5 +set g_balance_fireball_secondary_laserdamage 30 +set g_balance_fireball_secondary_laseredgedamage 20 +set g_balance_fireball_secondary_laserradius 256 +set g_balance_fireball_secondary_lifetime 15 +set g_balance_fireball_secondary_refire 0 +set g_balance_fireball_secondary_speed 650 +set g_balance_fireball_secondary_speed_up 0 +set g_balance_fireball_secondary_speed_z 0 +set g_balance_fireball_secondary_spread 0 +// }}} +// {{{ seeker +set g_balance_seeker_flac_ammo 0.5 +set g_balance_seeker_flac_animtime 0.1 +set g_balance_seeker_flac_damage 15 +set g_balance_seeker_flac_edgedamage 10 +set g_balance_seeker_flac_force 50 +set g_balance_seeker_flac_lifetime 0.1 +set g_balance_seeker_flac_lifetime_rand 0.05 +set g_balance_seeker_flac_radius 100 +set g_balance_seeker_flac_refire 0.1 +set g_balance_seeker_flac_speed 3000 +set g_balance_seeker_flac_speed_up 1000 +set g_balance_seeker_flac_speed_z 0 +set g_balance_seeker_flac_spread 0.4 +set g_balance_seeker_missile_accel 1.05 +set g_balance_seeker_missile_ammo 2 +set g_balance_seeker_missile_animtime 0.3 +set g_balance_seeker_missile_count 8 +set g_balance_seeker_missile_damage 15 +set g_balance_seeker_missile_damageforcescale 4 +set g_balance_seeker_missile_decel 0.9 +set g_balance_seeker_missile_delay 0.25 +set g_balance_seeker_missile_edgedamage 10 +set g_balance_seeker_missile_force 250 +set g_balance_seeker_missile_health 5 +set g_balance_seeker_missile_lifetime 15 +set g_balance_seeker_missile_proxy 0 +set g_balance_seeker_missile_proxy_delay 0.2 +set g_balance_seeker_missile_proxy_maxrange 45 +set g_balance_seeker_missile_radius 80 +set g_balance_seeker_missile_refire 0.5 +set g_balance_seeker_missile_smart 1 +set g_balance_seeker_missile_smart_mindist 800 +set g_balance_seeker_missile_smart_trace_max 2500 +set g_balance_seeker_missile_smart_trace_min 1000 +set g_balance_seeker_missile_speed 700 +set g_balance_seeker_missile_speed_accel 0 +set g_balance_seeker_missile_speed_up 300 +set g_balance_seeker_missile_speed_z 0 +set g_balance_seeker_missile_speed_max 1250 +set g_balance_seeker_missile_spread 0 +set g_balance_seeker_missile_turnrate 0.65 +set g_balance_seeker_tag_ammo 1 +set g_balance_seeker_tag_animtime 0.3 +set g_balance_seeker_tag_damageforcescale 4 +set g_balance_seeker_tag_health 5 +set g_balance_seeker_tag_lifetime 15 +set g_balance_seeker_tag_refire 0.7 +set g_balance_seeker_tag_speed 9000 +set g_balance_seeker_tag_spread 0 +// End new seeker diff --git a/balanceNexSVN.cfg b/balanceNexSVN.cfg index 0f8a8dc35c..6c5a74655d 100644 --- a/balanceNexSVN.cfg +++ b/balanceNexSVN.cfg @@ -318,8 +318,10 @@ set g_balance_electro_primary_refire 0.6 set g_balance_electro_primary_animtime 0.3 set g_balance_electro_primary_ammo 2 set g_balance_electro_primary_range 0 +set g_balance_electro_primary_falloff_mindist 255 // 0.3 * radius +set g_balance_electro_primary_falloff_maxdist 850 +set g_balance_electro_primary_falloff_halflifedist 425 set g_balance_electro_secondary_damage 50 -set g_balance_electro_secondary_spread 0.05 set g_balance_electro_secondary_edgedamage 0 set g_balance_electro_secondary_force 200 set g_balance_electro_secondary_radius 150 diff --git a/balanceSamual.cfg b/balanceSamual.cfg index e70157872e..17c3e14105 100644 --- a/balanceSamual.cfg +++ b/balanceSamual.cfg @@ -318,8 +318,10 @@ set g_balance_electro_primary_refire 0.6 set g_balance_electro_primary_animtime 0.3 set g_balance_electro_primary_ammo 2 set g_balance_electro_primary_range 0 +set g_balance_electro_primary_falloff_mindist 255 // 0.3 * radius +set g_balance_electro_primary_falloff_maxdist 850 +set g_balance_electro_primary_falloff_halflifedist 425 set g_balance_electro_secondary_damage 50 -set g_balance_electro_secondary_spread 0.05 set g_balance_electro_secondary_edgedamage 0 set g_balance_electro_secondary_force 200 set g_balance_electro_secondary_radius 150 diff --git a/balanceXonotic.cfg b/balanceXonotic.cfg index 39b9b26ccc..076a4935b6 100644 --- a/balanceXonotic.cfg +++ b/balanceXonotic.cfg @@ -114,7 +114,7 @@ set g_balance_pause_health_rot 1 set g_balance_pause_health_rot_spawn 0 set g_balance_health_regenstable 100 set g_balance_health_rotstable 100 -set g_balance_health_limit 200 +set g_balance_health_limit 999 set g_balance_armor_regen 0 set g_balance_armor_regenlinear 0 set g_balance_armor_rot 0 @@ -123,7 +123,7 @@ set g_balance_pause_armor_rot 1 set g_balance_pause_armor_rot_spawn 0 set g_balance_armor_regenstable 100 set g_balance_armor_rotstable 100 -set g_balance_armor_limit 200 +set g_balance_armor_limit 999 set g_balance_armor_blockpercent 0.7 set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)" set g_balance_fuel_regenlinear 0 @@ -244,10 +244,10 @@ 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_range 85 set g_balance_shotgun_secondary_melee_swing 50 set g_balance_shotgun_secondary_melee_time 0.1 -set g_balance_shotgun_secondary_damage 115 +set g_balance_shotgun_secondary_damage 110 set g_balance_shotgun_secondary_force 150 set g_balance_shotgun_secondary_refire 1.1 set g_balance_shotgun_secondary_animtime 1 @@ -259,7 +259,7 @@ set g_balance_uzi_first_force 35 set g_balance_uzi_first_spread 0.03 set g_balance_uzi_first_refire 0.2 set g_balance_uzi_first_ammo 2 -set g_balance_uzi_sustained_damage 7 +set g_balance_uzi_sustained_damage 9 set g_balance_uzi_sustained_force 7.5 set g_balance_uzi_sustained_spread 0.1 set g_balance_uzi_sustained_refire 0.075 @@ -281,7 +281,7 @@ set g_balance_grenadelauncher_primary_spread 0 set g_balance_grenadelauncher_primary_lifetime 5 set g_balance_grenadelauncher_primary_lifetime2 0.65 set g_balance_grenadelauncher_primary_refire 0.8 -set g_balance_grenadelauncher_primary_animtime 0.2 +set g_balance_grenadelauncher_primary_animtime 0.4 set g_balance_grenadelauncher_primary_ammo 2 set g_balance_grenadelauncher_primary_health 72 set g_balance_grenadelauncher_secondary_sticky 1 @@ -296,7 +296,7 @@ set g_balance_grenadelauncher_secondary_spread 0 set g_balance_grenadelauncher_secondary_lifetime 5 set g_balance_grenadelauncher_secondary_lifetime2 1 set g_balance_grenadelauncher_secondary_refire 0.8 -set g_balance_grenadelauncher_secondary_animtime 0.2 +set g_balance_grenadelauncher_secondary_animtime 0.4 set g_balance_grenadelauncher_secondary_ammo 2 set g_balance_grenadelauncher_secondary_health 40 set g_balance_grenadelauncher_secondary_damageforcescale 0 @@ -314,12 +314,14 @@ set g_balance_electro_primary_comboradius 75 set g_balance_electro_primary_speed 0 set g_balance_electro_primary_spread 0 set g_balance_electro_primary_lifetime 0 -set g_balance_electro_primary_refire 0.03333333 +set g_balance_electro_primary_refire 0.4 set g_balance_electro_primary_animtime 0.03333333 -set g_balance_electro_primary_ammo 10 +set g_balance_electro_primary_ammo 7 set g_balance_electro_primary_range 800 +set g_balance_electro_primary_falloff_mindist 255 // 0.3 * radius +set g_balance_electro_primary_falloff_maxdist 850 +set g_balance_electro_primary_falloff_halflifedist 425 set g_balance_electro_secondary_damage 25 -set g_balance_electro_secondary_spread 0 set g_balance_electro_secondary_edgedamage 0 set g_balance_electro_secondary_force 100 set g_balance_electro_secondary_radius 100 @@ -343,10 +345,10 @@ set g_balance_electro_combo_comboradius 0 set g_balance_electro_combo_speed 400 // }}} // {{{ crylink -set g_balance_crylink_primary_damage 10 -set g_balance_crylink_primary_edgedamage 8 -set g_balance_crylink_primary_force -60 -set g_balance_crylink_primary_radius 100 +set g_balance_crylink_primary_damage 8 +set g_balance_crylink_primary_edgedamage 6 +set g_balance_crylink_primary_force 40 +set g_balance_crylink_primary_radius 80 set g_balance_crylink_primary_speed 1100 set g_balance_crylink_primary_spread 0.1 set g_balance_crylink_primary_shots 7 @@ -364,16 +366,16 @@ set g_balance_crylink_primary_other_lifetime 2 // range: 800 full, fades to 1300 set g_balance_crylink_primary_other_fadetime 0.25 set g_balance_crylink_secondary 1 -set g_balance_crylink_secondary_damage 4 +set g_balance_crylink_secondary_damage 2 set g_balance_crylink_secondary_edgedamage 0 set g_balance_crylink_secondary_force -20 -set g_balance_crylink_secondary_radius 15 +set g_balance_crylink_secondary_radius 5 set g_balance_crylink_secondary_speed 1600 set g_balance_crylink_secondary_spread 0.03 set g_balance_crylink_secondary_shots 3 set g_balance_crylink_secondary_bounces 0 -set g_balance_crylink_secondary_refire 0.1 -set g_balance_crylink_secondary_animtime 0.1 +set g_balance_crylink_secondary_refire 0.15 +set g_balance_crylink_secondary_animtime 0.15 set g_balance_crylink_secondary_ammo 1 set g_balance_crylink_secondary_bouncedamagefactor 0.5 @@ -384,25 +386,25 @@ set g_balance_crylink_secondary_line_fadetime 2 // }}} // {{{ nex set g_balance_nex_primary_damage 80 -set g_balance_nex_primary_force 200 +set g_balance_nex_primary_force 400 set g_balance_nex_primary_refire 1.25 set g_balance_nex_primary_animtime 0.75 set g_balance_nex_primary_ammo 5 -set g_balance_nex_primary_damagefalloff_mindist 1000 -set g_balance_nex_primary_damagefalloff_maxdist 3000 -set g_balance_nex_primary_damagefalloff_halflife 4000 -set g_balance_nex_primary_damagefalloff_forcehalflife 4000 +set g_balance_nex_primary_damagefalloff_mindist 0 +set g_balance_nex_primary_damagefalloff_maxdist 4000 +set g_balance_nex_primary_damagefalloff_halflife 2000 +set g_balance_nex_primary_damagefalloff_forcehalflife 2000 set g_balance_nex_secondary 1 set g_balance_nex_secondary_damage 80 -set g_balance_nex_secondary_force -200 +set g_balance_nex_secondary_force -500 set g_balance_nex_secondary_refire 1.25 set g_balance_nex_secondary_animtime 0.75 set g_balance_nex_secondary_ammo 5 -set g_balance_nex_secondary_damagefalloff_mindist 1000 -set g_balance_nex_secondary_damagefalloff_maxdist 3000 -set g_balance_nex_secondary_damagefalloff_halflife 4000 -set g_balance_nex_secondary_damagefalloff_forcehalflife 4000 +set g_balance_nex_secondary_damagefalloff_mindist 0 +set g_balance_nex_secondary_damagefalloff_maxdist 4000 +set g_balance_nex_secondary_damagefalloff_halflife 2000 +set g_balance_nex_secondary_damagefalloff_forcehalflife 2000 // }}} // {{{ minstanex set g_balance_minstanex_refire 1.25 @@ -411,9 +413,9 @@ set g_balance_minstanex_ammo 10 // }}} // {{{ hagar set g_balance_hagar_primary_damage 12 -set g_balance_hagar_primary_edgedamage 12 +set g_balance_hagar_primary_edgedamage 6 set g_balance_hagar_primary_force 70 -set g_balance_hagar_primary_radius 70 +set g_balance_hagar_primary_radius 100 set g_balance_hagar_primary_spread 0.1 set g_balance_hagar_primary_speed 1800 set g_balance_hagar_primary_lifetime 5 @@ -421,9 +423,9 @@ set g_balance_hagar_primary_refire 0.12 set g_balance_hagar_primary_ammo 1 set g_balance_hagar_secondary 1 set g_balance_hagar_secondary_damage 12 -set g_balance_hagar_secondary_edgedamage 12 +set g_balance_hagar_secondary_edgedamage 6 set g_balance_hagar_secondary_force 70 -set g_balance_hagar_secondary_radius 50 +set g_balance_hagar_secondary_radius 100 set g_balance_hagar_secondary_spread 0.15 set g_balance_hagar_secondary_speed 1800 set g_balance_hagar_secondary_lifetime_min 5 @@ -441,7 +443,7 @@ set g_balance_rocketlauncher_speedaccel 0 set g_balance_rocketlauncher_speedstart 1000 set g_balance_rocketlauncher_lifetime 5 set g_balance_rocketlauncher_refire 1 -set g_balance_rocketlauncher_animtime 0.2 +set g_balance_rocketlauncher_animtime 0.4 set g_balance_rocketlauncher_ammo 3 set g_balance_rocketlauncher_health 0 set g_balance_rocketlauncher_damageforcescale 0 @@ -523,12 +525,12 @@ set g_balance_hlac_secondary_ammo 10 set g_balance_hlac_secondary_shots 6 // }}} // {{{ campingrifle -set g_balance_campingrifle_magazinecapacity 4 // make it pretty much useless in close combat +set g_balance_campingrifle_magazinecapacity 8 // make it pretty much useless in close combat set g_balance_campingrifle_reloadtime 2 // matches reload anim set g_balance_campingrifle_auto_reload_after_changing_weapons 0 set g_balance_campingrifle_bursttime 0 set g_balance_campingrifle_tracer 1 -set g_balance_campingrifle_primary_damage 60 +set g_balance_campingrifle_primary_damage 50 set g_balance_campingrifle_primary_headshotaddeddamage 50 set g_balance_campingrifle_primary_spread 0 set g_balance_campingrifle_primary_force 2 @@ -542,7 +544,7 @@ set g_balance_campingrifle_primary_burstcost 0 set g_balance_campingrifle_primary_bullethail 0 // empty magazine on shot set g_balance_campingrifle_secondary 1 set g_balance_campingrifle_secondary_damage 25 -set g_balance_campingrifle_secondary_headshotaddeddamage 20 // 45 damage only on head +set g_balance_campingrifle_secondary_headshotaddeddamage 25 // 50 damage only on head set g_balance_campingrifle_secondary_spread 0.008 set g_balance_campingrifle_secondary_force 1 set g_balance_campingrifle_secondary_speed 20000 diff --git a/darkplaces-icon.tga b/darkplaces-icon.tga new file mode 100644 index 0000000000..d7a0dd09e9 Binary files /dev/null and b/darkplaces-icon.tga differ diff --git a/darkplaces-icon.xpm b/darkplaces-icon.xpm new file mode 100644 index 0000000000..cdd7f44147 --- /dev/null +++ b/darkplaces-icon.xpm @@ -0,0 +1,127 @@ +/* XPM */ +static char * xonotic_32_xpm[] = { +"32 32 92 1", +" c None", +". c #000509", +"+ c #0F0303", +"@ c #150400", +"# c #1B0400", +"$ c #010C14", +"% c #220700", +"& c #010F1A", +"* c #250700", +"= c #2B0900", +"- c #011321", +"; c #310A03", +"> c #001628", +", c #330B00", +"' c #390B03", +") c #400A01", +"! c #3C0E00", +"~ c #051A31", +"{ c #331103", +"] c #430D00", +"^ c #4D1002", +"/ c #0A1F36", +"( c #141E29", +"_ c #451A07", +": c #082743", +"< c #0A273F", +"[ c #4F1D08", +"} c #5B1B07", +"| c #182C3F", +"1 c #0C2F51", +"2 c #5D2409", +"3 c #65240A", +"4 c #562812", +"5 c #4D2C1B", +"6 c #0D3A65", +"7 c #662A06", +"8 c #722D0F", +"9 c #743101", +"0 c #2C3F53", +"a c #77310A", +"b c #1A4673", +"c c #7C3908", +"d c #683D29", +"e c #733B1E", +"f c #823A03", +"g c #214C76", +"h c #8B3E18", +"i c #8F410D", +"j c #963F11", +"k c #604D4A", +"l c #255A88", +"m c #255A9B", +"n c #295B8F", +"o c #9F4610", +"p c #984A17", +"q c #255EA5", +"r c #1761B1", +"s c #9A4A21", +"t c #A54C15", +"u c #475E79", +"v c #346399", +"w c #A2511E", +"x c #3E6792", +"y c #5C6272", +"z c #266BBB", +"A c #2271BD", +"B c #4D6C8F", +"C c #3C6FA5", +"D c #B15A26", +"E c #3472BA", +"F c #3373B4", +"G c #3479C1", +"H c #4178AE", +"I c #287ED1", +"J c #347CCA", +"K c #387FC7", +"L c #4380C1", +"M c #3A84D2", +"N c #5489C0", +"O c #488CD4", +"P c #648AB7", +"Q c #628DB2", +"R c #678DBA", +"S c #5691CC", +"T c #748CA8", +"U c #5F9AD7", +"V c #6D99CC", +"W c #74A4DA", +"X c #81A4C9", +"Y c #7AACDC", +"Z c #8DBCE9", +"` c #98C2EA", +" ", +" ", +" E E ", +" AUG EUA ", +" SW WS ", +" SY YS ", +" LZr rZL ", +" E`E cwcppc E`E ", +" YW pwh}h3}sp WY ", +" GXL w8hD8^3swD LXG ", +" VR is^]8h^ai9 RV ", +" zxS p8]]]]]]Dpptf Sxz ", +" JlO t}))))))))}io OlJ ", +" MgJ fo]!!!!!!!!8o JgM ", +" MbI ih}t!''''''8i IbM ", +" K6M ijht3,,,,,,!i M6K ", +" K6K otffa3;;;;;;a9 K6K ", +" K6Fq f ftia======a rF6K ", +" M1nz f!======a An1M ", +" Ib1K a*******29 K1bI ", +" rv1bJ c[%%%%%%%%a9 Jb1vr ", +" K::Fq c7%%%%%%%%%*2a9 mF::K ", +" Ag:1Le_############%_2eH1:gA ", +" K//:Hd{############{dH://K ", +" zv~~/Ck[%@@@@@@@@%[kC/~~vz ", +" Jg>>>gCy4!@++@!4yCg>>>gJ ", +" Jg----= portal1_idx) { - Draw_CylindricLine(p, q, 4, "", 1, 0, '0 0 1', 0.5, DRAWFLAG_NORMAL); + Draw_CylindricLine(p, q, 4, "", 1, 0, '0 0 1', 0.5, DRAWFLAG_NORMAL, view_origin); } else { - Draw_CylindricLine(p, q, 4, "", 1, 0, '1 0 0', 0.5, DRAWFLAG_NORMAL); + Draw_CylindricLine(p, q, 4, "", 1, 0, '1 0 0', 0.5, DRAWFLAG_NORMAL, view_origin); } --idx; } @@ -102,7 +102,7 @@ void CheckForGamestartChange() { if (previous_game_starttime != startTime) { if ((time + 5.0) < startTime) { //if connecting to server while restart was active don't always play prepareforbattle - sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/prepareforbattle.wav"), VOL_BASEVOICE, ATTN_NONE); + sound(world, CHAN_AUTO, strcat("announcer/", cvar_string("cl_announcer"), "/prepareforbattle.wav"), VOL_BASEVOICE, ATTN_NONE); } if (time < startTime) { restartAnnouncer = spawn(); @@ -354,6 +354,12 @@ void CSQC_UpdateView(float w, float h) float fov; float f, i, j; vector v, vo; + vector vf_size, vf_min; + + vf_size = R_SetView3fv(VF_SIZE); + vf_min = R_SetView3fv(VF_MIN); + vid_width = vf_size_x; + vid_height = vf_size_y; vector reticle_pos, reticle_size; @@ -398,9 +404,6 @@ void CSQC_UpdateView(float w, float h) view_set = 1; } - vid_width = w; - vid_height = h; - #ifdef BLURTEST if(time > blurtest_time0 && time < blurtest_time1) { @@ -488,6 +491,10 @@ void CSQC_UpdateView(float w, float h) // ALWAYS Clear Current Scene First R_ClearScene(); + // FIXME engine bug? VF_SIZE and VF_MIN are not restored to sensible values by this + R_SetView(VF_SIZE, vf_size); + R_SetView(VF_MIN, vf_min); + // Assign Standard Viewflags // Draw the World (and sky) R_SetView(VF_DRAWWORLD, 1); @@ -623,11 +630,6 @@ void CSQC_UpdateView(float w, float h) self.draw2d(); self = e; - // draw hud - if(cvar("r_letterbox") == 0) { - HUD_DrawCenterPrint(); // draw centerprint messages even if viewsize >= 120 - } - float hud; hud = getstati(STAT_HUD); if(hud == HUD_SPIDERBOT) @@ -645,7 +647,7 @@ void CSQC_UpdateView(float w, float h) CSQC_common_hud(); // crosshair goes VERY LAST - if(!scoreboard_active && !camera_active) { + if(!scoreboard_active && !camera_active && intermission != 2) { // TrueAim check float shottype; float bullets, ring_scale; @@ -883,6 +885,11 @@ void CSQC_UpdateView(float w, float h) if(autocvar__hud_configure) HUD_Panel_Mouse(); + + // let's reset the view back to normal for the end + R_SetView(VF_MIN, '0 0 0'); + R_SetView(VF_SIZE, '1 0 0' * w + '0 1 0' * h); + // be safe against triggerbots until everyone has the fixed engine // this call is meant to overwrite the trace globals by something // unsuspicious @@ -1204,23 +1211,29 @@ void CSQC_common_hud(void) acc_lev[i] = stof(argv(i)); } - // hud first - HUD_Main(); + HUD_Main(); // always run these functions for alpha checks + HUD_DrawScoreboard(); - // scoreboard/accuracy - if (intermission == 2 && !scoreboard_showaccuracy && !scoreboard_showscores) // map voting screen + if (scoreboard_showscores || scoreboard_showscores_force || getstati(STAT_HEALTH) <= 0 || intermission == 1) // scoreboard/accuracy + { + HUD_Reset(); + // HUD_DrawScoreboard takes care of centerprint_start + } + else if (intermission == 2) // map voting screen { HUD_FinaleOverlay(); HUD_Reset(); - } - else if(scoreboard_showaccuracy && spectatee_status != -1) - HUD_DrawAccuracyStats(); - else - HUD_DrawScoreboard(); - if (scoreboard_showscores || scoreboard_showaccuracy || scoreboard_showscores_force || getstati(STAT_HEALTH) <= 0 || intermission == 1) - HUD_Reset(); + centerprint_start_x = 0; + centerprint_start_y = cvar("scr_centerpos") * vid_conheight; + } + else // hud + { + centerprint_start_x = 0; + centerprint_start_y = cvar("scr_centerpos") * vid_conheight; + } + HUD_DrawCenterPrint(); break; case HUD_SPIDERBOT: diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index 0c2df0e636..5e724442b7 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -10,7 +10,7 @@ var float autocvar_cl_gentle; var float autocvar_cl_gentle_gibs; var float autocvar_cl_gentle_messages; -var float autocvar_hud_color_bg_team; +var float autocvar_scoreboard_color_bg_team; var float autocvar__menu_alpha; diff --git a/qcsrc/client/csqc_builtins.qc b/qcsrc/client/csqc_builtins.qc index ec2ab9a319..760197a276 100644 --- a/qcsrc/client/csqc_builtins.qc +++ b/qcsrc/client/csqc_builtins.qc @@ -79,6 +79,7 @@ void () R_ClearScene = #300; void (float mask) R_AddEntities = #301; void (entity e) R_AddEntity = #302; float (float property, ...) R_SetView = #303; +vector (float property, ...) R_SetView3fv = #303; void () R_RenderScene = #304; void (vector org, float radius, vector rgb) R_AddDynamicLight = #305; void () R_CalcRefDef = #306; @@ -292,6 +293,7 @@ entity(vector org, float rad) findradius = #22; string(float uselocaltime, string format, ...) strftime = #478; float(float timer) gettime = #519; +#define GETTIME_REALTIME 1 #define GETTIME_CDTRACK 4 float(string s) tokenize_console = #514; diff --git a/qcsrc/client/effects.qc b/qcsrc/client/effects.qc index bbee658009..2e946fc830 100644 --- a/qcsrc/client/effects.qc +++ b/qcsrc/client/effects.qc @@ -10,8 +10,8 @@ void SUB_Remove() void b_draw() { - //Draw_CylindricLine(self.fx_start, self.fx_end, self.fx_with, self.fx_texture, 0, time * 3, '1 1 1', 0.7, DRAWFLAG_ADDITIVE); - Draw_CylindricLine(self.fx_start, self.fx_end, self.fx_with, self.fx_texture, (self.fx_with/256), 0, '1 1 1', 1, DRAWFLAG_ADDITIVE); + //Draw_CylindricLine(self.fx_start, self.fx_end, self.fx_with, self.fx_texture, 0, time * 3, '1 1 1', 0.7, DRAWFLAG_ADDITIVE, view_origin); + Draw_CylindricLine(self.fx_start, self.fx_end, self.fx_with, self.fx_texture, (self.fx_with/256), 0, '1 1 1', 1, DRAWFLAG_ADDITIVE, view_origin); } void b_make(vector s,vector e, string t,float l,float z) diff --git a/qcsrc/client/hook.qc b/qcsrc/client/hook.qc index b769947eeb..c1e8383aa6 100644 --- a/qcsrc/client/hook.qc +++ b/qcsrc/client/hook.qc @@ -5,7 +5,7 @@ .float HookSilent; .float HookRange; -void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float alpha, float drawflag) +void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float alpha, float drawflag, vector vieworg) { // I want to draw a quad... // from and to are MIDPOINTS. @@ -17,7 +17,7 @@ void Draw_CylindricLine(vector from, vector to, float thickness, string texture, length_tex = aspect * vlen(to - from) / thickness; // direction is perpendicular to the view normal, and perpendicular to the axis - thickdir = normalize(cross(axis, view_origin - from)); + thickdir = normalize(cross(axis, vieworg - from)); /* print("from ", vtos(from), "\n"); @@ -46,11 +46,14 @@ float Draw_GrapplingHook_trace_callback_a; void Draw_GrapplingHook_trace_callback(vector start, vector hit, vector end) { float i; + vector vorg; + vorg = WarpZone_TransformOrigin(WarpZone_trace_transform, view_origin); for(i = 0; i < Draw_GrapplingHook_trace_callback_a; ++i) - Draw_CylindricLine(hit, start, 8, Draw_GrapplingHook_trace_callback_tex, 0.25, Draw_GrapplingHook_trace_callback_rnd, Draw_GrapplingHook_trace_callback_rgb, min(1, Draw_GrapplingHook_trace_callback_a - i), DRAWFLAG_NORMAL); + Draw_CylindricLine(hit, start, 8, Draw_GrapplingHook_trace_callback_tex, 0.25, Draw_GrapplingHook_trace_callback_rnd, Draw_GrapplingHook_trace_callback_rgb, min(1, Draw_GrapplingHook_trace_callback_a - i), DRAWFLAG_NORMAL, vorg); Draw_GrapplingHook_trace_callback_rnd += 0.25 * vlen(hit - start) / 8; } +.float teleport_time; void Draw_GrapplingHook() { vector a, b, atrans; @@ -61,6 +64,13 @@ void Draw_GrapplingHook() vector vs; float intensity, offset; + if(self.teleport_time) + if(time > self.teleport_time) + { + sound (self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM); // safeguard + self.teleport_time = 0; + } + InterpolateOrigin_Do(); s = cvar("cl_gunalign"); @@ -251,7 +261,7 @@ void Ent_ReadHook(float bIsNew, float type) InterpolateOrigin_Note(); - if(bIsNew) + if(bIsNew || !self.teleport_time) { self.draw = Draw_GrapplingHook; self.entremove = Remove_GrapplingHook; @@ -272,6 +282,8 @@ void Ent_ReadHook(float bIsNew, float type) break; } } + + self.teleport_time = time + 10; } void Hook_Precache() diff --git a/qcsrc/client/hud.qc b/qcsrc/client/hud.qc index f2b900fa97..c1dbede921 100644 --- a/qcsrc/client/hud.qc +++ b/qcsrc/client/hud.qc @@ -131,7 +131,7 @@ float stringwidth_nocolors(string s, vector theSize) #define CENTERPRINT_MAX_LINES 30 string centerprint_messages[CENTERPRINT_MAX_LINES]; float centerprint_width[CENTERPRINT_MAX_LINES]; -vector centerprint_start; +float centerprint_time; float centerprint_expire; float centerprint_num; float centerprint_offset_hint; @@ -182,6 +182,8 @@ void centerprint(string strMessage) while(getWrappedLine_remaining) { s = getWrappedLine(vid_conwidth * 0.75, centerprint_fontsize, stringwidth_colors); + if(centerprint_messages[i] != s) // don't fade the same message in, looks stupid + centerprint_time = time; if(centerprint_messages[i]) strunzone(centerprint_messages[i]); centerprint_messages[i] = strzone(s); @@ -208,8 +210,6 @@ void centerprint(string strMessage) if(havail > vid_conheight - 70) havail = vid_conheight - 70; // avoid overlapping HUD - centerprint_start_x = 0; - #if 0 float forbiddenmin, forbiddenmax, allowedmin, allowedmax, preferred; @@ -260,17 +260,10 @@ void centerprint(string strMessage) centerprint_start_y = bound(forbiddenmax, preferred, allowedmax); } #else - centerprint_start_y = - min( - max( - max(scoreboard_bottom, vid_conheight * 0.5 + 16), - (havail - h)/2 - ), - havail - h - ); #endif centerprint_num = i; + centerprint_expire = time + cvar("scr_centertime"); } @@ -279,32 +272,39 @@ void HUD_DrawCenterPrint (void) float i; vector pos; string ts; - float a; - - //if(time > centerprint_expire) - // return; + float a, sz; - //a = bound(0, 1 - 2 * (time - centerprint_expire), 1); - a = bound(0, 1 - 4 * (time - centerprint_expire), 1); - //sz = 1.2 / (a + 0.2); + if(time - centerprint_time < 0.25) + a = (time - centerprint_time) / 0.25; + else + a = bound(0, 1 - 4 * (time - centerprint_expire), 1); if(a <= 0) return; + sz = 0.8 + (a / 5); + + if(centerprint_num * cvar("scr_centersize") > 24 && HUD_WouldDrawScoreboard()) // 24 = height of Scoreboard text + { + centerprint_start_y = scoreboard_bottom + centerprint_fontsize_y; + } pos = centerprint_start; for (i=0; i vid_conwidth) + tmp_size_x = vid_conwidth - panel_pos_x; + if (panel_pos_y + panel_size_copied_y > vid_conheight) + tmp_size_y = vid_conheight - panel_pos_y; + + if (panel_size == tmp_size) + return true; + + // backup first! + panel_pos_backup = panel_pos; + panel_size_backup = panel_size; + highlightedPanel_backup = highlightedPanel_prev; + + string s; + s = strcat(ftos(tmp_size_x/vid_conwidth), " ", ftos(tmp_size_y/vid_conheight)); + cvar_set(strcat("hud_panel_", panel_name, "_size"), s); + } + else if(nPrimary == 'z') // undo last action + { + if (bInputType == 1) + return true; + //restore previous values + if (highlightedPanel_backup != -1) + { + HUD_Panel_GetName(highlightedPanel_backup) + string s; + s = strcat(ftos(panel_pos_backup_x/vid_conwidth), " ", ftos(panel_pos_backup_y/vid_conheight)); + cvar_set(strcat("hud_panel_", panel_name, "_pos"), s); + s = strcat(ftos(panel_size_backup_x/vid_conwidth), " ", ftos(panel_size_backup_y/vid_conheight)); + cvar_set(strcat("hud_panel_", panel_name, "_size"), s); + highlightedPanel_backup = -1; + } + } + } else if(nPrimary == K_UPARROW || nPrimary == K_DOWNARROW || nPrimary == K_LEFTARROW || nPrimary == K_RIGHTARROW) { if (bInputType == 1) @@ -1226,6 +1318,7 @@ void HUD_Panel_Highlight() } float highlightcheck; +vector prev_pos, prev_size; void HUD_Panel_Mouse() { // TODO: needs better check... is there any float that contains the current state of the menu? _menu_alpha isn't apparently updated the frame the menu gets enabled @@ -1255,9 +1348,28 @@ void HUD_Panel_Mouse() if(mouseClicked) { if(prevMouseClicked == 0) + { HUD_Panel_Highlight(); // sets highlightedPanel, highlightedAction, panel_click_distance, panel_click_resizeorigin + // and calls HUD_Panel_UpdatePosSizeForId() for the highlighted panel + prev_pos = panel_pos; + prev_size = panel_size; + } + else + HUD_Panel_UpdatePosSizeForId(highlightedPanel) - hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions); + if (prev_pos != panel_pos || prev_size != panel_size) + { + hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions); + // backup! + panel_pos_backup = prev_pos; + panel_size_backup = prev_size; + highlightedPanel_backup = highlightedPanel; + } + else + // in case the clicked panel is inside another panel and we aren't + // moving it, avoid the immediate "fix" of its position/size + // (often unwanted and hateful) by disabling collisions check + hud_configure_checkcollisions = false; if(highlightedAction == 1) HUD_Panel_SetPos(mousepos - panel_click_distance); @@ -1385,14 +1497,94 @@ void HUD_Weapons(void) if(!autocvar_hud_panel_weapons && !autocvar__hud_configure) return; + float timeout = cvar("hud_panel_weapons_timeout"); + float timeout_effect_length, timein_effect_length; + if (cvar("hud_panel_weapons_timeout_effect") == 0) + { + timeout_effect_length = 0; + timein_effect_length = 0; + } + else + { + timeout_effect_length = 0.75; + timein_effect_length = 0.375; + } + + if (timeout && time >= weapontime + timeout + timeout_effect_length && !autocvar__hud_configure) + { + weaponprevtime = time; + return; + } + active_panel = HUD_PANEL_WEAPONS; HUD_Panel_UpdateCvars(weapons); - vector pos, mySize; - float i, weapid, fade, weapon_stats, weapon_number, weapon_cnt; - pos = panel_pos; - mySize = panel_size; + if (timeout && time >= weapontime + timeout && !autocvar__hud_configure) + { + float f = (time - (weapontime + timeout)) / timeout_effect_length; + if (cvar("hud_panel_weapons_timeout_effect")) + { + panel_bg_alpha *= (1 - f); + panel_fg_alpha *= (1 - f); + } + if (cvar("hud_panel_weapons_timeout_effect") == 1) + { + f *= f; // for a cooler movement + vector center; + center_x = panel_pos_x + panel_size_x/2; + center_y = panel_pos_y + panel_size_y/2; + float screen_ar = vid_conwidth/vid_conheight; + if (center_x/center_y < screen_ar) //bottom left + { + if ((vid_conwidth - center_x)/center_y < screen_ar) //bottom + panel_pos_y += f * (vid_conheight - panel_pos_y); + else //left + panel_pos_x -= f * (panel_pos_x + panel_size_x); + } + else //top right + { + if ((vid_conwidth - center_x)/center_y < screen_ar) //right + panel_pos_x += f * (vid_conwidth - panel_pos_x); + else //top + panel_pos_y -= f * (panel_pos_y + panel_size_y); + } + } + weaponprevtime = time - (1 - f) * timein_effect_length; + } + else if (timeout && time < weaponprevtime + timein_effect_length && !autocvar__hud_configure) + { + float f = (time - weaponprevtime) / timein_effect_length; + if (cvar("hud_panel_weapons_timeout_effect")) + { + panel_bg_alpha *= (f); + panel_fg_alpha *= (f); + } + if (cvar("hud_panel_weapons_timeout_effect") == 1) + { + f *= f; // for a cooler movement + f = 1 - f; + vector center; + center_x = panel_pos_x + panel_size_x/2; + center_y = panel_pos_y + panel_size_y/2; + float screen_ar = vid_conwidth/vid_conheight; + if (center_x/center_y < screen_ar) //bottom left + { + if ((vid_conwidth - center_x)/center_y < screen_ar) //bottom + panel_pos_y += f * (vid_conheight - panel_pos_y); + else //left + panel_pos_x -= f * (panel_pos_x + panel_size_x); + } + else //top right + { + if ((vid_conwidth - center_x)/center_y < screen_ar) //right + panel_pos_x += f * (vid_conwidth - panel_pos_x); + else //top + panel_pos_y -= f * (panel_pos_y + panel_size_y); + } + } + } + float i, weapid, fade, weapon_stats, weapon_number, weapon_cnt; weapon_cnt = 0; for(i = WEP_FIRST; i <= WEP_LAST; ++i) { @@ -1425,8 +1617,8 @@ void HUD_Weapons(void) HUD_Panel_DrawBg(1); if(panel_bg_padding) { - pos += '1 1 0' * panel_bg_padding; - mySize -= '2 2 0' * panel_bg_padding; + panel_pos += '1 1 0' * panel_bg_padding; + panel_size -= '2 2 0' * panel_bg_padding; } // hits @@ -1449,7 +1641,7 @@ void HUD_Weapons(void) HUD_Weapons_Clear(); float rows, columns; - rows = mySize_y/mySize_x; + rows = panel_size_y/panel_size_x; rows = bound(1, floor((sqrt(4 * autocvar_hud_panel_weapons_aspect * rows * WEP_COUNT + rows * rows) + rows + 0.5) / 2), WEP_COUNT); columns = ceil(WEP_COUNT/rows); @@ -1467,8 +1659,8 @@ void HUD_Weapons(void) for(i = 0; i < weapon_cnt; ++i) { - wpnpos = pos + eX * column * mySize_x*(1/columns) + eY * row * mySize_y*(1/rows); - wpnsize = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows); + wpnpos = panel_pos + eX * column * panel_size_x*(1/columns) + eY * row * panel_size_y*(1/rows); + wpnsize = eX * panel_size_x*(1/columns) + eY * panel_size_y*(1/rows); self = weaponorder[i]; weapid = self.impulse; @@ -1510,9 +1702,9 @@ void HUD_Weapons(void) drawpic_aspect_skin(wpnpos, strcat("weapon", self.netname), wpnsize, '1 1 1', fade * panel_fg_alpha, DRAWFLAG_NORMAL); if(autocvar_hud_panel_weapons_label == 1) // weapon number - drawstring(wpnpos, ftos(weapid), '1 1 0' * 0.5 * mySize_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + drawstring(wpnpos, ftos(weapid), '1 1 0' * 0.5 * panel_size_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); else if(autocvar_hud_panel_weapons_label == 2) // bind - drawstring(wpnpos, getcommandkey(ftos(weapid), strcat("impulse ", ftos(weapid))), '1 1 0' * 0.5 * mySize_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + drawstring(wpnpos, getcommandkey(ftos(weapid), strcat("impulse ", ftos(weapid))), '1 1 0' * 0.5 * panel_size_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); // draw ammo status bar if(autocvar_hud_panel_weapons_ammo && weapid != WEP_TUBA && weapid != WEP_LASER && weapid != WEP_PORTO) @@ -1845,10 +2037,17 @@ void HUD_Powerups(void) { pos = panel_pos; mySize = panel_size; - float strength_time, shield_time; - - strength_time = bound(0, getstatf(STAT_STRENGTH_FINISHED) - time, 99); - shield_time = bound(0, getstatf(STAT_INVINCIBLE_FINISHED) - time, 99); + float strength_time, shield_time; + if(autocvar__hud_configure) + { + strength_time = 15; + shield_time = 27; + } + else + { + strength_time = bound(0, getstatf(STAT_STRENGTH_FINISHED) - time, 99); + shield_time = bound(0, getstatf(STAT_INVINCIBLE_FINISHED) - time, 99); + } HUD_Panel_DrawBg(bound(0, max(strength_time, shield_time), 1)); if(panel_bg_padding) @@ -1857,12 +2056,6 @@ void HUD_Powerups(void) { mySize -= '2 2 0' * panel_bg_padding; } - if(autocvar__hud_configure) - { - strength_time = 15; - shield_time = 27; - } - vector barpos, barsize; vector picpos; vector numpos; @@ -2391,7 +2584,7 @@ void HUD_KillNotify_Push(string attacker, string victim, float actiontype, float killnotify_victims[0] = strzone(victim); } -void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) +void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) // s1 = attacker, s2 = victim { float w; float alsoprint, gentle; @@ -2472,96 +2665,104 @@ void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) } else if(type == KILL_FIRST_BLOOD) print("^1",s1, "^1 drew first blood", "\n"); - // TODO: icon! - else if (type == DEATH_TELEFRAG) - print ("^1",s1, "^1 was telefragged by ", s2, "\n"); + else if (type == DEATH_TELEFRAG) { + HUD_KillNotify_Push(s1, s2, 1, DEATH_TELEFRAG); + if(gentle) + print ("^1",s2, "^1 tried to occupy ", s1, "^1's teleport destination space\n"); + else + print ("^1",s2, "^1 was telefragged by ", s1, "\n"); + } else if (type == DEATH_DROWN) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_DROWN); + HUD_KillNotify_Push(s1, s2, 1, DEATH_DROWN); if(alsoprint) - print ("^1",s1, "^1 was drowned by ", s2, "\n"); + print ("^1",s2, "^1 was drowned by ", s1, "\n"); } else if (type == DEATH_SLIME) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_SLIME); + HUD_KillNotify_Push(s1, s2, 1, DEATH_SLIME); if(alsoprint) - print ("^1",s1, "^1 was slimed by ", s2, "\n"); + print ("^1",s2, "^1 was slimed by ", s1, "\n"); } else if (type == DEATH_LAVA) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_LAVA); + HUD_KillNotify_Push(s1, s2, 1, DEATH_LAVA); if(alsoprint) - print ("^1",s1, "^1 was cooked by ", s2, "\n"); + print ("^1",s2, "^1 was cooked by ", s1, "\n"); } else if (type == DEATH_FALL) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_FALL); + HUD_KillNotify_Push(s1, s2, 1, DEATH_FALL); if(alsoprint) - print ("^1",s1, "^1 was grounded by ", s2, "\n"); + print ("^1",s2, "^1 was grounded by ", s1, "\n"); } else if (type == DEATH_SHOOTING_STAR) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_SHOOTING_STAR); + HUD_KillNotify_Push(s1, s2, 1, DEATH_SHOOTING_STAR); if(alsoprint) - print ("^1",s1, "^1 was shot into space by ", s2, "\n"); + print ("^1",s2, "^1 was shot into space by ", s1, "\n"); } else if (type == DEATH_SWAMP) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 was conserved by ", s2, "\n"); + print ("^1",s2, "^1 was conserved by ", s1, "\n"); } else if (type == DEATH_HURTTRIGGER) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_HURTTRIGGER); + HUD_KillNotify_Push(s1, s2, 1, DEATH_HURTTRIGGER); if(alsoprint) - print("^1",s1, "^1 was thrown into a world of hurt by ", s2, "\n"); + print("^1",s2, "^1 was thrown into a world of hurt by ", s1, "\n"); } else if(type == DEATH_SBCRUSH) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 was crushed by ^1", s2, "\n"); + print ("^1",s2, "^1 was crushed by ^1", s1, "\n"); } else if(type == DEATH_SBMINIGUN) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 got shredded by ^1", s2, "\n"); + print ("^1",s2, "^1 got shredded by ^1", s1, "\n"); } else if(type == DEATH_SBROCKET) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 was blased to bits by ^1", s2, "\n"); + print ("^1",s2, "^1 was blased to bits by ^1", s1, "\n"); } else if(type == DEATH_SBBLOWUP) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 got caught in the destruction of ^1", s2, "'s vehicle\n"); + print ("^1",s2, "^1 got caught in the destruction of ^1", s1, "'s vehicle\n"); } else if(type == DEATH_WAKIGUN) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 was bolted down by ^1", s2, "\n"); + print ("^1",s2, "^1 was bolted down by ^1", s1, "\n"); } else if(type == DEATH_WAKIROCKET) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 could find no shelter from ^1", s2, "'s rockets\n"); + print ("^1",s2, "^1 could find no shelter from ^1", s1, "'s rockets\n"); } else if(type == DEATH_WAKIBLOWUP) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 dies when ^1", s2, "'s wakizashi dies.\n"); + print ("^1",s2, "^1 dies when ^1", s1, "'s wakizashi dies.\n"); } else if(type == DEATH_TURRET) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 was pushed into the line of fire by ^1", s2, "\n"); + print ("^1",s2, "^1 was pushed into the line of fire by ^1", s1, "\n"); } else if(type == DEATH_TOUCHEXPLODE) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 was pushed into an accident by ^1", s2, "\n"); + print ("^1",s2, "^1 was pushed into an accident by ^1", s1, "\n"); } else if(type == DEATH_CHEAT) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 was unfairly eliminated by ^1", s2, "\n"); + print ("^1",s2, "^1 was unfairly eliminated by ^1", s1, "\n"); } else if (type == DEATH_FIRE) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 was burnt to death by ^1", s2, "\n"); + print ("^1",s2, "^1 was burnt to death by ^1", s1, "\n"); } else if (type == DEATH_CUSTOM) { - HUD_KillNotify_Push(s2, s1, 1, DEATH_CUSTOM); + HUD_KillNotify_Push(s1, s2, 1, DEATH_CUSTOM); if(alsoprint) - print ("^1",s1, "^1 ", s2, "\n"); + print("^1", sprintf(s3, strcat(s2, "^1"), strcat(s1, "^1")), "\n"); + } else if (type == DEATH_HURTTRIGGER) { + HUD_KillNotify_Push(s1, s2, 1, DEATH_HURTTRIGGER); + if(alsoprint) + print("^1", sprintf(s3, strcat(s2, "^1"), strcat(s1, "^1")), "\n"); } else { - HUD_KillNotify_Push(s2, s1, 1, DEATH_GENERIC); + HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC); if(alsoprint) - print ("^1",s1, "^1 was fragged by ", s2, "\n"); + print ("^1",s2, "^1 was fragged by ", s1, "\n"); } } else if(msg == MSG_SPREE) { if(type == KILL_END_SPREE) { @@ -2662,11 +2863,11 @@ void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) } else if (type == DEATH_CUSTOM) { HUD_KillNotify_Push(s1, "", 0, DEATH_CUSTOM); if(alsoprint) - print ("^1",s1, "^1 ", s2, "\n"); + print("^1", sprintf(s2, strcat(s1, "^1")), "\n"); } else if (type == DEATH_HURTTRIGGER) { HUD_KillNotify_Push(s1, "", 0, DEATH_HURTTRIGGER); if(alsoprint) - print ("^1",s1, "^1 was in the wrong place\n"); + print("^1", sprintf(s2, strcat(s1, "^1")), "\n"); } else if(type == DEATH_TOUCHEXPLODE) { HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC); if(alsoprint) @@ -2752,7 +2953,7 @@ void HUD_Centerprint(string s1, string s2, float type, float msg) centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, "^1Don't shoot your team mates!")); } else if (type == DEATH_QUIET) { // do nothing - } else if (type == DEATH_KILL) { + } else { // generic message if(gentle) centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, "^1You need to be more careful!")); else @@ -2795,7 +2996,7 @@ void HUD_Centerprint(string s1, string s2, float type, float msg) } else { centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, "^4You fragged ^7", s1, s2)); } - } else if (type == KILL_FRAGGED) { + } else { // generic message if(gentle) { centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, "^1You were scored against by ^7", s1, s2)); } else { @@ -2846,7 +3047,7 @@ void HUD_Notify (void) float width_attacker; string attacker, victim; - float i, j; + float i, j, w; for(j = 0; j < entries; ++j) { s = ""; @@ -2870,7 +3071,7 @@ void HUD_Notify (void) a = 0; } - float w; + w = -1; w = DEATH_WEAPONOF(killnotify_deathtype[j]); // TODO: maybe print in team colors? @@ -3024,6 +3225,10 @@ void HUD_Notify (void) { s = "notify_teamkill_red"; } + else if(killnotify_deathtype[j] == DEATH_TELEFRAG) + { + s = "notify_telefrag"; + } else if(killnotify_deathtype[j] == DEATH_DROWN) { s = "notify_water"; @@ -3547,6 +3752,17 @@ void HUD_VoteWindow(void) pos = panel_pos; mySize = panel_size; + if(!autocvar__hud_configure) + { + panel_fg_alpha = autocvar_hud_panel_fg_alpha; + panel_bg_alpha_str = autocvar_hud_panel_vote_bg_alpha; + + if(panel_bg_alpha_str == "") { + panel_bg_alpha_str = ftos(autocvar_hud_panel_bg_alpha); + } + panel_bg_alpha = stof(panel_bg_alpha_str); + } + string s; float a; if(vote_active != vote_prev) { @@ -3569,9 +3785,9 @@ void HUD_VoteWindow(void) if(!vote_alpha) return; - a = vote_alpha * bound(autocvar_hud_panel_vote_alreadyvoted_alpha, 1 - vote_highlighted, 1); - + a = panel_bg_alpha * vote_alpha * bound(autocvar_hud_panel_vote_alreadyvoted_alpha, 1 - vote_highlighted, 1); HUD_Panel_DrawBg(a); + a = panel_fg_alpha * vote_alpha * bound(autocvar_hud_panel_vote_alreadyvoted_alpha, 1 - vote_highlighted, 1); if(panel_bg_padding) { pos += '1 1 0' * panel_bg_padding; @@ -3597,37 +3813,37 @@ void HUD_VoteWindow(void) mySize = newSize; s = "A vote has been called for:"; - drawstring_aspect(pos, s, eX * mySize_x + eY * (2/8) * mySize_y, '1 1 1', a * panel_fg_alpha, DRAWFLAG_NORMAL); + drawstring_aspect(pos, s, eX * mySize_x + eY * (2/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL); s = textShortenToWidth(vote_called_vote, mySize_x, '1 1 0' * mySize_y * (1.75/8), stringwidth_colors); if(autocvar__hud_configure) s = "^1Configure the HUD"; - drawcolorcodedstring_aspect(pos + eY * (2/8) * mySize_y, s, eX * mySize_x + eY * (1.75/8) * mySize_y, a * panel_fg_alpha, DRAWFLAG_NORMAL); + drawcolorcodedstring_aspect(pos + eY * (2/8) * mySize_y, s, eX * mySize_x + eY * (1.75/8) * mySize_y, a, DRAWFLAG_NORMAL); // print the yes/no counts - s = strcat("Yes (", getcommandkey("not bound", "vyes"), "): ", ftos(vote_yescount)); - drawstring_aspect(pos + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '0 1 0', a * panel_fg_alpha, DRAWFLAG_NORMAL); - s = strcat("No (", getcommandkey("not bound", "vno"), "): ", ftos(vote_nocount)); - drawstring_aspect(pos + eX * 0.5 * mySize_x + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '1 0 0', a * panel_fg_alpha, DRAWFLAG_NORMAL); + s = strcat("Yes (", getcommandkey("vyes", "vyes"), "): ", ftos(vote_yescount)); + drawstring_aspect(pos + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '0 1 0', a, DRAWFLAG_NORMAL); + s = strcat("No (", getcommandkey("vno", "vno"), "): ", ftos(vote_nocount)); + drawstring_aspect(pos + eX * 0.5 * mySize_x + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '1 0 0', a, DRAWFLAG_NORMAL); // draw the progress bar backgrounds - drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_back", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a * panel_fg_alpha, DRAWFLAG_NORMAL); + drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_back", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL); // draw the highlights if(vote_highlighted == 1) { drawsetcliparea(pos_x, pos_y, mySize_x * 0.5, mySize_y); - drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_voted", eX * mySize_x + eY * (3/8) * mySize_y, '0 1 0', a * panel_fg_alpha, DRAWFLAG_NORMAL); + drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_voted", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL); } else if(vote_highlighted == 2) { drawsetcliparea(pos_x + 0.5 * mySize_x, pos_y, mySize_x * 0.5, mySize_y); - drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_voted", eX * mySize_x + eY * (3/8) * mySize_y, '0 1 0', a * panel_fg_alpha, DRAWFLAG_NORMAL); + drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_voted", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL); } // draw the progress bars drawsetcliparea(pos_x, pos_y, mySize_x * 0.5 * (vote_yescount/vote_needed), mySize_y); - drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_prog", eX * mySize_x + eY * (3/8) * mySize_y, '0 1 0', a * panel_fg_alpha, DRAWFLAG_NORMAL); + drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_prog", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL); drawsetcliparea(pos_x + mySize_x - mySize_x * 0.5 * (vote_nocount/vote_needed), pos_y, mySize_x * 0.5, mySize_y); - drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_prog", eX * mySize_x + eY * (3/8) * mySize_y, '1 0 0', a * panel_fg_alpha, DRAWFLAG_NORMAL); + drawpic_skin(pos + eY * (5/8) * mySize_y, "voteprogress_prog", eX * mySize_x + eY * (3/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL); drawresetcliparea(); @@ -4236,8 +4452,15 @@ void HUD_Chat(void) { panel_pos_y = panel_bg_border; panel_size_y = vid_conheight - panel_bg_border * 2; - if(panel_bg == "0") - panel_bg = "border"; // force a border when maximized + if(panel_bg == "0") // force a border when maximized + { + if(precache_pic(panel_bg) == "") { + panel_bg = strcat(hud_skin_path, "/border_default"); + if(precache_pic(panel_bg) == "") { + panel_bg = "gfx/hud/default/border_default"; + } + } + } panel_bg_alpha = max(0.75, panel_bg_alpha); // force an alpha of at least 0.75 } @@ -4305,29 +4528,32 @@ void HUD_EngineInfo(void) mySize -= '2 2 0' * panel_bg_padding; } + float currentTime = gettime(GETTIME_REALTIME); if(cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage")) { - frametimeavg = (frametimeavg + frametimeavg1 + frametimeavg2 + frametime)/4; // average three frametimes into framecounter for slightly more stable fps readings :P + float currentframetime = currentTime - prevfps_time; + frametimeavg = (frametimeavg + frametimeavg1 + frametimeavg2 + currentframetime)/4; // average three frametimes into framecounter for slightly more stable fps readings :P frametimeavg2 = frametimeavg1; frametimeavg1 = frametimeavg; float weight; weight = cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_new_weight"); - if(frametime > 0.0001) // filter out insane values which sometimes seem to occur and throw off the average? If you are getting 10,000 fps or more, then you don't need a framerate counter. + if(currentframetime > 0.0001) // filter out insane values which sometimes seem to occur and throw off the average? If you are getting 10,000 fps or more, then you don't need a framerate counter. { - if(fabs(prevfps - (1/frametimeavg)) > prevfps * cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold")) // if there was a big jump in fps, just force prevfps at current (1/frametime) to make big updates instant - prevfps = (1/frametime); + if(fabs(prevfps - (1/frametimeavg)) > prevfps * cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold")) // if there was a big jump in fps, just force prevfps at current (1/currentframetime) to make big updates instant + prevfps = (1/currentframetime); prevfps = (1 - weight) * prevfps + weight * (1/frametimeavg); // framecounter just used so there's no need for a new variable, think of it as "frametime average" } + prevfps_time = currentTime; } else { framecounter += 1; - if(time - prevfps_time > cvar("hud_panel_engineinfo_framecounter_time")) + if(currentTime - prevfps_time > cvar("hud_panel_engineinfo_framecounter_time")) { - prevfps = framecounter/cvar("hud_panel_engineinfo_framecounter_time"); + prevfps = framecounter/(currentTime - prevfps_time); framecounter = 0; - prevfps_time = time; + prevfps_time = currentTime; } } @@ -4340,6 +4566,11 @@ void HUD_EngineInfo(void) // Info messages panel (#14) // +#define drawInfoMessage(s)\ + if(autocvar_hud_panel_infomessages_flip)\ + o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize);\ + drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);\ + o_y += fontsize_y; void HUD_InfoMessages(void) { if(!autocvar_hud_panel_infomessages && !autocvar__hud_configure) @@ -4383,6 +4614,12 @@ void HUD_InfoMessages(void) vector fontsize; fontsize = '0.20 0.20 0' * mySize_y; + float a; + if(spectatee_status != 0) + a = 1; + else + a = panel_fg_alpha; + string s; if(!autocvar__hud_configure) { @@ -4392,35 +4629,22 @@ void HUD_InfoMessages(void) s = "^1Observing"; else s = strcat("^1Spectating: ^7", GetPlayerName(spectatee_status - 1)); - - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) if(spectatee_status == -1) - s = strcat("^1Press ^3", getcommandkey("primary fire", "+attack"), "^1 to spectate"); + s = strcat("^1Press ^3", getcommandkey("primary fire", "+fire"), "^1 to spectate"); else - s = strcat("^1Press ^3", getcommandkey("primary fire", "+attack"), "^1 for another player"); - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + s = strcat("^1Press ^3", getcommandkey("primary fire", "+fire"), "^1 for another player"); + drawInfoMessage(s) if(spectatee_status == -1) s = strcat("^1Use ^3", getcommandkey("next weapon", "weapnext"), "^1 or ^3", getcommandkey("previous weapon", "weapprev"), "^1 to change the speed"); else - s = strcat("^1Press ^3", getcommandkey("secondary fire", "+attack2"), "^1 to observe"); - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + s = strcat("^1Press ^3", getcommandkey("secondary fire", "+fire2"), "^1 to observe"); + drawInfoMessage(s) s = strcat("^1Press ^3", getcommandkey("server info", "+show_info"), "^1 for gamemode info"); - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) if(gametype == GAME_ARENA) s = "^1Wait for your turn to join"; @@ -4437,10 +4661,7 @@ void HUD_InfoMessages(void) } else s = strcat("^1Press ^3", getcommandkey("jump", "+jump"), "^1 to join"); - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) //show restart countdown: if (time < getstatf(STAT_GAMESTARTTIME)) { @@ -4448,17 +4669,14 @@ void HUD_InfoMessages(void) //we need to ceil, otherwise the countdown would be off by .5 when using round() countdown = ceil(getstatf(STAT_GAMESTARTTIME) - time); s = strcat("^1Game starts in ^3", ftos(countdown), "^1 seconds"); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL); + o_y += fontsize_y; } } if(warmup_stage && !intermission) { s = "^2Currently in ^1warmup^2 stage!"; - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) } string blinkcolor; @@ -4483,18 +4701,12 @@ void HUD_InfoMessages(void) else s = strcat("^2Waiting for others to ready up..."); } - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) } else if(warmup_stage && !intermission && !spectatee_status) { s = strcat("^2Press ^3", getcommandkey("ready", "ready"), "^2 to end warmup"); - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) } if(teamplay && !intermission && !spectatee_status && gametype != GAME_CA && teamnagger) @@ -4520,11 +4732,7 @@ void HUD_InfoMessages(void) if (tm.team != COLOR_SPECTATOR) if (tm.team_size == ts_max) s = strcat(s, " Press ^3", getcommandkey("team menu", "menu_showteamselect"), blinkcolor, " to adjust"); - - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) } } } @@ -4532,25 +4740,13 @@ void HUD_InfoMessages(void) else { s = "^7Press ^3ESC ^7to show HUD options."; - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) s = "^3Doubleclick ^7a panel for panel-specific options."; - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) s = "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and"; - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) s = "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments."; - if(autocvar_hud_panel_infomessages_flip) - o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); - drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); - o += eY * fontsize_y; + drawInfoMessage(s) } } @@ -4703,10 +4899,19 @@ void HUD_Main (void) { hud_skin_path = strcat("gfx/hud/", autocvar_hud_skin); + // global hud alpha fade if(disable_menu_alphacheck == 1) - menu_fade_alpha = 1; + hud_fade_alpha = 1; else - menu_fade_alpha = (1 - autocvar__menu_alpha); + hud_fade_alpha = (1 - autocvar__menu_alpha); + + if(scoreboard_fade_alpha) + hud_fade_alpha = (1 - scoreboard_fade_alpha); + + if(intermission == 2) // no hud during mapvote + hud_fade_alpha = 0; + else if(autocvar__menu_alpha == 0 && scoreboard_fade_alpha == 0) + hud_fade_alpha = 1; hud_border_thickness = bound(0, cvar("hud_border_thickness"), 5); hud_accuracy_border_thickness = bound(0, cvar_or("hud_accuracy_border_thickness", 1), 5); @@ -4758,9 +4963,12 @@ void HUD_Main (void) string pic; pic = strcat(hud_skin_path, "/", autocvar_hud_dock); if(precache_pic(pic) == "") { - pic = "gfx/hud/default/dock"; + pic = strcat(hud_skin_path, "/dock_medium"); + if(precache_pic(pic) == "") { + pic = "gfx/hud/default/dock_medium"; + } } - drawpic('0 0 0', pic, eX * vid_conwidth + eY * vid_conheight, color, autocvar_hud_dock_alpha * menu_fade_alpha, DRAWFLAG_NORMAL); // no aspect ratio forcing on dock... + drawpic('0 0 0', pic, eX * vid_conwidth + eY * vid_conheight, color, autocvar_hud_dock_alpha * hud_fade_alpha, DRAWFLAG_NORMAL); // no aspect ratio forcing on dock... } // cache the panel order into the panel_order array diff --git a/qcsrc/client/hud.qh b/qcsrc/client/hud.qh index bdc533edbd..e311c66a8a 100644 --- a/qcsrc/client/hud.qh +++ b/qcsrc/client/hud.qh @@ -1,5 +1,7 @@ float log(float f); +vector centerprint_start; + float panel_order[HUD_PANEL_NUM]; string hud_panelorder_prev; @@ -31,6 +33,7 @@ float ts_primary, ts_secondary; float last_weapon; float weapontime; +float weaponprevtime; float teamnagger; float hud_accuracy_hud; @@ -46,12 +49,19 @@ const float S_CTRL = 2; const float S_ALT = 4; float disable_menu_alphacheck; // 0 = enable alpha check, 1 = disable for entire hud, 2 = disable for one panel -float menu_fade_alpha; +float hud_fade_alpha; string hud_skin_path; var vector progressbar_color; +var float highlightedPanel_backup = -1; +var vector panel_pos_backup; +var vector panel_size_backup; + +var float highlightedPanel_copied = -1; //this is good only to know if there is something copied +var vector panel_size_copied; + var float active_panel; // this panel has recently referred the UpdateCvars macro var string panel_name; var float panel_enabled; @@ -85,7 +95,7 @@ var string picpath; // ---------------------- // MACRO HELL STARTS HERE // ---------------------- -// Little help for the poor people who have to make sense of this: Start from the bottom +// Little help for the poor people who have to make sense of this: Start from the bottom ;) #define HUD_Panel_GetProgressBarColor(item) \ switch(item) {\ @@ -104,18 +114,19 @@ if(!autocvar__hud_configure && panel_bg_str == "0") {\ panel_bg = "0";\ } else {\ if(panel_bg_str == "") {\ - panel_bg = autocvar_hud_panel_bg;\ - } else if(panel_bg_str == "0" && autocvar__hud_configure) {\ - panel_bg = autocvar_hud_panel_bg;\ - panel_bg_alpha_str = "0";\ - } else {\ - panel_bg = panel_bg_str;\ + panel_bg_str = autocvar_hud_panel_bg;\ }\ - panel_bg = strcat(hud_skin_path, "/", panel_bg);\ - if(precache_pic(panel_bg) == "") {\ - panel_bg = strcat(hud_skin_path, "/", "border");\ + if(panel_bg_str == "0" && !autocvar__hud_configure) {\ + panel_bg = "0";\ + } else {\ + if (panel_bg_str == "0" && autocvar__hud_configure)\ + panel_bg_alpha_str = "0";\ + panel_bg = strcat(hud_skin_path, "/", panel_bg_str);\ if(precache_pic(panel_bg) == "") {\ - panel_bg = strcat("gfx/hud/default/", "border");\ + panel_bg = strcat(hud_skin_path, "/", "border_default");\ + if(precache_pic(panel_bg) == "") {\ + panel_bg = strcat("gfx/hud/default/", "border_default");\ + }\ }\ }\ } @@ -162,7 +173,7 @@ if(autocvar__hud_configure && disable_menu_alphacheck == 2 && highlightedPanel = } if(autocvar__hud_configure && !panel_enabled) {\ panel_bg_alpha = 0.25;\ } if(!(disable_menu_alphacheck == 2 && highlightedPanel == active_panel)) {\ - panel_bg_alpha *= menu_fade_alpha;\ + panel_bg_alpha *= hud_fade_alpha;\ } // Get value for panel_fg_alpha. Also do various minalpha checks @@ -173,7 +184,7 @@ panel_fg_alpha = autocvar_hud_panel_fg_alpha;\ if(autocvar__hud_configure && !panel_enabled)\ panel_fg_alpha = 0.25;\ if(!(disable_menu_alphacheck == 2 && highlightedPanel == active_panel))\ - panel_fg_alpha *= menu_fade_alpha; + panel_fg_alpha *= hud_fade_alpha; // Get border. See comments above, it's similar. #define HUD_Panel_GetBorder()\ diff --git a/qcsrc/client/interpolate.qc b/qcsrc/client/interpolate.qc index 5593570508..5ee28b0fd2 100644 --- a/qcsrc/client/interpolate.qc +++ b/qcsrc/client/interpolate.qc @@ -24,7 +24,8 @@ void InterpolateOrigin_Note() self.iorigin2 = self.origin; if(self.iflags & IFLAG_AUTOANGLES) - self.angles = vectoangles(self.iorigin2 - self.iorigin1); + if(self.iorigin2 != self.iorigin1) + self.angles = vectoangles(self.iorigin2 - self.iorigin1); if(self.iflags & IFLAG_ANGLES) { diff --git a/qcsrc/client/laser.qc b/qcsrc/client/laser.qc index 23ced4b64a..6703b1b11f 100644 --- a/qcsrc/client/laser.qc +++ b/qcsrc/client/laser.qc @@ -35,11 +35,11 @@ void Draw_Laser() { if(self.alpha) { - Draw_CylindricLine(self.origin, trace_endpos, self.scale, "particles/laserbeam", 0, time * 3, self.colormod, self.alpha, DRAWFLAG_NORMAL); // TODO make a texture to make the laser look smoother + Draw_CylindricLine(self.origin, trace_endpos, self.scale, "particles/laserbeam", 0, time * 3, self.colormod, self.alpha, DRAWFLAG_NORMAL, view_origin); } else { - Draw_CylindricLine(self.origin, trace_endpos, self.scale, "particles/laserbeam", 0, time * 3, self.colormod, 0.5, DRAWFLAG_ADDITIVE); // TODO make a texture to make the laser look smoother + Draw_CylindricLine(self.origin, trace_endpos, self.scale, "particles/laserbeam", 0, time * 3, self.colormod, 0.5, DRAWFLAG_ADDITIVE, view_origin); } } if not(trace_dphitq3surfaceflags & (Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NOIMPACT)) diff --git a/qcsrc/client/miscfunctions.qc b/qcsrc/client/miscfunctions.qc index 0269874508..ed8f84fc28 100644 --- a/qcsrc/client/miscfunctions.qc +++ b/qcsrc/client/miscfunctions.qc @@ -8,7 +8,7 @@ void serverAnnouncer() // check for pending announcement, play it and remove it if(announce_snd != "") { - sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/", announce_snd, ".wav"), VOL_BASEVOICE, ATTN_NONE); + sound(world, CHAN_AUTO, strcat("announcer/", cvar_string("cl_announcer"), "/", announce_snd, ".wav"), VOL_BASEVOICE, ATTN_NONE); strunzone(announce_snd); announce_snd = ""; } @@ -22,7 +22,7 @@ void restartAnnouncer_Think() { if (!spectatee_status) //do cprint only for players centerprint("^1Begin!"); - sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/begin.wav"), VOL_BASEVOICE, ATTN_NONE); + sound(world, CHAN_AUTO, strcat("announcer/", cvar_string("cl_announcer"), "/begin.wav"), VOL_BASEVOICE, ATTN_NONE); //reset maptime announcers now as well announcer_5min = announcer_1min = FALSE; @@ -34,7 +34,7 @@ void restartAnnouncer_Think() { centerprint(strcat("^1Game starts in ", ftos(countdown_rounded), " seconds")); if(countdown_rounded <= 3 && countdown_rounded >= 1) { - sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/", ftos(countdown_rounded), ".wav"), VOL_BASEVOICE, ATTN_NONE); + sound(world, CHAN_AUTO, strcat("announcer/", cvar_string("cl_announcer"), "/", ftos(countdown_rounded), ".wav"), VOL_BASEVOICE, ATTN_NONE); } self.nextthink = getstatf(STAT_GAMESTARTTIME) - (countdown - 1); @@ -72,7 +72,7 @@ void maptimeAnnouncer() { if not (warmuplimit == -1 && warmup_stage) { announcer_5min = TRUE; //dprint("i will play the sound, I promise!\n"); - sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/5minutesremain.wav"), VOL_BASEVOICE, ATTN_NONE); + sound(world, CHAN_AUTO, strcat("announcer/", cvar_string("cl_announcer"), "/5minutesremain.wav"), VOL_BASEVOICE, ATTN_NONE); } } @@ -87,7 +87,7 @@ void maptimeAnnouncer() { //if we're in warmup mode, check whether there's a warmup timelimit if not (warmuplimit == -1 && warmup_stage) { announcer_1min = TRUE; - sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/1minuteremains.wav"), VOL_BASEVOICE, ATTN_NONE); + sound(world, CHAN_AUTO, strcat("announcer/", cvar_string("cl_announcer"), "/1minuteremains.wav"), VOL_BASEVOICE, ATTN_NONE); } } } @@ -324,19 +324,6 @@ vector HUD_GetFontsize(string cvarname) return v; } -float HUD_GetWidth(float teamcolumnwidth) -{ - float f; - f = cvar("hud_width"); - if(f == 0) - f = 640; - if(f < 320) - f = 320; - if(f > vid_conwidth - 2 * teamcolumnwidth) - f = vid_conwidth - 2 * teamcolumnwidth; - return f; -} - float PreviewExists(string name) { float f; diff --git a/qcsrc/client/particles.qc b/qcsrc/client/particles.qc index e0bbeb81bf..d4a95b7754 100644 --- a/qcsrc/client/particles.qc +++ b/qcsrc/client/particles.qc @@ -58,7 +58,7 @@ void Draw_PointParticles() if(self.noise != "") { self.origin = p; - sound(self, CHAN_AUTO, self.noise, VOL_BASE * self.volume, self.atten); + sound(self, CHAN_TRIGGER, self.noise, VOL_BASE * self.volume, self.atten); } self.just_toggled = 0; } diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index 4569e497ce..1334d7d3c7 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -22,6 +22,7 @@ autocvars.qh interpolate.qh teamradar.qh hud.qh +scoreboard.qh waypointsprites.qh movetypes.qh prandom.qh diff --git a/qcsrc/client/projectile.qc b/qcsrc/client/projectile.qc index 407b86c746..9a773379b5 100644 --- a/qcsrc/client/projectile.qc +++ b/qcsrc/client/projectile.qc @@ -72,7 +72,8 @@ void Projectile_Draw() else Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy); if(!(self.move_flags & FL_ONGROUND)) - self.angles = vectoangles(self.velocity); + if(self.velocity != '0 0 0') + self.angles = vectoangles(self.velocity); } else { @@ -318,12 +319,12 @@ void Ent_Projectile() self.maxs = '3 3 3'; break; case PROJECTILE_GRENADE: - self.mins = '0 0 -3'; - self.maxs = '0 0 -3'; + self.mins = '-3 -3 -3'; + self.maxs = '3 3 3'; break; case PROJECTILE_GRENADE_BOUNCING: - self.mins = '0 0 -3'; - self.maxs = '0 0 -3'; + self.mins = '-3 -3 -3'; + self.maxs = '3 3 3'; self.move_movetype = MOVETYPE_BOUNCE; self.move_touch = SUB_Null; self.move_bounce_factor = g_balance_grenadelauncher_secondary_bouncefactor; diff --git a/qcsrc/client/scoreboard.qc b/qcsrc/client/scoreboard.qc index 29fb20642a..76b19a54c5 100644 --- a/qcsrc/client/scoreboard.qc +++ b/qcsrc/client/scoreboard.qc @@ -595,8 +595,8 @@ string HUD_FixScoreboardColumnWidth(float i, string str) for(j = 0; j < hud_num_fields; ++j) if(j != i) if (hud_field[i] != SP_SEPARATOR) - namesize -= hud_size[j] + 1; - namesize += 1; + namesize -= hud_size[j] + hud_fontsize_x; + namesize += hud_fontsize_x; hud_size[i] = namesize; if (hud_fixscoreboardcolumnwidth_iconlen != 0) @@ -760,7 +760,10 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz tmp_y = 1.25 * hud_fontsize_y; // rounded header - drawpic(pos, "gfx/scoreboard/scoreboard_tableheader", tmp, (rgb * autocvar_hud_color_bg_team) + '0.5 0.5 0.5', scoreboard_alpha_bg, DRAWFLAG_NORMAL); + if (teamplay) + drawpic(pos, "gfx/scoreboard/scoreboard_tableheader", tmp, (rgb * autocvar_scoreboard_color_bg_team) + '0.5 0.5 0.5', scoreboard_alpha_bg, DRAWFLAG_NORMAL); + else + drawpic(pos, "gfx/scoreboard/scoreboard_tableheader", tmp, rgb + '0.5 0.5 0.5', scoreboard_alpha_bg, DRAWFLAG_NORMAL); // table border tmp_y += hud_border_thickness; @@ -776,7 +779,10 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz // table background tmp_y = body_table_height; - drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_hud_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL); + if (teamplay) + drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL); + else + drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL); // anyway, apply some color //drawfill(pos, tmp + '2 0 0', rgb, 0.1, DRAWFLAG_NORMAL); @@ -877,7 +883,7 @@ float HUD_WouldDrawScoreboard() { return 1; else if (intermission == 1) return 1; - else if (intermission == 2) + else if (intermission == 2 && scoreboard_showscores) return 1; else if (getstati(STAT_HEALTH) <= 0 && cvar("cl_deathscoreboard")) return 1; @@ -907,12 +913,15 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size) } drawstring(pos, strcat("Accuracy stats (average ", ftos(average_accuracy), "%)"), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL); - pos_y += 18; + pos_y += 1.25 * hud_fontsize_y; vector tmp; tmp_x = sbwidth; tmp_y = height * rows; - drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_hud_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL); + if (teamplay) + drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL); + else + drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL); drawborderlines(hud_accuracy_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL); // column highlighting @@ -1006,6 +1015,8 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size) pos_x -= sbwidth/weapon_cnt / 2; pos_x -= sbwidth; pos_y += height; + + pos_y += 1.25 * hud_fontsize_y; return pos; } @@ -1013,9 +1024,9 @@ vector HUD_DrawScoreboardRankings(vector pos, entity pl, vector rgb, vector bg_ { float i; RANKINGS_RECEIVED_CNT = 0; - for (i=RANKINGS_CNT-1; i>=0; --i) - if (grecordtime[i]) - RANKINGS_RECEIVED_CNT = RANKINGS_RECEIVED_CNT + 1; + for (i=RANKINGS_CNT-1; i>=0; --i) + if (grecordtime[i]) + ++RANKINGS_RECEIVED_CNT; if (RANKINGS_RECEIVED_CNT == 0) return pos; @@ -1023,9 +1034,9 @@ vector HUD_DrawScoreboardRankings(vector pos, entity pl, vector rgb, vector bg_ float is_spec; is_spec = (GetPlayerColor(pl.sv_entnum) == COLOR_SPECTATOR); vector hl_rgb; - hl_rgb_x = cvar("scoreboard_color_bg_r") + 0.5; - hl_rgb_y = cvar("scoreboard_color_bg_g") + 0.5; - hl_rgb_z = cvar("scoreboard_color_bg_b") + 0.5; + hl_rgb_x = cvar("scoreboard_color_bg_r") + 0.5; + hl_rgb_y = cvar("scoreboard_color_bg_g") + 0.5; + hl_rgb_z = cvar("scoreboard_color_bg_b") + 0.5; pos_y += hud_fontsize_y; drawstring(pos, strcat("Rankings"), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL); @@ -1034,7 +1045,10 @@ vector HUD_DrawScoreboardRankings(vector pos, entity pl, vector rgb, vector bg_ tmp_x = sbwidth; tmp_y = hud_fontsize_y * RANKINGS_RECEIVED_CNT; - drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_hud_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL); + if (teamplay) + drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL); + else + drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL); drawborderlines(hud_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL); // row highlighting @@ -1054,13 +1068,12 @@ vector HUD_DrawScoreboardRankings(vector pos, entity pl, vector rgb, vector bg_ drawstring(pos, p, hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL); drawstring(pos + '3 0 0' * hud_fontsize_x, TIME_ENCODED_TOSTRING(t), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL); drawcolorcodedstring(pos + '8 0 0' * hud_fontsize_x, n, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL); - pos += '0 1 0' * hud_fontsize_y; + pos_y += 1.25 * hud_fontsize_y; } return pos; } -float scoreboard_fade_alpha; float hud_woulddrawscoreboard_prev; float hud_woulddrawscoreboard_change; // "time" at which HUD_WouldDrawScoreboard() changed void HUD_DrawScoreboard() @@ -1102,13 +1115,11 @@ void HUD_DrawScoreboard() vector rgb, pos, tmp; entity pl, tm; - sbwidth = HUD_GetWidth(6.5 * hud_fontsize_y); - - xmin = 0.5 * (vid_conwidth - sbwidth); - ymin = SCOREBOARD_OFFSET; + xmin = cvar("scoreboard_offset_left") * vid_conwidth; + ymin = cvar("con_notify") * cvar("con_notifysize"); - xmax = vid_conwidth - xmin; - ymax = vid_conheight - 0.2*vid_conheight; + sbwidth = xmax = vid_conwidth - xmin - cvar("scoreboard_offset_right") * vid_conwidth; + ymax = vid_conheight - ymin; // Initializes position pos_x = xmin; @@ -1117,10 +1128,12 @@ void HUD_DrawScoreboard() // Heading drawfont = hud_bigfont; - drawstringcenter('0 1 0' * ymin, "Scoreboard", '24 24 0', '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL); + drawstring(pos, "Scoreboard", '24 24 0', '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL); + + centerprint_start_x = vid_conwidth - 0.5 * (pos_x + stringwidth("Scoreboard", FALSE, '24 24 0')); + centerprint_start_y = pos_y; - pos_y += 24 + 4; - pos_y += hud_fontsize_y; + pos_y += 24; drawfont = hud_font; @@ -1136,10 +1149,10 @@ void HUD_DrawScoreboard() continue; rgb = GetTeamRGB(tm.team); - drawstring(pos - '9.5 0 0' * hud_fontsize_y + '0 1 0' * hud_fontsize_y, ftos(tm.(teamscores[ts_primary])), '1 1 0' * hud_fontsize_y * 1.5, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL); + drawstring(pos - '2 0 0' * hud_fontsize_x + '0 1 0' * hud_fontsize_y, ftos(tm.(teamscores[ts_primary])), '1 1 0' * hud_fontsize_y * 1.5, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL); if(ts_primary != ts_secondary) - drawstring(pos - '7.5 0 0' * hud_fontsize_y + '0 2.5 0' * hud_fontsize_y, ftos(tm.(teamscores[ts_secondary])), '1 1 0' * hud_fontsize_y * 1, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL); + drawstring(pos - '2 0 0' * hud_fontsize_x + '0 2.5 0' * hud_fontsize_y, ftos(tm.(teamscores[ts_secondary])), '1 1 0' * hud_fontsize_y * 1, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL); pos = HUD_Scoreboard_MakeTable(pos, tm, rgb, bg_size); } @@ -1177,23 +1190,24 @@ void HUD_DrawScoreboard() pos = HUD_DrawScoreboardAccuracyStats(pos, rgb, bg_size); } - tmp = pos + '0 1.5 0' * hud_fontsize_y; - pos_y += 3 * hud_fontsize_y; - // List spectators float specs; specs = 0; + tmp = pos; for(pl = players.sort_next; pl; pl = pl.sort_next) { if(pl.team != COLOR_SPECTATOR) continue; - HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localentnum - 1), specs); pos_y += 1.25 * hud_fontsize_y; + HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localentnum - 1), specs); ++specs; } if(specs) + { drawstring(tmp, "Spectators", hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL); + pos_y += 1.25 * hud_fontsize_y; + } // Print info string string str; diff --git a/qcsrc/client/scoreboard.qh b/qcsrc/client/scoreboard.qh new file mode 100644 index 0000000000..b39b48e53b --- /dev/null +++ b/qcsrc/client/scoreboard.qh @@ -0,0 +1,2 @@ +float HUD_WouldDrawScoreboard(void); +float scoreboard_fade_alpha; diff --git a/qcsrc/client/teamradar.qc b/qcsrc/client/teamradar.qc index dbb884168d..55b5650747 100644 --- a/qcsrc/client/teamradar.qc +++ b/qcsrc/client/teamradar.qc @@ -106,17 +106,17 @@ void(vector coord3d, vector pangles, vector rgb) draw_teamradar_player = rgb2 = '1 1 1'; R_BeginPolygon("", 0); - R_PolygonVertex(coord+v_forward*3, '0 0 0', rgb2, autocvar_hud_panel_fg_alpha); - R_PolygonVertex(coord+v_right*4-v_forward*2.5, '0 1 0', rgb2, autocvar_hud_panel_fg_alpha); - R_PolygonVertex(coord-v_forward*2, '1 0 0', rgb2, autocvar_hud_panel_fg_alpha); - R_PolygonVertex(coord-v_right*4-v_forward*2.5, '1 1 0', rgb2, autocvar_hud_panel_fg_alpha); + R_PolygonVertex(coord+v_forward*3, '0 0 0', rgb2, panel_fg_alpha); + R_PolygonVertex(coord+v_right*4-v_forward*2.5, '0 1 0', rgb2, panel_fg_alpha); + R_PolygonVertex(coord-v_forward*2, '1 0 0', rgb2, panel_fg_alpha); + R_PolygonVertex(coord-v_right*4-v_forward*2.5, '1 1 0', rgb2, panel_fg_alpha); R_EndPolygon(); R_BeginPolygon("", 0); - R_PolygonVertex(coord+v_forward*2, '0 0 0', rgb, autocvar_hud_panel_fg_alpha); - R_PolygonVertex(coord+v_right*3-v_forward*2, '0 1 0', rgb, autocvar_hud_panel_fg_alpha); - R_PolygonVertex(coord-v_forward, '1 0 0', rgb, autocvar_hud_panel_fg_alpha); - R_PolygonVertex(coord-v_right*3-v_forward*2, '1 1 0', rgb, autocvar_hud_panel_fg_alpha); + R_PolygonVertex(coord+v_forward*2, '0 0 0', rgb, panel_fg_alpha); + R_PolygonVertex(coord+v_right*3-v_forward*2, '0 1 0', rgb, panel_fg_alpha); + R_PolygonVertex(coord-v_forward, '1 0 0', rgb, panel_fg_alpha); + R_PolygonVertex(coord-v_right*3-v_forward*2, '1 1 0', rgb, panel_fg_alpha); R_EndPolygon(); }; @@ -161,10 +161,10 @@ void draw_teamradar_link(vector start, vector end, float colors) c1 = colormapPaletteColor((colors & 0xF0) / 0x10, FALSE); R_BeginPolygon("", 0); - R_PolygonVertex(start - norm, '0 0 0', c0, autocvar_hud_panel_fg_alpha); - R_PolygonVertex(start + norm, '0 1 0', c0, autocvar_hud_panel_fg_alpha); - R_PolygonVertex(end + norm, '1 1 0', c1, autocvar_hud_panel_fg_alpha); - R_PolygonVertex(end - norm, '1 0 0', c1, autocvar_hud_panel_fg_alpha); + R_PolygonVertex(start - norm, '0 0 0', c0, panel_fg_alpha); + R_PolygonVertex(start + norm, '0 1 0', c0, panel_fg_alpha); + R_PolygonVertex(end + norm, '1 1 0', c1, panel_fg_alpha); + R_PolygonVertex(end - norm, '1 0 0', c1, panel_fg_alpha); R_EndPolygon(); } @@ -179,14 +179,14 @@ void teamradar_loadcvars() { v_flipped = cvar("v_flipped"); hud_panel_radar_scale = cvar("hud_panel_radar_scale"); - hud_panel_radar_foreground_alpha = cvar("hud_panel_radar_foreground_alpha") * autocvar_hud_panel_fg_alpha; + hud_panel_radar_foreground_alpha = cvar("hud_panel_radar_foreground_alpha") * panel_fg_alpha; hud_panel_radar_rotation = cvar("hud_panel_radar_rotation"); hud_panel_radar_zoommode = cvar("hud_panel_radar_zoommode"); // others default to 0 // match this to defaultXonotic.cfg! if(!hud_panel_radar_scale) hud_panel_radar_scale = 4096; - if(!hud_panel_radar_foreground_alpha) hud_panel_radar_foreground_alpha = 0.8 * autocvar_hud_panel_fg_alpha; + if(!hud_panel_radar_foreground_alpha) hud_panel_radar_foreground_alpha = 0.8 * panel_fg_alpha; if(!hud_panel_radar_size_x) hud_panel_radar_size_x = 128; if(!hud_panel_radar_size_y) hud_panel_radar_size_y = hud_panel_radar_size_x; diff --git a/qcsrc/client/waypointsprites.qc b/qcsrc/client/waypointsprites.qc index d7b9ee9d01..a001732da2 100644 --- a/qcsrc/client/waypointsprites.qc +++ b/qcsrc/client/waypointsprites.qc @@ -436,11 +436,7 @@ void WaypointSprite_Load() for(i = 0; i < n; ++i) { s = search_getfilename(dh, i); - if(substring(s, 0, 15) != "models/sprites/") - continue; - if(substring(s, strlen(s) - 4, 4) != ".tga") - continue; - s = substring(s, 15, strlen(s) - 19); + s = substring(s, 15, strlen(s) - 15 - 4); // strip models/sprites/ and .tga o = strstrofs(s, "_frame", 0); sname = strcat("/spriteframes/", substring(s, 0, o)); diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 53f37bcdd2..5ebeb54659 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -398,7 +398,7 @@ float CHAN_AUTO = 0; // on world: announcers, ... INFO // on players: item pickup ITEMS // on entities: UNUSED - // on csqc: UNUSED + // on csqc: announcers INFO float CHAN_WEAPON = 1; // Weapon fire // on world: UNUSED // on players: weapon firing WEAPONS @@ -413,7 +413,7 @@ float CHAN_TRIGGER = 3; // Triggers/Items // on world: UNUSED // on players: item pickup ITEMS // on entities: platforms moving etc. ITEMS - // on csqc: UNUSED + // on csqc: platforms moving etc. ITEMS float CHAN_PROJECTILE = 4; // Projectiles // on world: UNUSED // on players: projectiles hitting player SHOTS diff --git a/qcsrc/common/mapinfo.qc b/qcsrc/common/mapinfo.qc index 1fd2cf8093..10b5943204 100644 --- a/qcsrc/common/mapinfo.qc +++ b/qcsrc/common/mapinfo.qc @@ -720,7 +720,7 @@ float MapInfo_Get_ByName(string pFilename, float pAllowGenerate, float pGametype for(i = 1; i <= MapInfo_Map_supportedGametypes; i *= 2) if(MapInfo_Map_supportedGametypes & i) - fputs(fh, sprintf("type %s %s\n", i, MapInfo_GetDefault(i))); + fputs(fh, sprintf("type %s %s\n", MapInfo_Type_ToString(i), MapInfo_GetDefault(i))); fh2 = fopen(strcat("scripts/", pFilename, ".arena"), FILE_READ); if(fh2 >= 0) diff --git a/qcsrc/common/util.qc b/qcsrc/common/util.qc index 72af701119..f33512f235 100644 --- a/qcsrc/common/util.qc +++ b/qcsrc/common/util.qc @@ -1913,3 +1913,9 @@ float get_model_parameters(string m, float sk) return 1; } + +vector vec2(vector v) +{ + v_z = 0; + return v; +} diff --git a/qcsrc/common/util.qh b/qcsrc/common/util.qh index f2c2e6702a..767092cc75 100644 --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@ -236,3 +236,5 @@ switch(id) { \ case HUD_PANEL_CHAT: panel_name = HUD_PANELNAME_CHAT; break; \ }\ HUD_Panel_GetName_Part2(id) + +vector vec2(vector v); diff --git a/qcsrc/menu/classes.c b/qcsrc/menu/classes.c index c0568b1e56..9ebcbb8f5b 100644 --- a/qcsrc/menu/classes.c +++ b/qcsrc/menu/classes.c @@ -101,3 +101,4 @@ #include "xonotic/dialog_hudpanel_engineinfo.c" #include "xonotic/dialog_hudpanel_infomessages.c" #include "xonotic/dialog_hudpanel_weapons.c" +#include "xonotic/slider_picmip.c" diff --git a/qcsrc/menu/draw.qc b/qcsrc/menu/draw.qc index cec73d6c0a..a33cac9163 100644 --- a/qcsrc/menu/draw.qc +++ b/qcsrc/menu/draw.qc @@ -69,6 +69,8 @@ void draw_PreloadPicture(string pic) void draw_Picture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha) { + if(theSize_x == 0 || theSize_y <= 0) // no default sizing please + return; pic = draw_UseSkinFor(pic); drawpic(boxToGlobal(theOrigin, draw_shift, draw_scale), pic, boxToGlobalSize(theSize, draw_scale), theColor, theAlpha * draw_alpha, 0); } @@ -174,11 +176,40 @@ void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector the theAlpha *= draw_alpha; width = eX * theSize_x; height = eY * theSize_y; - if(theSize_x <= theBorderSize_x * 2) + // zero size? bail out, we cannot handle this + if(theSize_x <= 0 || theSize_y <= 0) + return; + if(theBorderSize_x <= 0) // no x border + { + if(theBorderSize_y <= 0) + { + drawsubpic(theOrigin, width + height, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0); + } + else if(theSize_y <= theBorderSize_y * 2) + { + // not high enough... draw just top and bottom then + bH = eY * (0.25 * theSize_y / (theBorderSize_y * 2)); + drawsubpic(theOrigin, width + height * 0.5, pic, '0.25 0 0', '0.5 0 0' + bH, theColor, theAlpha, 0); + drawsubpic(theOrigin + height * 0.5, width + height * 0.5, pic, '0.25 0 0' + eY - bH, '0.5 0 0' + bH, theColor, theAlpha, 0); + } + else + { + dY = theBorderSize_y * eY; + drawsubpic(theOrigin, width + dY, pic, '0.25 0 0', '0.5 0.25 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + dY, width + height - 2 * dY, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + height - dY, width + dY, pic, '0.25 0.75 0', '0.5 0.25 0', theColor, theAlpha, 0); + } + } + else if(theSize_x <= theBorderSize_x * 2) { // not wide enough... draw just left and right then bW = eX * (0.25 * theSize_x / (theBorderSize_x * 2)); - if(theSize_y <= theBorderSize_y * 2) + if(theBorderSize_y <= 0) + { + drawsubpic(theOrigin, width * 0.5 + height, pic, '0 0.25 0', '0 0.5 0' + bW, theColor, theAlpha, 0); + drawsubpic(theOrigin + width * 0.5, width * 0.5 + height, pic, '0 0.25 0' + eX - bW, '0 0.5 0' + bW, theColor, theAlpha, 0); + } + else if(theSize_y <= theBorderSize_y * 2) { // not high enough... draw just corners bH = eY * (0.25 * theSize_y / (theBorderSize_y * 2)); @@ -189,7 +220,7 @@ void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector the } else { - dY = theBorderSize_x * eY; + dY = theBorderSize_y * eY; drawsubpic(theOrigin, width * 0.5 + dY, pic, '0 0 0', '0 0.25 0' + bW, theColor, theAlpha, 0); drawsubpic(theOrigin + width * 0.5, width * 0.5 + dY, pic, '0 0 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0); drawsubpic(theOrigin + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0', '0 0.5 0' + bW, theColor, theAlpha, 0); @@ -200,7 +231,14 @@ void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector the } else { - if(theSize_y <= theBorderSize_y * 2) + if(theBorderSize_y <= 0) + { + dX = theBorderSize_x * eX; + drawsubpic(theOrigin, dX + height, pic, '0 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + dX, width - 2 * dX + height, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0); + drawsubpic(theOrigin + width - dX, dX + height, pic, '0.75 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0); + } + else if(theSize_y <= theBorderSize_y * 2) { // not high enough... draw just top and bottom then bH = eY * (0.25 * theSize_y / (theBorderSize_y * 2)); @@ -215,7 +253,7 @@ void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector the else { dX = theBorderSize_x * eX; - dY = theBorderSize_x * eY; + dY = theBorderSize_y * eY; drawsubpic(theOrigin, dX + dY, pic, '0 0 0', '0.25 0.25 0', theColor, theAlpha, 0); drawsubpic(theOrigin + dX, width - 2 * dX + dY, pic, '0.25 0 0', '0.5 0.25 0', theColor, theAlpha, 0); drawsubpic(theOrigin + width - dX, dX + dY, pic, '0.75 0 0', '0.25 0.25 0', theColor, theAlpha, 0); diff --git a/qcsrc/menu/item/slider.c b/qcsrc/menu/item/slider.c index 1f01cb4e2e..c8bab9bf80 100644 --- a/qcsrc/menu/item/slider.c +++ b/qcsrc/menu/item/slider.c @@ -104,7 +104,7 @@ float Slider_keyDown(entity me, float key, float ascii, float shift) if(me.disabled) return 0; inRange = (almost_in_bounds(me.valueMin, me.value, me.valueMax)); - if(key == K_LEFTARROW || key == K_KP_LEFTARROW) + if(key == K_LEFTARROW || key == K_KP_LEFTARROW || key == K_MWHEELUP) { if(inRange) me.setValue(me, median(me.valueMin, me.value - me.valueKeyStep, me.valueMax)); @@ -112,7 +112,7 @@ float Slider_keyDown(entity me, float key, float ascii, float shift) me.setValue(me, me.valueMax); return 1; } - if(key == K_RIGHTARROW || key == K_KP_RIGHTARROW) + if(key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_MWHEELDOWN) { if(inRange) me.setValue(me, median(me.valueMin, me.value + me.valueKeyStep, me.valueMax)); diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.c b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.c index a32099d9d8..538723bce1 100644 --- a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.c +++ b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.c @@ -4,7 +4,7 @@ CLASS(XonoticHUDWeaponsDialog) EXTENDS(XonoticRootDialog) ATTRIB(XonoticHUDWeaponsDialog, title, string, "Weapons Panel") ATTRIB(XonoticHUDWeaponsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT) ATTRIB(XonoticHUDWeaponsDialog, intendedWidth, float, 0.4) - ATTRIB(XonoticHUDWeaponsDialog, rows, float, 15) + ATTRIB(XonoticHUDWeaponsDialog, rows, float, 17) ATTRIB(XonoticHUDWeaponsDialog, columns, float, 4) ATTRIB(XonoticHUDWeaponsDialog, name, string, "HUDweapons") ENDCLASS(XonoticHUDWeaponsDialog) @@ -71,6 +71,23 @@ void XonoticHUDWeaponsDialog_fill(entity me) for(i = 0; i <= 10; ++i) e.addValue(e, strzone(ftos_decimals(i - 5, 0)), strzone(ftos(i - 5))); e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "Fade out after:")); + me.TD(me, 1, 2.6, e = makeXonoticTextSlider(strzone(strcat("hud_panel_", panelname, "_timeout")))); + e.addValue(e, "Never", "0"); + for(i = 1; i <= 10; ++i) + e.addValue(e, strzone(strcat(ftos_decimals(i, 0), "s")), strzone(ftos(i))); + e.configureXonoticTextSliderValues(e); + me.TR(me); + me.TDempty(me, 0.2); + me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, "Fade effect:")); + me.TD(me, 1, 0.8, e = makeXonoticRadioButton(3, "hud_panel_weapons_timeout_effect", "0", "None")); + setDependentStringNotEqual(e, strzone(strcat("hud_panel_", panelname, "_timeout")), "0"); + me.TD(me, 1, 0.8, e = makeXonoticRadioButton(3, "hud_panel_weapons_timeout_effect", "1", "Slide")); + setDependentStringNotEqual(e, strzone(strcat("hud_panel_", panelname, "_timeout")), "0"); + me.TD(me, 1, 0.8, e = makeXonoticRadioButton(3, "hud_panel_weapons_timeout_effect", "2", "Alpha")); + setDependentStringNotEqual(e, strzone(strcat("hud_panel_", panelname, "_timeout")), "0"); me.TR(me); me.TD(me, 1, 2, e = makeXonoticTextLabel(0, "Weapon icons:")); me.TR(me); diff --git a/qcsrc/menu/xonotic/dialog_hudsetup_exit.c b/qcsrc/menu/xonotic/dialog_hudsetup_exit.c index d3a21c6bf6..3f8bcebd77 100644 --- a/qcsrc/menu/xonotic/dialog_hudsetup_exit.c +++ b/qcsrc/menu/xonotic/dialog_hudsetup_exit.c @@ -69,7 +69,7 @@ void XonoticHUDExitDialog_fill(entity me) me.TD(me, 1, 2.6, e = makeXonoticTextSlider("hud_dock")); e.addValue(e, "Disable", "0"); e.addValue(e, "Small", "dock_small"); - e.addValue(e, "Medium", "dock"); + e.addValue(e, "Medium", "dock_medium"); e.addValue(e, "Large", "dock_large"); e.configureXonoticTextSliderValues(e); me.TR(me); diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c index 05ed89887d..bd54aa2194 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c @@ -163,6 +163,5 @@ void XonoticMapInfoDialog_fill(entity me) me.TD(me, 1, me.columns - 5.5, me.startButton = e = makeXonoticButton("Play", '0 0 0')); me.startButton.onClick = MapList_LoadMap; me.startButton.onClickEntity = NULL; // filled later - me.TDempty(me, 0.5); } #endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_playersetup.c b/qcsrc/menu/xonotic/dialog_multiplayer_playersetup.c index 8c75c1f469..754da256a9 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_playersetup.c +++ b/qcsrc/menu/xonotic/dialog_multiplayer_playersetup.c @@ -151,7 +151,7 @@ void XonoticPlayerSettingsTab_fill(entity me) me.TD(me, 1, 2/3, e = makeXonoticRadioButton(1, "crosshair_hittest", "1.25", "Enemies")); me.TR(me); me.TDempty(me, 0.4); - me.TD(me, 1, 2.2, e = makeXonoticButton("Waypoints Setup", '0 0 0')); + me.TD(me, 1, 2.2, e = makeXonoticButton("Waypoints setup...", '0 0 0')); e.onClick = DialogOpenButton_Click; e.onClickEntity = main.waypointDialog; me.TDempty(me, 0.5); @@ -178,7 +178,6 @@ void XonoticPlayerSettingsTab_fill(entity me) e.addValue(e, "Lots", "0"); e.configureXonoticTextSliderValues(e); setDependent(e, "cl_gentle", 0, 0); - me.TR(me); me.gotoRC(me, me.rows - 1, 0); me.TD(me, 1, me.columns, makeXonoticCommandButton("Apply immediately", '0 0 0', "color -1 -1;name \"$_cl_name\";cl_cmd sendcvar cl_weaponpriority;sendcvar cl_zoomfactor;sendcvar cl_zoomspeed;sendcvar cl_autoswitch;sendcvar cl_shownames;sendcvar cl_forceplayermodelsfromxonotic;sendcvar cl_forceplayermodels;playermodel $_cl_playermodel;playerskin $_cl_playerskin", COMMANDBUTTON_APPLY)); diff --git a/qcsrc/menu/xonotic/dialog_settings_audio.c b/qcsrc/menu/xonotic/dialog_settings_audio.c index 7d1f17f0f2..ddde45d2b8 100644 --- a/qcsrc/menu/xonotic/dialog_settings_audio.c +++ b/qcsrc/menu/xonotic/dialog_settings_audio.c @@ -51,7 +51,7 @@ void XonoticAudioSettingsTab_fill(entity me) me.TR(me); me.TDempty(me, 0.2); s = makeXonoticDecibelsSlider(-20, 0, 0.5, "snd_entchannel3volume"); - makeMulti(s, "snd_playerchannel0volume snd_playerchannel3volume"); + makeMulti(s, "snd_playerchannel0volume snd_playerchannel3volume snd_csqcchannel3volume"); me.TD(me, 1, 0.8, e = makeXonoticSliderCheckBox(-1000000, 1, s, "Items:")); me.TD(me, 1, 2, s); setDependentStringNotEqual(e, "volume", "0"); @@ -155,7 +155,8 @@ void XonoticAudioSettingsTab_fill(entity me) if(sl.value != e.savedValue) e.savedValue = 0.65; // default me.TR(me); - me.TD(me, 1, 3, e = makeXonoticTextLabel(0.1, "Frequency:")); + me.TDempty(me, 0.2); + me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, "Frequency:")); me.TD(me, 1, 2, sl); me.TR(me); me.TR(me); diff --git a/qcsrc/menu/xonotic/dialog_settings_effects.c b/qcsrc/menu/xonotic/dialog_settings_effects.c index 6cb0715360..d5fbd82fd9 100644 --- a/qcsrc/menu/xonotic/dialog_settings_effects.c +++ b/qcsrc/menu/xonotic/dialog_settings_effects.c @@ -36,9 +36,9 @@ float updateCompression() float have_dds, have_jpg, have_tga; if((have_dds = (fh = fopen("dds/particles/particlefont.dds", FILE_READ) >= 0))) fclose(fh); - if((have_jpg = (fh = fopen("jpg/particles/particlefont.jpg", FILE_READ) >= 0))) + if((have_jpg = (fh = fopen("particles/particlefont.jpg", FILE_READ) >= 0))) fclose(fh); - if((have_tga = (fh = fopen("tga/particles/particlefont.tga", FILE_READ) >= 0))) + if((have_tga = (fh = fopen("particles/particlefont.tga", FILE_READ) >= 0))) fclose(fh); if(have_dds && (have_jpg || have_tga)) { @@ -96,7 +96,7 @@ void XonoticEffectsSettingsTab_fill(entity me) me.TR(me); me.TR(me); me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Texture resolution:")); - me.TD(me, 1, 2, e = makeXonoticTextSlider("gl_picmip")); + me.TD(me, 1, 2, e = makeXonoticPicmipSlider()); if(cvar("developer")) e.addValue(e, "Leet", "1337"); e.addValue(e, "Lowest", "2"); diff --git a/qcsrc/menu/xonotic/dialog_settings_misc.c b/qcsrc/menu/xonotic/dialog_settings_misc.c index 2dcf83f1f0..89c8471ca7 100644 --- a/qcsrc/menu/xonotic/dialog_settings_misc.c +++ b/qcsrc/menu/xonotic/dialog_settings_misc.c @@ -66,13 +66,12 @@ void XonoticMiscSettingsTab_fill(entity me) me.TR(me); me.TR(me); me.TDempty(me, 0.2); - me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "host_sleep", "Minimize input latency")); + me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_maxfps_alwayssleep", "Minimize input latency")); me.TR(me); me.TR(me); me.TDempty(me, 0.5); me.TD(me, 1, 2, e = makeXonoticButton("Advanced settings...", '0 0 0')); e.onClick = DialogOpenButton_Click; e.onClickEntity = main.cvarsDialog; - me.TDempty(me, 0.5); } #endif diff --git a/qcsrc/menu/xonotic/slider_picmip.c b/qcsrc/menu/xonotic/slider_picmip.c new file mode 100644 index 0000000000..e906242fe4 --- /dev/null +++ b/qcsrc/menu/xonotic/slider_picmip.c @@ -0,0 +1,49 @@ +#ifdef INTERFACE +CLASS(XonoticPicmipSlider) EXTENDS(XonoticTextSlider) + METHOD(XonoticPicmipSlider, configureXonoticPicmipSlider, void(entity)) + METHOD(XonoticPicmipSlider, draw, void(entity)) + METHOD(XonoticPicmipSlider, autofix, void(entity)) +ENDCLASS(XonoticPicmipSlider) +entity makeXonoticPicmipSlider(); // note: you still need to call addValue and configureXonoticTextSliderValues! +#endif + +#ifdef IMPLEMENTATION +entity makeXonoticPicmipSlider() +{ + entity me; + me = spawnXonoticPicmipSlider(); + me.configureXonoticPicmipSlider(me); + return me; +} +void XonoticPicmipSlider_configureXonoticPicmipSlider(entity me) +{ + me.configureXonoticTextSlider(me, "gl_picmip"); + me.autofix(me); +} +float texmemsize() +{ + return + ( + 2500 * pow(0.5, max(0, cvar("gl_picmip") + cvar("gl_picmip_other"))) + + 1500 * pow(0.5, max(0, cvar("gl_picmip") + cvar("gl_picmip_world"))) + ) * ((cvar("r_texture_dds_load") || cvar("gl_texturecompression")) ? 0.4 : 1.0); // TC: normalmaps 50%, other 25%, few incompressible, guessing 40% as conservative average +} +void XonoticPicmipSlider_autofix(entity me) +{ + float max_hard, max_soft; + max_hard = cvar("sys_memsize_virtual"); + max_soft = cvar("sys_memsize_physical"); + if(max_hard > 0) + { + while(me.value > 0 && texmemsize() > max_hard) + me.setValue(me, me.value - 1); + } + // TODO also check the soft limit! + // TODO better handling than clamping the slider! +} +void XonoticPicmipSlider_draw(entity me) +{ + me.autofix(me); + SUPER(XonoticPicmipSlider).draw(me); +} +#endif diff --git a/qcsrc/menu/xonotic/textslider.c b/qcsrc/menu/xonotic/textslider.c index 69270a67ac..3fee2bf558 100644 --- a/qcsrc/menu/xonotic/textslider.c +++ b/qcsrc/menu/xonotic/textslider.c @@ -6,13 +6,13 @@ CLASS(XonoticTextSlider) EXTENDS(TextSlider) ATTRIB(XonoticTextSlider, fontSize, float, SKINFONTSIZE_NORMAL) ATTRIB(XonoticTextSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT) ATTRIB(XonoticTextSlider, image, string, SKINGFX_SLIDER) - ATTRIB(XonoticSlider, tolerance, vector, SKINTOLERANCE_SLIDER) + ATTRIB(XonoticTextSlider, tolerance, vector, SKINTOLERANCE_SLIDER) ATTRIB(XonoticTextSlider, align, float, 0.5) - ATTRIB(XonoticSlider, color, vector, SKINCOLOR_SLIDER_N) - ATTRIB(XonoticSlider, colorC, vector, SKINCOLOR_SLIDER_C) - ATTRIB(XonoticSlider, colorF, vector, SKINCOLOR_SLIDER_F) - ATTRIB(XonoticSlider, colorD, vector, SKINCOLOR_SLIDER_D) - ATTRIB(XonoticSlider, color2, vector, SKINCOLOR_SLIDER_S) + ATTRIB(XonoticTextSlider, color, vector, SKINCOLOR_SLIDER_N) + ATTRIB(XonoticTextSlider, colorC, vector, SKINCOLOR_SLIDER_C) + ATTRIB(XonoticTextSlider, colorF, vector, SKINCOLOR_SLIDER_F) + ATTRIB(XonoticTextSlider, colorD, vector, SKINCOLOR_SLIDER_D) + ATTRIB(XonoticTextSlider, color2, vector, SKINCOLOR_SLIDER_S) ATTRIB(XonoticTextSlider, cvarName, string, string_null) METHOD(XonoticTextSlider, loadCvars, void(entity)) @@ -61,6 +61,16 @@ void XonoticTextSlider_loadCvars(entity me) for(i = 1; i < n; ++i) s = strcat(s, " ", cvar_string(argv(i))); me.setValueFromIdentifier(me, s); + if(me.value < 0 && n > 1) + { + // if it failed: check if all cvars have the same value + // if yes, try its value as 1-word identifier + for(i = 1; i < n; ++i) + if(cvar_string(argv(i)) != cvar_string(argv(i-1))) + break; + if(i >= n) + me.setValueFromIdentifier(me, cvar_string(argv(0))); + } } void XonoticTextSlider_saveCvars(entity me) { diff --git a/qcsrc/server/anticheat.qc b/qcsrc/server/anticheat.qc index 3b729ca48c..5e7eb70756 100644 --- a/qcsrc/server/anticheat.qc +++ b/qcsrc/server/anticheat.qc @@ -70,11 +70,11 @@ void anticheat_physics() MEAN_ACCUMULATE(anticheat_div0_evade, 1 - (self.anticheat_div0_evade_forward_initial * v_forward), 1); } - MEAN_ACCUMULATE(anticheat_div0_strafebot_old, movement_oddity(self.movement, self.anticheat_div0_strafebot_movement_prev), max(0, 0.05 - frametime)); + MEAN_ACCUMULATE(anticheat_div0_strafebot_old, movement_oddity(self.movement, self.anticheat_div0_strafebot_movement_prev), max(0, sys_frametime - frametime)); self.anticheat_div0_strafebot_movement_prev = self.movement; if(vlen(self.anticheat_div0_strafebot_forward_prev)) - MEAN_ACCUMULATE(anticheat_div0_strafebot_new, 1 - (self.anticheat_div0_strafebot_forward_prev * v_forward), max(0, 0.05 - frametime)); + MEAN_ACCUMULATE(anticheat_div0_strafebot_new, 1 - (self.anticheat_div0_strafebot_forward_prev * v_forward), max(0, sys_frametime - frametime)); self.anticheat_div0_strafebot_forward_prev = v_forward; // generic speedhack detection: correlate anticheat_speedhack_movetime (UPDATED BEFORE THIS) and server time diff --git a/qcsrc/server/antilag.qc b/qcsrc/server/antilag.qc index 8b1dc6de1d..8a628a1bea 100644 --- a/qcsrc/server/antilag.qc +++ b/qcsrc/server/antilag.qc @@ -49,7 +49,7 @@ float antilag_find(entity e, float t) return -1; } -vector lerp(float t0, vector v0, float t1, vector v1, float t) +vector lerpv(float t0, vector v0, float t1, vector v1, float t) { return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); } @@ -69,7 +69,17 @@ vector antilag_takebackorigin(entity e, float t) if(i1 >= ANTILAG_MAX_ORIGINS) i1 = 0; - return lerp(e.(antilag_times[i0]), e.(antilag_origins[i0]), e.(antilag_times[i1]), e.(antilag_origins[i1]), t); + return lerpv(e.(antilag_times[i0]), e.(antilag_origins[i0]), e.(antilag_times[i1]), e.(antilag_origins[i1]), t); +} + +vector antilag_takebackavgvelocity(entity e, float t0, float t1) +{ + vector o0, o1; + if(t0 >= t1) + return '0 0 0'; + o0 = antilag_takebackorigin(e, t0); + o1 = antilag_takebackorigin(e, t1); + return (o1 - o0) * (1 / (t1 - t0)); } void antilag_takeback(entity e, float t) diff --git a/qcsrc/server/antilag.qh b/qcsrc/server/antilag.qh index d4ed9118e8..2a7343243d 100644 --- a/qcsrc/server/antilag.qh +++ b/qcsrc/server/antilag.qh @@ -1,6 +1,7 @@ void antilag_record(entity e, float t); float antilag_find(entity e, float t); vector antilag_takebackorigin(entity e, float t); +vector antilag_takebackavgvelocity(entity e, float t0, float t1); void antilag_takeback(entity e, float t); void antilag_restore(entity e); diff --git a/qcsrc/server/bot/bot.qc b/qcsrc/server/bot/bot.qc index 3ef50481dc..945600a886 100644 --- a/qcsrc/server/bot/bot.qc +++ b/qcsrc/server/bot/bot.qc @@ -43,7 +43,7 @@ void bot_think() //self.bot_painintensity = self.bot_painintensity + self.bot_oldhealth - self.health; //self.bot_painintensity = bound(0, self.bot_painintensity, 100); - if(time < game_starttime || ((cvar("g_campaign") && !campaign_bots_may_start))) + if (cvar("g_campaign") && !campaign_bots_may_start) { self.nextthink = time + 0.5; return; @@ -81,6 +81,14 @@ void bot_think() self.BUTTON_CHAT = 0; self.BUTTON_USE = 0; + if (time < game_starttime) + { + // block the bot during the countdown to game start + self.movement = '0 0 0'; + self.nextthink = game_starttime; + return; + } + // if dead, just wait until we can respawn if (self.deadflag) { @@ -555,17 +563,16 @@ void bot_serverframe() // But don't remove bots immediately on level change, as the real players // usually haven't rejoined yet bots_would_leave = FALSE; - if ((realplayers || cvar("bot_join_empty") || (currentbots > 0 && time < 5))) + if (teamplay && cvar("bot_vs_human") && (c3==-1 && c4==-1)) + bots = min(ceil(fabs(cvar("bot_vs_human")) * activerealplayers), maxclients - realplayers); + else if ((realplayers || cvar("bot_join_empty") || (currentbots > 0 && time < 5))) { float realminplayers, minplayers; realminplayers = cvar("minplayers"); minplayers = max(0, floor(realminplayers)); float realminbots, minbots; - if(teamplay && cvar("bot_vs_human")) - realminbots = ceil(fabs(cvar("bot_vs_human")) * activerealplayers); - else - realminbots = cvar("bot_number"); + realminbots = cvar("bot_number"); minbots = max(0, floor(realminbots)); bots = min(max(minbots, minplayers - activerealplayers), maxclients - realplayers); diff --git a/qcsrc/server/cheats.qc b/qcsrc/server/cheats.qc index a75537907d..8d837b8014 100644 --- a/qcsrc/server/cheats.qc +++ b/qcsrc/server/cheats.qc @@ -672,6 +672,7 @@ float CheatCommand(float argc) END_CHEAT_FUNCTION(); } +void crosshair_trace_plusvisibletriggers(entity pl); void Drag_Begin(entity dragger, entity draggee, vector touchpoint); void Drag_Finish(entity dragger); float Drag_IsDraggable(entity draggee); @@ -725,7 +726,7 @@ float CheatFrame() if(Drag_CanDrag(self)) if(self.BUTTON_DRAG) { - crosshair_trace(self); + crosshair_trace_plusvisibletriggers(self); if(trace_ent) if(Drag_IsDraggable(trace_ent)) switch(0) @@ -752,6 +753,22 @@ float CheatFrame() // ENTITY DRAGGING +void crosshair_trace_plusvisibletriggers(entity pl) +{ + entity first; + entity e; + first = findchainfloat(solid, SOLID_TRIGGER); + + for (e = first; e; e = e.chain) + if (e.model != "") + e.solid = SOLID_BSP; + + crosshair_trace(pl); + + for (e = first; e; e = e.chain) + e.solid = SOLID_TRIGGER; +} + // on dragger: .float draggravity; .float dragspeed; // speed of mouse wheel action @@ -828,14 +845,16 @@ float Drag_IsDraggable(entity draggee) return FALSE; if(draggee.classname == "func_button") return FALSE; - if(draggee.model == "") - return FALSE; +// if(draggee.model == "") +// return FALSE; if(draggee.classname == "spectator") return FALSE; if(draggee.classname == "observer") return FALSE; if(draggee.classname == "exteriorweaponentity") return FALSE; + if(draggee.classname == "weaponentity") + return FALSE; return TRUE; } diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index f08ef5f538..ac33ddc50b 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -1593,7 +1593,7 @@ void ClientConnect (void) race_SendRankings(i, 0, 0, MSG_ONE); } } - else if(cvar("sv_teamnagger") && !g_ca) // teamnagger is currently bad for ca + else if(cvar("sv_teamnagger") && !(cvar("bot_vs_human") && (c3==-1 && c4==-1)) && !g_ca) // teamnagger is currently bad for ca send_CSQC_teamnagger(); CheatInitClient(); @@ -2856,9 +2856,16 @@ float isInvisibleString(string s) switch(c) { case 0: - case 32: - case 160: + case 32: // space break; + case 192: // charmap space + if (!cvar("utf8_enable")) + break; + return FALSE; + case 160: // space in unicode fonts + case 0xE000 + 192: // utf8 charmap space + if (cvar("utf8_enable")) + break; default: return FALSE; } diff --git a/qcsrc/server/cl_physics.qc b/qcsrc/server/cl_physics.qc index 70e702505c..2df6c1c4fe 100644 --- a/qcsrc/server/cl_physics.qc +++ b/qcsrc/server/cl_physics.qc @@ -33,6 +33,10 @@ float sv_airspeedlimit_nonqw; .float wasFlying; .float spectatorspeed; +.float multijump_count; +.float multijump_ready; +.float prevjumpbutton; + /* ============= PlayerJump @@ -66,9 +70,58 @@ void PlayerJump (void) return; } + if (cvar("g_multijump")) + { + if (self.prevjumpbutton == FALSE && !(self.flags & FL_ONGROUND)) // jump button pressed this frame and we are in midair + self.multijump_ready = TRUE; // this is necessary to check that we released the jump button and pressed it again + else + self.multijump_ready = FALSE; + } + + if(!doublejump && self.multijump_ready && self.multijump_count < cvar("g_multijump") && self.velocity_z > cvar("g_multijump_speed")) + { + // doublejump = FALSE; // checked above in the if + if (cvar("g_multijump") > 0) + { + if (cvar("g_multijump_add") == 0) // in this case we make the z velocity == jumpvelocity + { + if (self.velocity_z < mjumpheight) + { + doublejump = TRUE; + self.velocity_z = 0; + } + } + else + doublejump = TRUE; + + if(doublejump) + { + if(self.movement_x != 0 || self.movement_y != 0) // don't remove all speed if player isnt pressing any movement keys + { + float curspeed; + vector wishvel, wishdir; + + curspeed = max( + vlen(vec2(self.velocity)), // current xy speed + vlen(vec2(antilag_takebackavgvelocity(self, max(self.lastteleporttime + sys_frametime, time - 0.25), time))) // average xy topspeed over the last 0.25 secs + ); + makevectors(self.v_angle_y * '0 1 0'); + wishvel = v_forward * self.movement_x + v_right * self.movement_y; + wishdir = normalize(wishvel); + + self.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump + self.velocity_y = wishdir_y * curspeed; + // keep velocity_z unchanged! + } + self.multijump_count += 1; + } + } + self.multijump_ready = FALSE; // require releasing and pressing the jump button again for the next jump + } + if (!doublejump) - if (!(self.flags & FL_ONGROUND)) - return; + if (!(self.flags & FL_ONGROUND)) + return; if(!sv_pogostick) if (!(self.flags & FL_JUMPRELEASED)) @@ -319,8 +372,7 @@ void RaceCarPhysics() float mt; rigvel_z -= frametime * sv_gravity; // 4x gravity plays better - rigvel_xy = rigvel; - rigvel_xy_z = 0; + rigvel_xy = vec2(rigvel); if(g_bugrigs_planar_movement_car_jumping && !g_touchexplode) // touchexplode is a better way to handle collisions mt = MOVE_NORMAL; @@ -512,7 +564,7 @@ void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float acce vel_straight = self.velocity * wishdir; vel_z = self.velocity_z; - vel_xy = self.velocity - vel_z * '0 0 1'; + vel_xy = vec2(self.velocity); vel_perpend = vel_xy - vel_straight * wishdir; step = accel * frametime * wishspeed0; @@ -652,7 +704,7 @@ void SV_PlayerPhysics() float buttons_prev; float not_allowed_to_move; string c; - + // fix physics stats for g_movement_highspeed self.stat_sv_airaccel_qw = AdjustAirAccelQW(sv_airaccel_qw, autocvar_g_movement_highspeed); if(sv_airstrafeaccel_qw) @@ -897,6 +949,14 @@ void SV_PlayerPhysics() if(self.classname == "player") { + if(self.flags & FL_ONGROUND) + { + if (cvar("g_multijump") > 0) + self.multijump_count = 0; + else + self.multijump_count = -2; // the cvar value for infinite jumps is -1, so this needs to be smaller + } + if (self.BUTTON_JUMP) PlayerJump (); else @@ -904,6 +964,7 @@ void SV_PlayerPhysics() if (self.waterlevel == WATERLEVEL_SWIMMING) CheckWaterJump (); + self.prevjumpbutton = self.BUTTON_JUMP; } if (self.flags & FL_WATERJUMP ) diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 494a80b369..db8bc4bfc9 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -660,7 +660,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht // call the corpse damage function just in case it wants to gib self.event_damage(inflictor, attacker, 0, deathtype, hitloc, force); // set up to fade out later - SUB_SetFade (self, time + 12 + random () * 4, 1); + SUB_SetFade (self, time + 6 + random (), 1); // remove laserdot if(self.weaponentity) diff --git a/qcsrc/server/cl_weapons.qc b/qcsrc/server/cl_weapons.qc index 4ab7abde4b..9530f9a519 100644 --- a/qcsrc/server/cl_weapons.qc +++ b/qcsrc/server/cl_weapons.qc @@ -293,7 +293,7 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce) return; if(!W_IsWeaponThrowable(w)) return; - if(self.weaponentity.state != WS_READY) + if(self.deadflag == DEAD_NO && self.weaponentity.state != WS_READY) return; wb = W_WeaponBit(w); diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index 26e7075d3c..f452e51106 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -642,4 +642,6 @@ string deathmessage; #define ACTIVE_BUSY 2 #define ACTIVE_TOGGLE 3 .float active; -.float (float act_state) setactive; \ No newline at end of file +.float (float act_state) setactive; +======= +.entity realowner; diff --git a/qcsrc/server/domination.qc b/qcsrc/server/domination.qc index 5bf2b9ad86..3e5bed8b25 100644 --- a/qcsrc/server/domination.qc +++ b/qcsrc/server/domination.qc @@ -77,7 +77,10 @@ void dompoint_captured () wait_time = self.wait; bprint("^3", head.netname, "^3", self.message); - bprint(" ^7(", ftos(points), " points every ", ftos(wait_time), " seconds)\n"); + if (points != 1) + bprint(" ^7(", ftos(points), " points every ", ftos(wait_time), " seconds)\n"); + else + bprint(" ^7(", ftos(points), " point every ", ftos(wait_time), " seconds)\n"); if(self.enemy.playerid == self.enemy_playerid) PlayerScore_Add(self.enemy, SP_DOM_TAKES, 1); diff --git a/qcsrc/server/func_breakable.qc b/qcsrc/server/func_breakable.qc index eb4c8b4de6..44605ddeee 100644 --- a/qcsrc/server/func_breakable.qc +++ b/qcsrc/server/func_breakable.qc @@ -31,8 +31,6 @@ // Otherwise mdl_dead will be displayed at the map origin, and nobody would // want that! -.vector mins_save, maxs_save; - void func_breakable_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force); // @@ -87,15 +85,18 @@ void func_breakable_look_destroyed() { local float floor_z; + if(self.solid == SOLID_BSP) // in case a misc_follow moved me, save the current origin first + self.dropped_origin = self.origin; + if(self.mdl_dead == "") self.model = ""; else { - setmodel(self, self.mdl_dead); if (self.origin == '0 0 0') { // probably no origin brush, so don't spawn in the middle of the map.. floor_z = self.absmin_z; setorigin(self,((self.absmax+self.absmin)*.5)); self.origin_z = floor_z; } + setmodel(self, self.mdl_dead); } self.solid = SOLID_NOT; @@ -104,6 +105,8 @@ void func_breakable_look_destroyed() void func_breakable_look_restore() { setmodel(self, self.mdl); + if(self.mdl_dead != "") // only do this if we use mdl_dead, to behave better with misc_follow + setorigin(self, self.dropped_origin); self.solid = SOLID_BSP; } @@ -113,7 +116,6 @@ void func_breakable_behave_destroyed() self.takedamage = DAMAGE_NO; self.event_damage = SUB_Null; self.state = 1; - setsize(self, '0 0 0', '0 0 0'); func_breakable_colormod(); } @@ -123,7 +125,6 @@ void func_breakable_behave_restore() self.takedamage = DAMAGE_AIM; self.event_damage = func_breakable_damage; self.state = 0; - setsize(self, self.mins_save, self.maxs_save); func_breakable_colormod(); } @@ -145,6 +146,7 @@ void func_breakable_destroy() { string oldmsg; activator = self.owner; + self.owner = world; // set by W_PrepareExplosionByDamage // now throw around the debris n = tokenize_console(self.debris); @@ -232,8 +234,6 @@ void spawnfunc_func_breakable() { self.mdl = self.model; SetBrushEntityModel(); - self.mins_save = self.mins; - self.maxs_save = self.maxs; self.use = func_breakable_restore; @@ -247,6 +247,7 @@ void spawnfunc_func_breakable() { precache_sound(self.noise); self.team_saved = self.team; + self.dropped_origin = self.origin; self.reset = func_breakable_reset; func_breakable_reset(); diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index 45962bee7b..7108fd3dbe 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -364,11 +364,12 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype) // TODO: fix this? if (deathtype == DEATH_CUSTOM) - msg = strcat(deathmessage, " by ^1", msg); - else if (deathtype == DEATH_HURTTRIGGER && inflictor.message2 != "") - { - msg = ftos(strstrofs(inflictor.message2, "#", 0)); - } + msg = deathmessage; + else + msg = inflictor.message2; + + if(strstrofs(msg, "%", 0) < 0) + msg = strcat("%s ", msg, " by %s"); Send_KillNotification(a, s, msg, deathtype, MSG_KILL); @@ -435,6 +436,8 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype) msg = inflictor.message; else if (deathtype == DEATH_CUSTOM) msg = deathmessage; + if(strstrofs(msg, "%", 0) < 0) + msg = strcat("%s ", msg); GiveFrags(targ, targ, -1); if(PlayerScore_Add(targ, SP_SCORE, 0) == -5) { diff --git a/qcsrc/server/g_triggers.qc b/qcsrc/server/g_triggers.qc index 2ed219ac26..cecca06d2e 100644 --- a/qcsrc/server/g_triggers.qc +++ b/qcsrc/server/g_triggers.qc @@ -462,6 +462,7 @@ void spawnfunc_trigger_hurt() self.message = "was in the wrong place"; if (!self.message2) self.message2 = "was thrown into a world of hurt by"; + // self.message = "someone like %s always gets wrongplaced"; if(!trigger_hurt_first) trigger_hurt_first = self; @@ -818,7 +819,7 @@ void spawnfunc_func_pointparticles() if(!self.cnt) self.cnt = particleeffectnum(self.mdl); - Net_LinkEntity(self, FALSE, 0, pointparticles_SendEntity); + Net_LinkEntity(self, (self.spawnflags & 4), 0, pointparticles_SendEntity); IFTARGETED { diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 07898df168..9df213c1b8 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -703,6 +703,21 @@ void spawnfunc_worldspawn (void) localcmd("\n_sv_hook_gamestart ", GetGametype(), "\n"); + // fill sv_curl_serverpackages from .serverpackage files + if(cvar("sv_curl_serverpackages_auto")) + { + fd = search_begin("*.serverpackage", TRUE, FALSE); + s = ""; + if(fd >= 0) + { + j = search_getsize(fd); + for(i = 0; i < j; ++i) + s = strcat(s, " ", search_getfilename(fd, i)); + search_end(fd); + } + cvar_set("sv_curl_serverpackages", substring(s, 1, -1)); + } + world_initialized = 1; } diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 5b0fa2b8ca..3db4e47be8 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -100,9 +100,9 @@ string GetAdvancedDeathReports(entity enPlayer) // Extra fragmessage information if(cvar("sv_fragmessage_information_ping")) { if(clienttype(enPlayer) == CLIENTTYPE_BOT) // Bots have no ping - strMessage = strcat(strMessage, "\n^7(^2Bot"); + strMessage = strcat(strMessage, " ^7(^2Bot"); else - strMessage = strcat(strMessage, "\n^7(Ping ", strPlayerPingColor, ftos(nPlayerPing), "ms"); + strMessage = strcat(strMessage, " ^7(Ping ", strPlayerPingColor, ftos(nPlayerPing), "ms"); if(cvar("sv_fragmessage_information_handicap")) if(cvar("sv_fragmessage_information_handicap") == 2) if(nPlayerHandicap <= 1) diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc index c291e79a00..beed37321c 100644 --- a/qcsrc/server/t_items.qc +++ b/qcsrc/server/t_items.qc @@ -233,8 +233,13 @@ void Item_ScheduleRespawnIn(entity e, float t) void Item_ScheduleRespawn(entity e) { - Item_Show(e, 0); - Item_ScheduleRespawnIn(e, ITEM_RESPAWNTIME(e)); + if(e.respawntime > 0) + { + Item_Show(e, 0); + Item_ScheduleRespawnIn(e, ITEM_RESPAWNTIME(e)); + } + else // if respawntime is -1, this item does not respawn + Item_Show(e, -1); } void Item_ScheduleInitialRespawn(entity e) @@ -1192,7 +1197,7 @@ void spawnfunc_item_armor_small (void) { self.max_armorvalue = g_pickup_armorsmall_max; if(!self.pickup_anyway) self.pickup_anyway = g_pickup_armorsmall_anyway; - StartItem ("models/items/g_a1.md3", "misc/armor1.wav", g_pickup_respawntime_short, g_pickup_respawntimejitter_short, "5 Armor", IT_ARMOR_SHARD, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_LOW); + StartItem ("models/items/item_armor_small.md3", "misc/armor1.wav", g_pickup_respawntime_short, g_pickup_respawntimejitter_short, "5 Armor", IT_ARMOR_SHARD, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_LOW); } void spawnfunc_item_armor_medium (void) { @@ -1202,7 +1207,7 @@ void spawnfunc_item_armor_medium (void) { self.max_armorvalue = g_pickup_armormedium_max; if(!self.pickup_anyway) self.pickup_anyway = g_pickup_armormedium_anyway; - StartItem ("models/items/g_armormedium.md3", "misc/armor10.wav", g_pickup_respawntime_medium, g_pickup_respawntimejitter_medium, "25 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_MID); + StartItem ("models/items/item_armor_medium.md3", "misc/armor10.wav", g_pickup_respawntime_medium, g_pickup_respawntimejitter_medium, "25 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_MID); } void spawnfunc_item_armor_big (void) { @@ -1212,7 +1217,7 @@ void spawnfunc_item_armor_big (void) { self.max_armorvalue = g_pickup_armorbig_max; if(!self.pickup_anyway) self.pickup_anyway = g_pickup_armorbig_anyway; - StartItem ("models/items/g_a50.md3", "misc/armor17_5.wav", g_pickup_respawntime_long, g_pickup_respawntimejitter_long, "50 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, 20000); + StartItem ("models/items/item_armor_big.md3", "misc/armor17_5.wav", g_pickup_respawntime_long, g_pickup_respawntimejitter_long, "50 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, 20000); } void spawnfunc_item_armor_large (void) { @@ -1222,7 +1227,7 @@ void spawnfunc_item_armor_large (void) { self.max_armorvalue = g_pickup_armorlarge_max; if(!self.pickup_anyway) self.pickup_anyway = g_pickup_armorlarge_anyway; - StartItem ("models/items/g_a25.md3", "misc/armor25.wav", g_pickup_respawntime_long, g_pickup_respawntimejitter_long, "100 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_HIGH); + StartItem ("models/items/item_armor_large.md3", "misc/armor25.wav", g_pickup_respawntime_long, g_pickup_respawntimejitter_long, "100 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_HIGH); } void spawnfunc_item_health_small (void) { diff --git a/qcsrc/server/t_quake3.qc b/qcsrc/server/t_quake3.qc index 52214c2a6d..cffe88bd7f 100644 --- a/qcsrc/server/t_quake3.qc +++ b/qcsrc/server/t_quake3.qc @@ -5,42 +5,42 @@ // NOTE: for best experience, you need to swap MGs with SGs in the map or it won't have a MG // SG -> SG -void spawnfunc_ammo_shells() { spawnfunc_item_shells(); } - -// MG -> MG -void spawnfunc_weapon_machinegun() { spawnfunc_weapon_uzi(); } -void spawnfunc_ammo_bullets() { spawnfunc_item_bullets(); } - -// GL -> Mortar -void spawnfunc_ammo_grenades() { spawnfunc_item_rockets(); } - -// LG -> Electro -void spawnfunc_weapon_lightning() { spawnfunc_weapon_electro(); } -void spawnfunc_ammo_lightning() { spawnfunc_item_cells(); } - -// Plasma -> Hagar -void spawnfunc_weapon_plasmagun() { spawnfunc_weapon_hagar(); } -void spawnfunc_ammo_cells() { spawnfunc_item_rockets(); } - -// Rail -> Nex -void spawnfunc_weapon_railgun() { spawnfunc_weapon_nex(); } -void spawnfunc_ammo_slugs() { spawnfunc_item_cells(); } - -// BFG -> Crylink -void spawnfunc_weapon_bfg() { spawnfunc_weapon_crylink(); } -void spawnfunc_ammo_bfg() { spawnfunc_item_cells(); } +void spawnfunc_ammo_shells() { spawnfunc_item_shells(); } + +// MG -> MG +void spawnfunc_weapon_machinegun() { spawnfunc_weapon_uzi(); } +void spawnfunc_ammo_bullets() { spawnfunc_item_bullets(); } + +// GL -> Mortar +void spawnfunc_ammo_grenades() { spawnfunc_item_rockets(); } + +// LG -> Electro +void spawnfunc_weapon_lightning() { spawnfunc_weapon_electro(); } +void spawnfunc_ammo_lightning() { spawnfunc_item_cells(); } + +// Plasma -> Hagar +void spawnfunc_weapon_plasmagun() { spawnfunc_weapon_hagar(); } +void spawnfunc_ammo_cells() { spawnfunc_item_rockets(); } + +// Rail -> Rifle +void spawnfunc_weapon_railgun() { spawnfunc_weapon_campingrifle(); } +void spawnfunc_ammo_slugs() { spawnfunc_item_bullets(); } + +// BFG -> Crylink +void spawnfunc_weapon_bfg() { spawnfunc_weapon_crylink(); } +void spawnfunc_ammo_bfg() { spawnfunc_item_cells(); } // RL -> RL -void spawnfunc_ammo_rockets() { spawnfunc_item_rockets(); } - -// Armor -void spawnfunc_item_armor_body() { spawnfunc_item_armor_large(); } -void spawnfunc_item_armor_combat() { spawnfunc_item_armor_big(); } -void spawnfunc_item_armor_shard() { spawnfunc_item_armor_small(); } -void spawnfunc_item_enviro() { spawnfunc_item_invincible(); } +void spawnfunc_ammo_rockets() { spawnfunc_item_rockets(); } + +// Armor +void spawnfunc_item_armor_body() { spawnfunc_item_armor_large(); } +void spawnfunc_item_armor_combat() { spawnfunc_item_armor_big(); } +void spawnfunc_item_armor_shard() { spawnfunc_item_armor_small(); } +void spawnfunc_item_enviro() { spawnfunc_item_invincible(); } // weapon remove ent from defrag -void spawnfunc_target_init() +void spawnfunc_target_init() { self.spawnflags = 0; // remove all weapons except the ones listed below self.netname = "laser uzi"; // keep these weapons through the remove trigger diff --git a/qcsrc/server/t_teleporters.qc b/qcsrc/server/t_teleporters.qc index 795697dcdf..26acf7f0ea 100644 --- a/qcsrc/server/t_teleporters.qc +++ b/qcsrc/server/t_teleporters.qc @@ -29,13 +29,14 @@ void trigger_teleport_use() float check_tdeath(entity player, vector org, vector telefragmin, vector telefragmax) { - TDEATHLOOP(org) + if (player.classname == "player" && player.health >= 1) { - if ((player.classname == "player") && (player.health >= 1)) + TDEATHLOOP(org) { - if(head.classname == "player") - if(head.health >= 1) - return 1; + if not(teamplay && cvar("g_telefrags_teamplay") && head.team == player.team) + if(head.classname == "player") + if(head.health >= 1) + return 1; } } return 0; @@ -45,15 +46,16 @@ void tdeath(entity player, entity teleporter, entity telefragger, vector telefra { TDEATHLOOP(player.origin) { - if ((player.classname == "player") && (player.health >= 1)) + if (player.classname == "player" && player.health >= 1) { - if(head.classname == "player") - if(head.health >= 1) - ++tdeath_hit; - Damage (head, teleporter, telefragger, 10000, DEATH_TELEFRAG, head.origin, '0 0 0'); + if not(teamplay && cvar("g_telefrags_teamplay") && head.team == player.team) + { + if(head.classname == "player") + if(head.health >= 1) + ++tdeath_hit; + Damage (head, teleporter, telefragger, 10000, DEATH_TELEFRAG, head.origin, '0 0 0'); + } } - else if (telefragger.health < 1) // corpses gib - Damage (head, teleporter, telefragger, 10000, DEATH_TELEFRAG, head.origin, '0 0 0'); else // dead bodies and monsters gib themselves instead of telefragging Damage (telefragger, teleporter, telefragger, 10000, DEATH_TELEFRAG, telefragger.origin, '0 0 0'); } @@ -68,9 +70,10 @@ void spawn_tdeath(vector v0, entity e, vector v) #define TELEPORT_FLAG_SOUND 1 #define TELEPORT_FLAG_PARTICLES 2 #define TELEPORT_FLAG_TDEATH 4 +#define TELEPORT_FLAG_FORCE_TDEATH 8 #define TELEPORT_FLAGS_WARPZONE 0 -#define TELEPORT_FLAGS_PORTAL (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES) +#define TELEPORT_FLAGS_PORTAL (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH | TELEPORT_FLAG_FORCE_TDEATH) #define TELEPORT_FLAGS_TELEPORTER (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH) void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity, vector telefragmin, vector telefragmax, float tflags) { @@ -112,7 +115,7 @@ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angle if(player.classname == "player") { if(tflags & TELEPORT_FLAG_TDEATH) - if(player.takedamage && player.deadflag == DEAD_NO && !g_race && !g_cts && cvar("g_telefrags")) + if(player.takedamage && player.deadflag == DEAD_NO && !g_race && !g_cts && (cvar("g_telefrags") || (tflags & TELEPORT_FLAG_FORCE_TDEATH))) tdeath(player, teleporter, telefragger, telefragmin, telefragmax); // player no longer is on ground @@ -132,8 +135,7 @@ void TeleportPlayer(entity teleporter, entity player, vector to, vector to_angle player.pushltime = 0; } - if(player.isbot) - player.lastteleporttime = time; + player.lastteleporttime = time; // stop player name display { @@ -150,6 +152,7 @@ void Teleport_Touch (void) entity oldself, e; vector o; float p; + string s; if (other.health < 1) return; @@ -206,14 +209,15 @@ void Teleport_Touch (void) o = e.origin + '0 0 1' * (1 - other.mins_z - 24); TeleportPlayer(self, other, o, e.mangle, v_forward * vlen(other.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER); - if(e.target) - { - oldself = self; - activator = other; - self = e; - SUB_UseTargets(); - self = oldself; - } + activator = other; + s = self.target; self.target = string_null; + SUB_UseTargets(); + if not(self.target) self.target = s; + + oldself = self; + self = e; + SUB_UseTargets(); + self = oldself; } void spawnfunc_info_teleport_destination (void) @@ -308,5 +312,7 @@ void WarpZone_PostTeleportPlayer_Callback(entity pl) { // reset tracking of oldvelocity for impact damage (sudden velocity changes) pl.oldvelocity = pl.velocity; + // reset teleport time tracking too (or multijump can cause insane speeds) + pl.lastteleporttime = time; } } diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index 0798b29b29..04580e6c42 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -16,6 +16,8 @@ float IsTeamBalanceForced() return 0; if(cvar("g_campaign")) return 0; + if(cvar("bot_vs_human") && (c3==-1 && c4==-1)) + return 0; if(!cvar("g_balance_teams_force")) return -1; return 1; @@ -694,7 +696,7 @@ void CheckAllowedTeams (entity for_whom) } // TODO: Balance quantity of bots across > 2 teams when bot_vs_human is set (and remove next line) - if(c3==-1&&c4==-1) + if(c3==-1 && c4==-1) if(cvar("bot_vs_human") && for_whom) { if(cvar("bot_vs_human") > 0) @@ -721,6 +723,7 @@ float PlayerValue(entity p) if(IsTeamBalanceForced() == 1) return 1; return 1; + // FIXME: it always returns 1... } // c1...c4 should be set to -1 (not allowed) or 0 (allowed). @@ -799,7 +802,7 @@ float FindSmallestTeam(entity pl, float ignore_pl) if(c4 >= 0) totalteams = totalteams + 1; - if(cvar("bot_vs_human")) + if(cvar("bot_vs_human") && totalteams == 1) totalteams += 1; if(totalteams <= 1) @@ -879,6 +882,33 @@ float JoinBestTeam(entity pl, float only_return_best, float forcebestteam) // find out what teams are available CheckAllowedTeams(pl); + // if we want the player in a certain team for campaign, force him there + if(cvar("g_campaign")) + if(clienttype(pl) == CLIENTTYPE_REAL) // only players, not bots + { + switch(cvar("g_campaign_forceteam")) + { + case 1: + SetPlayerColors(pl, COLOR_TEAM1 - 1); + LogTeamchange(pl.playerid, pl.team, 2); + return COLOR_TEAM1; + case 2: + SetPlayerColors(pl, COLOR_TEAM2 - 1); + LogTeamchange(pl.playerid, pl.team, 2); + return COLOR_TEAM2; + case 3: + SetPlayerColors(pl, COLOR_TEAM3 - 1); + LogTeamchange(pl.playerid, pl.team, 2); + return COLOR_TEAM3; + case 4: + SetPlayerColors(pl, COLOR_TEAM4 - 1); + LogTeamchange(pl.playerid, pl.team, 2); + return COLOR_TEAM4; + default: + break; + } + } + // if we don't care what team he ends up on, put him on whatever team he entered as. // if he's not on a valid team, then let other code put him on the smallest team if(!forcebestteam) @@ -911,7 +941,7 @@ float JoinBestTeam(entity pl, float only_return_best, float forcebestteam) smallest = FindSmallestTeam(pl, TRUE); - if(!only_return_best) + if(!only_return_best && !pl.bot_forced_team) { TeamchangeFrags(self); if(smallest == 1) diff --git a/qcsrc/server/w_common.qc b/qcsrc/server/w_common.qc index 4427320586..99df7041ba 100644 --- a/qcsrc/server/w_common.qc +++ b/qcsrc/server/w_common.qc @@ -511,6 +511,7 @@ void W_PrepareExplosionByDamage(entity attacker, void() explode) self.takedamage = DAMAGE_NO; self.event_damage = SUB_Null; self.owner = attacker; + self.realowner = attacker; // do not explode NOW but in the NEXT FRAME! // because recursive calls to RadiusDamage are not allowed diff --git a/qcsrc/server/w_crylink.qc b/qcsrc/server/w_crylink.qc index e9015f5806..5d1721f78f 100644 --- a/qcsrc/server/w_crylink.qc +++ b/qcsrc/server/w_crylink.qc @@ -4,8 +4,6 @@ REGISTER_WEAPON(CRYLINK, w_crylink, IT_CELLS, 6, WEP_FLAG_NORMAL | WEP_TYPE_SPLA #ifdef SVQC .float gravity; -.entity realowner; - .entity queuenext; .entity queueprev; diff --git a/qcsrc/server/w_electro.qc b/qcsrc/server/w_electro.qc index a98c5a9153..e885cd0d28 100644 --- a/qcsrc/server/w_electro.qc +++ b/qcsrc/server/w_electro.qc @@ -226,7 +226,7 @@ void lgbeam_think() makevectors(self.owner.v_angle); - float dt; + float dt, f; dt = frametime; if not(self.owner.items & IT_UNLIMITED_WEAPON_AMMO) { @@ -243,8 +243,11 @@ void lgbeam_think() { vector force; force = w_shotdir * cvar("g_balance_electro_primary_force") + '0 0 1' * cvar("g_balance_electro_primary_force_up"); - Damage (trace_ent, self.owner, self.owner, cvar("g_balance_electro_primary_damage") * dt, WEP_ELECTRO, trace_endpos, force * dt); - Damage_RecordDamage(self.owner, WEP_ELECTRO, cvar("g_balance_electro_primary_damage") * dt); + + f = ExponentialFalloff(cvar("g_balance_electro_primary_falloff_mindist"), cvar("g_balance_electro_primary_falloff_maxdist"), cvar("g_balance_electro_primary_falloff_halflifedist"), vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos) - w_shotorg)); + + Damage (trace_ent, self.owner, self.owner, cvar("g_balance_electro_primary_damage") * dt * f, WEP_ELECTRO, trace_endpos, force * dt); + Damage_RecordDamage(self.owner, WEP_ELECTRO, cvar("g_balance_electro_primary_damage") * dt * f); } W_Plasma_TriggerCombo(trace_endpos, cvar("g_balance_electro_primary_comboradius"), self.owner); @@ -365,7 +368,14 @@ float w_electro(float req) weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_electro_primary_animtime"), w_ready); } } else { - self.BUTTON_ATCK_prev = 0; + if(cvar("g_balance_electro_lightning")) + { + if (self.BUTTON_ATCK_prev != 0) + { + ATTACK_FINISHED(self) = time + cvar("g_balance_electro_primary_refire") * W_WeaponRateFactor(); + } + self.BUTTON_ATCK_prev = 0; + } } if (self.BUTTON_ATCK2) @@ -398,7 +408,7 @@ float w_electro(float req) else if (req == WR_CHECKAMMO1) { if(cvar("g_balance_electro_lightning")) - return self.ammo_cells >= cvar("g_balance_electro_primary_ammo") * cvar("g_balance_electro_primary_refire"); + return !cvar("g_balance_electro_primary_ammo") || (self.ammo_cells > 0); else return self.ammo_cells >= cvar("g_balance_electro_primary_ammo"); } diff --git a/qcsrc/server/w_fireball.qc b/qcsrc/server/w_fireball.qc index 368faecbf3..0827d2402f 100644 --- a/qcsrc/server/w_fireball.qc +++ b/qcsrc/server/w_fireball.qc @@ -378,7 +378,6 @@ float w_fireball(float req) } else if(req == WR_PRECACHE) { - precache_sound("weapons/fireball_impact.wav"); precache_sound("weapons/fireball_impact2.wav"); } else if (req == WR_SUICIDEMESSAGE) diff --git a/qcsrc/server/w_grenadelauncher.qc b/qcsrc/server/w_grenadelauncher.qc index 6848b2a5ad..84b98b525c 100644 --- a/qcsrc/server/w_grenadelauncher.qc +++ b/qcsrc/server/w_grenadelauncher.qc @@ -32,6 +32,10 @@ void W_Grenade_Explode2 (void) self.event_damage = SUB_Null; self.takedamage = DAMAGE_NO; + + if(self.movetype == MOVETYPE_NONE) + self.velocity = self.oldvelocity; + RadiusDamage (self, self.owner, cvar("g_balance_grenadelauncher_secondary_damage"), cvar("g_balance_grenadelauncher_secondary_edgedamage"), cvar("g_balance_grenadelauncher_secondary_radius"), world, cvar("g_balance_grenadelauncher_secondary_force"), self.projectiledeathtype, other); remove (self); @@ -51,7 +55,7 @@ void W_Grenade_Damage (entity inflictor, entity attacker, float damage, float de void W_Grenade_Touch1 (void) { PROJECTILE_TOUCH; - if(cvar("g_balance_grenadelauncher_primary_sticky") && other.takedamage != DAMAGE_AIM) + if(cvar("g_balance_grenadelauncher_primary_sticky") && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))) { spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM); @@ -74,7 +78,7 @@ void W_Grenade_Touch1 (void) void W_Grenade_Touch2 (void) { PROJECTILE_TOUCH; - if(cvar("g_balance_grenadelauncher_secondary_sticky") && other.takedamage != DAMAGE_AIM) + if(cvar("g_balance_grenadelauncher_secondary_sticky") && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))) { spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM); @@ -92,7 +96,7 @@ void W_Grenade_Touch2 (void) } else { - if (other.takedamage == DAMAGE_AIM) + if (cvar("g_balance_grenadelauncher_secondary_sticky") || other.takedamage == DAMAGE_AIM) { self.use (); } @@ -123,7 +127,7 @@ void W_Grenade_Attack (void) if not(self.items & IT_UNLIMITED_WEAPON_AMMO) self.ammo_rockets = self.ammo_rockets - cvar("g_balance_grenadelauncher_primary_ammo"); - W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 4, "weapons/grenade_fire.wav", cvar("g_balance_grenadelauncher_primary_damage")); + W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 4, "weapons/grenade_fire.wav", cvar("g_balance_grenadelauncher_primary_damage")); w_shotdir = v_forward; // no TrueAim for grenades please pointparticles(particleeffectnum("grenadelauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1); @@ -137,7 +141,7 @@ void W_Grenade_Attack (void) PROJECTILE_MAKETRIGGER(gren); gren.projectiledeathtype = WEP_GRENADE_LAUNCHER; setorigin(gren, w_shotorg); - setsize(gren, '0 0 -3', '0 0 -3'); + setsize(gren, '-3 -3 -3', '3 3 3'); gren.nextthink = time + cvar("g_balance_grenadelauncher_primary_lifetime"); gren.think = adaptor_think2use_hittype_splash; @@ -161,7 +165,7 @@ void W_Grenade_Attack2 (void) if not(self.items & IT_UNLIMITED_WEAPON_AMMO) self.ammo_rockets = self.ammo_rockets - cvar("g_balance_grenadelauncher_secondary_ammo"); - W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 4, "weapons/grenade_fire.wav", cvar("g_balance_grenadelauncher_secondary_damage")); + W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 4, "weapons/grenade_fire.wav", cvar("g_balance_grenadelauncher_secondary_damage")); w_shotdir = v_forward; // no TrueAim for grenades please pointparticles(particleeffectnum("grenadelauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1); @@ -177,7 +181,7 @@ void W_Grenade_Attack2 (void) PROJECTILE_MAKETRIGGER(gren); gren.projectiledeathtype = WEP_GRENADE_LAUNCHER | HITTYPE_SECONDARY; setorigin(gren, w_shotorg); - setsize(gren, '0 0 -3', '0 0 -3'); + setsize(gren, '-3 -3 -3', '3 3 3'); gren.nextthink = time + cvar("g_balance_grenadelauncher_secondary_lifetime"); gren.think = adaptor_think2use_hittype_splash; diff --git a/qcsrc/server/w_shotgun.qc b/qcsrc/server/w_shotgun.qc index b186230ecf..f47077a257 100644 --- a/qcsrc/server/w_shotgun.qc +++ b/qcsrc/server/w_shotgun.qc @@ -65,12 +65,12 @@ void shotgun_meleethink (void) WarpZone_traceline_antilag(self.owner, self.owner.origin + self.owner.view_ofs, targpos, FALSE, self.owner, ANTILAG_LATENCY(self.owner)); // apply the damage, also remove self - if(trace_fraction < 1 && trace_ent.takedamage == DAMAGE_AIM && trace_ent.classname == "player") + if(trace_fraction < 1 && trace_ent.takedamage == DAMAGE_AIM && (trace_ent.classname == "player" || trace_ent.classname == "body")) { vector force; force = angle * cvar("g_balance_shotgun_secondary_force"); - Damage (trace_ent, self.owner, self.owner, cvar("g_balance_shotgun_secondary_damage") * ((f + 1) / 2), WEP_SHOTGUN | HITTYPE_SECONDARY , self.owner.origin + self.owner.view_ofs, force); - Damage_RecordDamage(self.owner, WEP_SHOTGUN | HITTYPE_SECONDARY, cvar("g_balance_shotgun_secondary_damage") * ((f + 1) / 2)); + Damage (trace_ent, self.owner, self.owner, cvar("g_balance_shotgun_secondary_damage") * min(1, f + 1), WEP_SHOTGUN | HITTYPE_SECONDARY , self.owner.origin + self.owner.view_ofs, force); + Damage_RecordDamage(self.owner, WEP_SHOTGUN | HITTYPE_SECONDARY, cvar("g_balance_shotgun_secondary_damage") * min(1, f + 1)); remove(self); } else if(time >= self.cnt + cvar("g_balance_shotgun_secondary_melee_time")) // missed, remove ent @@ -94,6 +94,8 @@ void W_Shotgun_Attack2 (void) void spawnfunc_weapon_shotgun(); // defined in t_items.qc +.float shotgun_primarytime; + float w_shotgun(float req) { if (req == WR_AIM) @@ -104,10 +106,16 @@ float w_shotgun(float req) else if (req == WR_THINK) { if (self.BUTTON_ATCK) - if (weapon_prepareattack(0, cvar("g_balance_shotgun_primary_refire"))) { - W_Shotgun_Attack(); - weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_shotgun_primary_animtime"), w_ready); + if (time >= self.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary + { + if(weapon_prepareattack(0, cvar("g_balance_shotgun_primary_animtime"))) + { + W_Shotgun_Attack(); + self.shotgun_primarytime = time + cvar("g_balance_shotgun_primary_refire"); + weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_shotgun_primary_animtime"), w_ready); + } + } } if (self.BUTTON_ATCK2 && cvar("g_balance_shotgun_secondary")) if (weapon_prepareattack(1, cvar("g_balance_shotgun_secondary_refire"))) diff --git a/qcsrc/warpzonelib/client.qc b/qcsrc/warpzonelib/client.qc index d084e08084..725f84ffbd 100644 --- a/qcsrc/warpzonelib/client.qc +++ b/qcsrc/warpzonelib/client.qc @@ -1,5 +1,20 @@ +void WarpZone_Fade_PreDraw() +{ + if(self.warpzone_fadestart) + self.alpha = bound(0, (self.warpzone_fadeend - vlen(view_origin - self.origin - 0.5 * (self.mins + self.maxs))) / (self.warpzone_fadeend - self.warpzone_fadestart), 1); + else + self.alpha = 1; + //print(sprintf("%v <-> %v\n", view_origin, self.origin + 0.5 * (self.mins + self.maxs))); + if(self.alpha <= 0) + self.drawmask = 0; + else + self.drawmask = MASK_NORMAL; +} + void WarpZone_Read(float isnew) { + float f; + ++warpzone_warpzones_exist; if not(self.enemy) { @@ -8,10 +23,16 @@ void WarpZone_Read(float isnew) } self.classname = "trigger_warpzone"; - self.warpzone_isboxy = ReadByte(); - self.origin_x = ReadCoord(); - self.origin_y = ReadCoord(); - self.origin_z = ReadCoord(); + f = ReadByte(); + self.warpzone_isboxy = (f & 1); + if(f & 4) + { + self.origin_x = ReadCoord(); + self.origin_y = ReadCoord(); + self.origin_z = ReadCoord(); + } + else + self.origin = '0 0 0'; self.modelindex = ReadShort(); self.mins_x = ReadCoord(); self.mins_y = ReadCoord(); @@ -33,25 +54,48 @@ void WarpZone_Read(float isnew) self.avelocity_y = ReadCoord(); self.avelocity_z = ReadCoord(); + if(f & 2) + { + self.warpzone_fadestart = ReadShort(); + self.warpzone_fadeend = max(self.warpzone_fadestart + 1, ReadShort()); + } + else + { + self.warpzone_fadestart = 0; + self.warpzone_fadeend = 0; + } + // common stuff WarpZone_SetUp(self, self.enemy.oldorigin, self.enemy.avelocity, self.oldorigin, self.avelocity); - // engine currently wants this - self.drawmask = MASK_NORMAL; - // link me //setmodel(self, self.model); setorigin(self, self.origin); setsize(self, self.mins, self.maxs); + + // how to draw + // engine currently wants this + if(self.warpzone_fadestart) + self.predraw = WarpZone_Fade_PreDraw; + else + self.drawmask = MASK_NORMAL; } void WarpZone_Camera_Read(float isnew) { + float f; ++warpzone_cameras_exist; self.classname = "func_warpzone_camera"; - self.origin_x = ReadCoord(); - self.origin_y = ReadCoord(); - self.origin_z = ReadCoord(); + + f = ReadByte(); + if(f & 4) + { + self.origin_x = ReadCoord(); + self.origin_y = ReadCoord(); + self.origin_z = ReadCoord(); + } + else + self.origin = '0 0 0'; self.modelindex = ReadShort(); self.mins_x = ReadCoord(); self.mins_y = ReadCoord(); @@ -67,6 +111,17 @@ void WarpZone_Camera_Read(float isnew) self.avelocity_y = ReadCoord(); self.avelocity_z = ReadCoord(); + if(f & 2) + { + self.warpzone_fadestart = ReadShort(); + self.warpzone_fadeend = max(self.warpzone_fadestart + 1, ReadShort()); + } + else + { + self.warpzone_fadestart = 0; + self.warpzone_fadeend = 0; + } + // common stuff WarpZone_Camera_SetUp(self, self.oldorigin, self.avelocity); @@ -77,6 +132,13 @@ void WarpZone_Camera_Read(float isnew) //setmodel(self, self.model); setorigin(self, self.origin); setsize(self, self.mins, self.maxs); + + // how to draw + // engine currently wants this + if(self.warpzone_fadestart) + self.predraw = WarpZone_Fade_PreDraw; + else + self.drawmask = MASK_NORMAL; } float warpzone_fixingview; diff --git a/qcsrc/warpzonelib/common.qc b/qcsrc/warpzonelib/common.qc index 360652d6f2..1e4fc3e630 100644 --- a/qcsrc/warpzonelib/common.qc +++ b/qcsrc/warpzonelib/common.qc @@ -28,6 +28,11 @@ var float autocvar_cl_warpzone_usetrace = 1; vector WarpZone_camera_transform(vector org, vector ang) { vector vf, vr, vu; + if(self.warpzone_fadestart) + if(vlen(org - self.origin - 0.5 * (self.mins + self.maxs)) > self.warpzone_fadeend + 400) + return org; + // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies) + // unneeded on client, on server this helps a lot vf = v_forward; vr = v_right; vu = v_up; @@ -61,6 +66,11 @@ void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, ve vector WarpZone_Camera_camera_transform(vector org, vector ang) { // a fixed camera view + if(self.warpzone_fadestart) + if(vlen(org - self.origin - 0.5 * (self.mins + self.maxs)) > self.warpzone_fadeend + 400) + return org; + // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies) + // unneeded on client, on server this helps a lot trace_endpos = self.warpzone_origin; makevectors(self.warpzone_angles); return self.warpzone_origin; @@ -132,6 +142,8 @@ entity WarpZone_Find(vector mi, vector ma) { // if we are near any warpzone planes - MOVE AWAY (work around nearclip) entity e; + if(!warpzone_warpzones_exist) + return world; for(e = world; (e = find(e, classname, "trigger_warpzone")); ) if(WarpZoneLib_BoxTouchesBrush(mi, ma, e, world)) return e; @@ -141,6 +153,8 @@ entity WarpZone_Find(vector mi, vector ma) void WarpZone_MakeAllSolid() { entity e; + if(!warpzone_warpzones_exist) + return; for(e = world; (e = find(e, classname, "trigger_warpzone")); ) e.solid = SOLID_BSP; } @@ -148,6 +162,8 @@ void WarpZone_MakeAllSolid() void WarpZone_MakeAllOther() { entity e; + if(!warpzone_warpzones_exist) + return; for(e = world; (e = find(e, classname, "trigger_warpzone")); ) e.solid = SOLID_TRIGGER; } @@ -227,7 +243,7 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, goto fail; } WarpZone_Trace_AddTransform(wz); - org = WarpZone_TransformOrigin(wz, trace_endpos); + org = WarpZone_TransformOrigin(wz, org); end = WarpZone_TransformOrigin(wz, end); } WarpZone_MakeAllSolid(); @@ -303,6 +319,9 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo vector vf, vr, vu, v0, o0; entity wz; + o0 = e.origin; + v0 = e.velocity; + WarpZone_Trace_InitTransform(); WarpZone_tracetoss_time = 0; if(!warpzone_warpzones_exist) @@ -312,14 +331,15 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo cb(e.origin, trace_endpos, trace_endpos); dt = vlen(e.origin - o0) / vlen(e.velocity); WarpZone_tracetoss_time += dt; + e.velocity_z -= dt * g; + WarpZone_tracetoss_velocity = e.velocity; + e.velocity = v0; return; } vf = v_forward; vr = v_right; vu = v_up; - o0 = e.origin; - v0 = e.velocity; // if starting in warpzone, first transform wz = WarpZone_Find(e.origin + e.mins, e.origin + e.maxs); @@ -354,7 +374,7 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo e.origin = trace_endpos; dt = vlen(e.origin - o0) / vlen(e.velocity); WarpZone_tracetoss_time += dt; - e.velocity_z -= WarpZone_tracetoss_time * g; + e.velocity_z -= dt * g; if(trace_fraction >= 1) break; if(trace_ent.classname != "trigger_warpzone") diff --git a/qcsrc/warpzonelib/common.qh b/qcsrc/warpzonelib/common.qh index 8405ce6d3c..9ccd5216a6 100644 --- a/qcsrc/warpzonelib/common.qh +++ b/qcsrc/warpzonelib/common.qh @@ -15,6 +15,8 @@ const void func_null(void); // never assign to this one please .vector warpzone_targetangles; .vector warpzone_targetforward; .vector warpzone_transform; +.float warpzone_fadestart; +.float warpzone_fadeend; void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang); float WarpZoneLib_BoxTouchesBrush(vector mi, vector ma, entity e, entity ig); diff --git a/qcsrc/warpzonelib/server.qc b/qcsrc/warpzonelib/server.qc index 7c53d6e4aa..cfa6ef965e 100644 --- a/qcsrc/warpzonelib/server.qc +++ b/qcsrc/warpzonelib/server.qc @@ -111,14 +111,23 @@ void WarpZone_Touch (void) e = self.enemy; if(WarpZone_Teleport(other)) { - if(self.aiment.target) - { - oldself = self; - activator = other; - self = self.aiment; - SUB_UseTargets(); - self = oldself; - } + string save1, save2; + activator = other; + + save1 = self.target; self.target = string_null; + save2 = self.target3; self.target3 = string_null; + SUB_UseTargets(); + if not(self.target) self.target = save1; + if not(self.target3) self.target3 = save2; + + oldself = self; + self = self.enemy; + save1 = self.target; self.target = string_null; + save2 = self.target2; self.target2 = string_null; + SUB_UseTargets(); + if not(self.target) self.target = save1; + if not(self.target2) self.target2 = save2; + self = oldself; } else { @@ -128,15 +137,26 @@ void WarpZone_Touch (void) float WarpZone_Send(entity to, float sendflags) { + float f; WriteByte(MSG_ENTITY, ENT_CLIENT_WARPZONE); // we must send this flag for clientside to match properly too - WriteByte(MSG_ENTITY, self.warpzone_isboxy); + f = 0; + if(self.warpzone_isboxy) + f |= 1; + if(self.warpzone_fadestart) + f |= 2; + if(self.origin != '0 0 0') + f |= 4; + WriteByte(MSG_ENTITY, f); // we need THESE to render the warpzone (and cull properly)... - WriteCoord(MSG_ENTITY, self.origin_x); - WriteCoord(MSG_ENTITY, self.origin_y); - WriteCoord(MSG_ENTITY, self.origin_z); + if(f & 4) + { + WriteCoord(MSG_ENTITY, self.origin_x); + WriteCoord(MSG_ENTITY, self.origin_y); + WriteCoord(MSG_ENTITY, self.origin_z); + } WriteShort(MSG_ENTITY, self.modelindex); WriteCoord(MSG_ENTITY, self.mins_x); @@ -161,17 +181,33 @@ float WarpZone_Send(entity to, float sendflags) WriteCoord(MSG_ENTITY, self.warpzone_targetangles_y); WriteCoord(MSG_ENTITY, self.warpzone_targetangles_z); + if(f & 2) + { + WriteShort(MSG_ENTITY, self.warpzone_fadestart); + WriteShort(MSG_ENTITY, self.warpzone_fadeend); + } + return TRUE; } float WarpZone_Camera_Send(entity to, float sendflags) { + float f; WriteByte(MSG_ENTITY, ENT_CLIENT_WARPZONE_CAMERA); + if(self.warpzone_fadestart) + f |= 2; + if(self.origin != '0 0 0') + f |= 4; + WriteByte(MSG_ENTITY, f); + // we need THESE to render the warpzone (and cull properly)... - WriteCoord(MSG_ENTITY, self.origin_x); - WriteCoord(MSG_ENTITY, self.origin_y); - WriteCoord(MSG_ENTITY, self.origin_z); + if(f & 4) + { + WriteCoord(MSG_ENTITY, self.origin_x); + WriteCoord(MSG_ENTITY, self.origin_y); + WriteCoord(MSG_ENTITY, self.origin_z); + } WriteShort(MSG_ENTITY, self.modelindex); WriteCoord(MSG_ENTITY, self.mins_x); @@ -190,6 +226,12 @@ float WarpZone_Camera_Send(entity to, float sendflags) WriteCoord(MSG_ENTITY, self.enemy.angles_y); WriteCoord(MSG_ENTITY, self.enemy.angles_z); + if(f & 2) + { + WriteShort(MSG_ENTITY, self.warpzone_fadestart); + WriteShort(MSG_ENTITY, self.warpzone_fadeend); + } + return TRUE; } @@ -213,7 +255,7 @@ float WarpZone_CheckProjectileImpact() WarpZone_TraceBox_ThroughZone(self.warpzone_oldorigin, self.mins, self.maxs, self.warpzone_oldorigin + self.warpzone_oldvelocity * frametime, MOVE_NORMAL, self, wz, WarpZone_trace_callback_t_null); // this will get us through the warpzone setorigin(self, trace_endpos); self.angles = WarpZone_TransformAngles(WarpZone_trace_transform, self.angles); - self.velocity = WarpZone_TransformVelocity(WarpZone_trace_transform, self.velocity); + self.velocity = WarpZone_TransformVelocity(WarpZone_trace_transform, self.warpzone_oldvelocity); // in case we are in our warp zone post-teleport, shift the projectile forward a bit mpd = max(vlen(self.mins), vlen(self.maxs)); @@ -265,6 +307,7 @@ void WarpZone_InitStep_FindOriginTarget() error("Warp zone with nonexisting killtarget"); return; } + self.killtarget = string_null; } } diff --git a/quake.rc b/quake.rc index b595010c73..40228b079a 100644 --- a/quake.rc +++ b/quake.rc @@ -3,9 +3,8 @@ exec config.cfg exec data/campaign.cfg exec config_update.cfg exec autoexec.cfg +exec font-nimbussansl.cfg stuffcmds //startdemos demos/demo1 demos/demo2 demos/demo3 //startdemos //play announcer/male/welcome.ogg - -exec font-nimbussansl.cfg diff --git a/scripts/leiprojectile.shader b/scripts/leiprojectile.shader new file mode 100644 index 0000000000..f94c04b33a --- /dev/null +++ b/scripts/leiprojectile.shader @@ -0,0 +1,89 @@ +models/lasertrail +{ + cull disable + { + map models/ltrail.tga + blendfunc add + rgbGen identity + } +} + +models/lasercore +{ + deformVertexes autosprite + { + map models/lcore.tga + blendfunc add + rgbGen identity + } +} + +models/plastrail +{ + cull disable + { + map models/ptrail.tga + blendfunc add + rgbGen identity + } +} + +models/plascore +{ + deformVertexes autosprite + { + map models/pcore.tga + blendfunc add + rgbGen identity + } +} + +models/bultrail +{ + cull disable + { + map models/bultrail.tga + blendfunc add + rgbGen identity + } +} + +models/bulcore +{ + deformVertexes autosprite + { + map models/bulcore.tga + blendfunc add + rgbGen identity + } +} + +models/eleccore +{ + { + animmap 45 models/eleccore.tga models/eleccore2.tga models/eleccore3.tga models/eleccore4.tga models/eleccore5.tga models/eleccore6.tga models/eleccore7.tga models/eleccore8.tga + blendfunc blend + rgbGen identity + } +} + +models/elecglass +{ + { + map models/elecglass.tga + blendfunc add + rgbGen lightingDiffuse + } +} + +models/elecbeam +{ + cull disable + { + map models/elecbeam.tga + blendfunc add + rgbGen identity + tcMod scroll -2 0 + } +} + diff --git a/scripts/nutsandbolts.shader b/scripts/nutsandbolts.shader new file mode 100644 index 0000000000..e0eb347fcb --- /dev/null +++ b/scripts/nutsandbolts.shader @@ -0,0 +1,10 @@ +nutsandboltssteel +{ + { + map textures/nutsandbolts3 + tcgen environment + } + { + map $lightmap + } +} diff --git a/scripts/rocket.shader b/scripts/rocket.shader new file mode 100644 index 0000000000..b3041f215c --- /dev/null +++ b/scripts/rocket.shader @@ -0,0 +1,10 @@ +rocketThrust +{ + surfaceparm trans + cull disable + { + clampmap textures/thrustc1.tga + blendfunc add + tcMod rotate 720 + } +} diff --git a/sound/nexball/shoot1.ogg b/sound/nexball/shoot1.ogg new file mode 100644 index 0000000000..558a4466ac Binary files /dev/null and b/sound/nexball/shoot1.ogg differ diff --git a/sound/nexball/shoot1.wav b/sound/nexball/shoot1.wav deleted file mode 100644 index c68f13fa47..0000000000 Binary files a/sound/nexball/shoot1.wav and /dev/null differ diff --git a/sound/player/default.sounds b/sound/player/default.sounds index f427e1ef95..cf93bb6a4a 100644 --- a/sound/player/default.sounds +++ b/sound/player/default.sounds @@ -1,31 +1,31 @@ -//affirmative sound/player/torus/affirmative 0 -attack sound/player/torus/attack 0 -//attacking sound/player/torus/attacking 0 -attackinfive sound/player/torus/letsgo 0 -coverme sound/player/torus/coverme 0 -//defend sound/player/voice/defend 1 -//defending sound/player/torus/defending 0 -//droppedflag sound/player/voice/droppedflag 0 -//flagcarriertakingdamage sound/player/voice/flagcarriertakingdamage 0 -//freelance sound/player/voice/freelance 1 -//getflag sound/player/voice/getflag 0 -incoming sound/player/torus/incoming 0 -meet sound/player/torus/waypoint 0 -needhelp sound/player/torus/needhelp 0 -//negative sound/player/torus/negative 0 -//onmyway sound/player/torus/onmyway 0 -//roaming sound/player/torus/roaming 0 -//seenenemy sound/player/torus/seenenemy 0 -seenflag sound/player/torus/flagseen 0 -taunt sound/player/torus/taunt 0 -teamshoot sound/player/torus/teamshoot 0 -death sound/player/torus/death 0 -drown sound/player/torus/drown 0 -//fall sound/debug/v_falling 0 +//affirmative sound/player/torus/coms/affirmative 0 +attack sound/player/torus/coms/attack 0 +//attacking sound/player/torus/coms/attacking 0 +attackinfive sound/player/torus/coms/letsgo 0 +coverme sound/player/torus/coms/coverme 0 +//defend sound/player/torus/coms/defend 1 +//defending sound/player/torus/coms/defending 0 +//droppedflag sound/player/torus/coms/droppedflag 0 +//flagcarriertakingdamage sound/player/torus/coms/flagcarriertakingdamage 0 +//freelance sound/player/torus/coms/freelance 1 +//getflag sound/player/torus/coms/getflag 0 +incoming sound/player/torus/coms/incoming 0 +meet sound/player/torus/coms/waypoint 0 +needhelp sound/player/torus/coms/needhelp 0 +//negative sound/player/torus/coms/negative 0 +//onmyway sound/player/torus/coms/onmyway 0 +//roaming sound/player/torus/coms/roaming 0 +//seenenemy sound/player/torus/coms/seenenemy 0 +seenflag sound/player/torus/coms/seenflag 0 +taunt sound/player/torus/coms/taunt 2 +teamshoot sound/player/torus/coms/teamshoot 0 +death sound/player/torus/player/death 0 +drown sound/player/torus/player/drown 0 +//fall sound/player/torus/player/fall 0 //falling sound/debug/v_falling 0 -gasp sound/player/torus/gasp 0 -jump sound/player/torus/jump 0 -pain25 sound/player/torus/pain25 0 -pain50 sound/player/torus/pain50 0 -pain75 sound/player/torus/pain75 0 -pain100 sound/player/torus/pain100 0 +gasp sound/player/torus/player/gasp 0 +jump sound/player/torus/player/fall 0 +pain25 sound/player/torus/player/pain25 0 +pain50 sound/player/torus/player/pain50 0 +pain75 sound/player/torus/player/pain75 0 +pain100 sound/player/torus/player/pain100 0 diff --git a/sound/weapons/grenade_stick.wav b/sound/weapons/grenade_stick.wav new file mode 100644 index 0000000000..e38395f5a3 Binary files /dev/null and b/sound/weapons/grenade_stick.wav differ diff --git a/sound/weather/--tenshihan.txt b/sound/weather/--tenshihan.txt new file mode 100644 index 0000000000..a0efdd12be --- /dev/null +++ b/sound/weather/--tenshihan.txt @@ -0,0 +1,5 @@ +All these weather effects were recorded by Myself and released under the GPL liscence. + +~Michael "Tenshihan" Quinn + +Mar 7th 2010 \ No newline at end of file diff --git a/sound/weather/rain_1.ogg b/sound/weather/rain_1.ogg deleted file mode 100644 index c31fccf0e2..0000000000 Binary files a/sound/weather/rain_1.ogg and /dev/null differ diff --git a/sound/weather/rain_1.wav b/sound/weather/rain_1.wav new file mode 100644 index 0000000000..f5443e49ef Binary files /dev/null and b/sound/weather/rain_1.wav differ diff --git a/sound/weather/rain_loud.wav b/sound/weather/rain_loud.wav new file mode 100644 index 0000000000..4b42eaa23b Binary files /dev/null and b/sound/weather/rain_loud.wav differ diff --git a/sound/weather/rain_medium.wav b/sound/weather/rain_medium.wav new file mode 100644 index 0000000000..9fe5479bb1 Binary files /dev/null and b/sound/weather/rain_medium.wav differ diff --git a/sound/weather/rain_quiet.wav b/sound/weather/rain_quiet.wav new file mode 100644 index 0000000000..f5443e49ef Binary files /dev/null and b/sound/weather/rain_quiet.wav differ diff --git a/sound/weather/rain_wind_thunder.wav b/sound/weather/rain_wind_thunder.wav new file mode 100644 index 0000000000..18bda306c4 Binary files /dev/null and b/sound/weather/rain_wind_thunder.wav differ diff --git a/sound/weather/thunder_background.wav b/sound/weather/thunder_background.wav new file mode 100644 index 0000000000..4d3b1c70a7 Binary files /dev/null and b/sound/weather/thunder_background.wav differ diff --git a/sound/weather/thunder_crack.wav b/sound/weather/thunder_crack.wav new file mode 100644 index 0000000000..6b2df85fda Binary files /dev/null and b/sound/weather/thunder_crack.wav differ diff --git a/sound/weather/thunder_rain.wav b/sound/weather/thunder_rain.wav new file mode 100644 index 0000000000..4a4f2a7add Binary files /dev/null and b/sound/weather/thunder_rain.wav differ diff --git a/sound/weather/wind_ambience.wav b/sound/weather/wind_ambience.wav new file mode 100644 index 0000000000..f9c31e861c Binary files /dev/null and b/sound/weather/wind_ambience.wav differ diff --git a/sound/weather/wind_scary.wav b/sound/weather/wind_scary.wav new file mode 100644 index 0000000000..ad97cd217e Binary files /dev/null and b/sound/weather/wind_scary.wav differ diff --git a/sound/weather/wind_strong.wav b/sound/weather/wind_strong.wav new file mode 100644 index 0000000000..f4e2ab7149 Binary files /dev/null and b/sound/weather/wind_strong.wav differ diff --git a/textures/f_shotgun.jpg b/textures/f_shotgun.jpg new file mode 100644 index 0000000000..d6d49a70c7 Binary files /dev/null and b/textures/f_shotgun.jpg differ diff --git a/textures/flags/flag_blue.tga b/textures/flags/flag_blue.tga new file mode 100644 index 0000000000..e84fca549d Binary files /dev/null and b/textures/flags/flag_blue.tga differ diff --git a/textures/flags/flag_blue_cloth.tga b/textures/flags/flag_blue_cloth.tga new file mode 100644 index 0000000000..a8ea97f5ff Binary files /dev/null and b/textures/flags/flag_blue_cloth.tga differ diff --git a/textures/flags/flag_blue_gloss.tga b/textures/flags/flag_blue_gloss.tga new file mode 100644 index 0000000000..77176c068c Binary files /dev/null and b/textures/flags/flag_blue_gloss.tga differ diff --git a/textures/flags/flag_blue_glow.tga b/textures/flags/flag_blue_glow.tga new file mode 100644 index 0000000000..88d58c0daf Binary files /dev/null and b/textures/flags/flag_blue_glow.tga differ diff --git a/textures/flags/flag_blue_laser.tga b/textures/flags/flag_blue_laser.tga new file mode 100644 index 0000000000..6901f4f35a Binary files /dev/null and b/textures/flags/flag_blue_laser.tga differ diff --git a/textures/flags/flag_blue_norm.tga b/textures/flags/flag_blue_norm.tga new file mode 100644 index 0000000000..fc260222e1 Binary files /dev/null and b/textures/flags/flag_blue_norm.tga differ diff --git a/textures/flags/flag_red.tga b/textures/flags/flag_red.tga new file mode 100644 index 0000000000..d659d8c9e9 Binary files /dev/null and b/textures/flags/flag_red.tga differ diff --git a/textures/flags/flag_red_cloth.tga b/textures/flags/flag_red_cloth.tga new file mode 100644 index 0000000000..ae451c97b3 Binary files /dev/null and b/textures/flags/flag_red_cloth.tga differ diff --git a/textures/flags/flag_red_gloss.tga b/textures/flags/flag_red_gloss.tga new file mode 100644 index 0000000000..a499830ce7 Binary files /dev/null and b/textures/flags/flag_red_gloss.tga differ diff --git a/textures/flags/flag_red_glow.tga b/textures/flags/flag_red_glow.tga new file mode 100644 index 0000000000..deae22e2f1 Binary files /dev/null and b/textures/flags/flag_red_glow.tga differ diff --git a/textures/flags/flag_red_laser.tga b/textures/flags/flag_red_laser.tga new file mode 100644 index 0000000000..f4d4de5580 Binary files /dev/null and b/textures/flags/flag_red_laser.tga differ diff --git a/textures/flags/flag_red_norm.tga b/textures/flags/flag_red_norm.tga new file mode 100644 index 0000000000..97480bb649 Binary files /dev/null and b/textures/flags/flag_red_norm.tga differ diff --git a/update-cvarcount.sh b/update-cvarcount.sh index 539c0c1df1..b82840ae08 100755 --- a/update-cvarcount.sh +++ b/update-cvarcount.sh @@ -5,6 +5,15 @@ 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` if [ "$countw" != "$countb" ]; then echo "Mismatch between balanceXonotic.cfg and $b. Aborting." + echo "Differences are:" + A=`mktemp` + B=`mktemp` + awk '/^seta? g_/ { print $2; }' balanceXonotic.cfg | sort -u | tr -d '\r' > "$A" + awk '/^seta? g_/ { print $2; }' "$b" | sort -u | tr -d '\r' > "$B" + echo "< missing in $b" + echo "> must get removed from $b" + diff "$A" "$B" | grep '^[<>]' | sort + rm -f "$A" "$B" exit 1 fi done diff --git a/xonotic-credits.txt b/xonotic-credits.txt index 20e6048f9b..efc6b5c519 100644 --- a/xonotic-credits.txt +++ b/xonotic-credits.txt @@ -49,7 +49,9 @@ by Forest "LordHavoc" Hale **Active Contributors Ben "MooKow" Banker +Calinou Kristian "morfar" Johansson +kojn Maik "SavageX" Merten MrBougo Stephan "esteel" Stahl