* -crlf
-*.7z -crlf -diff
+*.0 -diff -crlf
+*.1 crlf=input
+*.3 crlf=input
+*.7z -diff -crlf
*.ac crlf=input
+*.a -diff -crlf
*.afm crlf=input
*.aft crlf=input
+*.ai -diff -crlf
*.aliases crlf=input
all crlf=input
*.am crlf=input
*.animinfo crlf=input
-*.aps -crlf -diff
+*.aps -diff -crlf
+*.asc -diff -crlf
*.ase -crlf
*.bat -crlf
*.bgs crlf=input
-*.blend -crlf -diff
-*.bmp -crlf -diff
+*.blend1 -diff -crlf
+*.blend -diff -crlf
+blind_id -diff -crlf
+*.bmp -diff -crlf
branch-manager crlf=input
+*.brand crlf=input
BSDmakefile crlf=input
bsp2ent crlf=input
-*.bsp -crlf -diff
-*.cache -crlf -diff
+*.bsp -diff -crlf
+*.cache -diff -crlf
*.cbp -crlf
-*.cbp -crlf -diff
+*.cbp -diff -crlf
*.c crlf=input
*.cfg crlf=input
*.cg crlf=input
ChangeLog crlf=input
CHANGES crlf=input
+cjpeg -diff -crlf
COMPILING crlf=input
compress-texture crlf=input
*.conf crlf=input
COPYING crlf=input
*.cpp crlf=input
create crlf=input
+*.cron crlf=input
*.css crlf=input
-Current -crlf -diff
-*.cvsignore crlf=input
*.cvswrappers crlf=input
-*.dat -crlf -diff
-*.db -crlf -diff
+*.d0pk -diff -crlf
+*.db -diff -crlf
*.default crlf=input
*.def crlf=input
-*.dem -crlf -diff
+*.dem -diff -crlf
*.dev -crlf
-*.dll -crlf -diff
-DOCS -crlf -diff
+dir -diff -crlf
+djpeg -diff -crlf
+*.dll -diff -crlf
+DOCS -diff -crlf
*.dot crlf=input
DoxyConfig crlf=input
+doxyfile crlf=input
Doxyfile crlf=input
*.doxygen crlf=input
-*.dpm -crlf -diff
+*.dpm -diff -crlf
*.dsp -crlf
*.dsw -crlf
*.dtd crlf=input
-*.dylib -crlf -diff
+*.dylib -diff -crlf
+empty -diff -crlf
*.EncoderPlugin crlf=input
-*.ent -crlf
+*.flac -diff -crlf
*.form crlf=input
*.framegroups crlf=input
*.game crlf=input
+*.gdb crlf=input
gendox crlf=input
gendoxfunctions crlf=input
genDoxyfile crlf=input
-*.gif -crlf -diff
+*.gif -diff -crlf
*.gitattributes crlf=input
git-branch-manager crlf=input
git-filter-index crlf=input
git-filter-repository crlf=input
*.gitignore crlf=input
+git-pk3-import crlf=input
+git-pk3-merge crlf=input
git-pullall crlf=input
+git-recurse crlf=input
git-split-repository crlf=input
git-svn-checkout crlf=input
git-svn-update crlf=input
*.hs crlf=input
*.html crlf=input
*.html-part crlf=input
-*.icns -crlf -diff
-*.ico -crlf -diff
+*.icns -diff -crlf
+*.ico -diff -crlf
+*.idl crlf=input
*.idsoftware crlf=input
*.inc crlf=input
*.in crlf=input
+*.info-1 -diff -crlf
+*.info-2 -diff -crlf
+*.info -diff -crlf
+*.inl crlf=input
*.instantaction crlf=input
-*.iqm -crlf -diff
+*.iqm -diff -crlf
*.java crlf=input
*.jhm crlf=input
*.jnlp crlf=input
-*.jpg -crlf -diff
+jpegtran -diff -crlf
+*.jpg -diff -crlf
*.jsmooth crlf=input
+*.la crlf=input
LGPL crlf=input
LICENSE crlf=input
-*.lmp -crlf -diff
+*.lmp -diff -crlf
*.loaders crlf=input
-*.lso -crlf -diff
+*.lso -diff -crlf
+*.m4 crlf=input
makefile crlf=input
Makefile crlf=input
-*.makespr32 crlf=input
makespr32 crlf=input
-*.map -crlf
+*.map -crlf filter=mapclean
*.mapinfo crlf=input
*.m crlf=input
-*.md3 -crlf -diff
+*.md3 -diff -crlf
*.md5anim -crlf
*.md5mesh -crlf
-*.mdl -crlf -diff
+*.mdl -diff -crlf
*.med crlf=input
*.mf crlf=input
-*.mid -crlf -diff
+*.mid -diff -crlf
*.mk crlf=input
-*.mkdir -crlf -diff
-*.mmpz -crlf -diff
-*.modinfo crlf=input
+*.mkdir -diff -crlf
+*.mmpz -diff -crlf
*.modules crlf=input
-nexuiz-map-compiler crlf=input
*.nib -crlf
*.obj -crlf
-OFFSETS -crlf -diff
-*.ogg -crlf -diff
+OFFSETS -diff -crlf
+*.ogg -diff -crlf
*.options crlf=input
pangorc crlf=input
*.patch crlf=input
*.patchsets crlf=input
-*.pcx -crlf -diff
-*.pfb -crlf -diff
-*.pfm -crlf -diff
-*.pk3 -crlf -diff
+*.pc crlf=input
+*.pcx -diff -crlf
+*.pfb -diff -crlf
+*.pfm -diff -crlf
+*.pk3 -diff -crlf
PkgInfo crlf=input
*.pl crlf=input
*.plist crlf=input
*.pm crlf=input
-*.png -crlf -diff
-POSITIONS -crlf -diff
+*.png -diff -crlf
+POSITIONS -diff -crlf
*.proj -crlf
*.properties crlf=input
-*.psd -crlf -diff
+*.psd -diff -crlf
*.py crlf=input
*.q3map1 crlf=input
*.qc crlf=input
*.rb crlf=input
*.rc2 crlf=input
*.rc -crlf
+rdjpgcom -diff -crlf
*.readme crlf=input
README crlf=input
-*.rtlights -crlf -diff
+*.rtlights -diff -crlf
SCHEMA crlf=input
*.scm crlf=input
-SDL -crlf -diff
-SDLMain.m crlf=input
+sdl-config crlf=input
+SDL -diff -crlf
*.shader crlf=input
*.sh crlf=input
*.skin crlf=input
*.sln -crlf
*.sounds crlf=input
-*.sp2 -crlf -diff
-*.spr32 -crlf -diff
-*.spr -crlf -diff
+*.sp2 -diff -crlf
+*.spr32 -diff -crlf
+*.spr -diff -crlf
*.src crlf=input
*.strings crlf=input
-*.strip crlf=input
strip crlf=input
-*.svg -crlf -diff
-*.TAB -crlf -diff
-*.tga -crlf -diff
-TMAP -crlf -diff
+*.svg -diff -crlf
+*.TAB -diff -crlf
+*.tga -diff -crlf
+TMAP -diff -crlf
todo crlf=input
TODO crlf=input
-*.ttf -crlf -diff
-*.TTF -crlf -diff
+*.ttf -diff -crlf
+*.TTF -diff -crlf
*.txt crlf=input
-*.TXT crlf=input
update-shaderlists crlf=input
+*.vbs -crlf
*.vcproj -crlf
-*.wav -crlf -diff
-*.waypoints -crlf -diff
+versionbuilder crlf=input
+*.wav -diff -crlf
+*.waypoints -diff -crlf
w crlf=input
*.width crlf=input
*.workspace -crlf
-*.xcf -crlf -diff
+wrjpgcom -diff -crlf
+*.xcf -diff -crlf
*.xlink crlf=input
*.xml crlf=input
xonotic-map-compiler-autobuild crlf=input
xonotic-map-compiler crlf=input
+xonotic-map-screenshot crlf=input
+xonotic-osx-agl crlf=input
+xonotic-osx-sdl crlf=input
*.xpm crlf=input
-*.zip -crlf -diff
+*.zip -diff -crlf
zipdiff crlf=input
-*.zym -crlf -diff
+*.zym -diff -crlf
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
FTEQCCFLAGS_WATERMARK ?= -DWATERMARK='"^1$(shell git describe) TEST BUILD"'
FTEQCCFLAGS ?= -Werror -Wall -Wno-mundane -O3 -Ono-c -Ono-cs -flo $(FTEQCCFLAGS_EXTRA) $(FTEQCCFLAGS_WATERMARK)
-FTEQCCFLAGS_PROGS ?=
-FTEQCCFLAGS_MENU ?=
+FTEQCCFLAGS_PROGS ?=
+FTEQCCFLAGS_MENU ?=
# NOTE: use -DUSE_FTE instead of -TFTE here!
# It will automagically add an engine check with -TID and then change back to -TFTE
.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
-csprogs.dat: qcsrc/client/*.* qcsrc/common/*.* qcsrc/warpzonelib/*.*
+FILES_CSPROGS = qcsrc/client/progs.src $(shell sed '/\.dat/d; s,//.*,,; s,[^ ],qcsrc/client/&,' < qcsrc/client/progs.src)
+csprogs.dat: $(FILES_CSPROGS)
@echo make[1]: Entering directory \`$(PWD)/qcsrc/client\'
cd qcsrc/client && $(FTEQCC) $(FTEQCCFLAGS) $(FTEQCCFLAGS_CSPROGS)
-progs.dat: qcsrc/server/*.* qcsrc/common/*.* qcsrc/server/*/*.* qcsrc/server/*/*/*.* qcsrc/warpzonelib/*.*
+FILES_PROGS = qcsrc/server/progs.src $(shell sed '/\.dat/d; s,//.*,,; s,[^ ],qcsrc/server/&,' < qcsrc/server/progs.src)
+progs.dat: $(FILES_PROGS)
@echo make[1]: Entering directory \`$(PWD)/qcsrc/server\'
cd qcsrc/server && $(FTEQCC) $(FTEQCCFLAGS) $(FTEQCCFLAGS_PROGS)
-menu.dat: qcsrc/menu/*.* qcsrc/menu/*/*.* qcsrc/common/*.*
+FILES_MENU = qcsrc/menu/progs.src $(shell sed '/\.dat/d; s,//.*,,; s,[^ ],qcsrc/menu/&,' < qcsrc/menu/progs.src)
+menu.dat: $(FILES_MENU)
@echo make[1]: Entering directory \`$(PWD)/qcsrc/menu\'
cd qcsrc/menu && $(FTEQCC) $(FTEQCCFLAGS) $(FTEQCCFLAGS_MENU)
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)
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"
set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_pickup_ammo_anyway 0
set g_pickup_weapons_anyway 0
set g_pickup_shells 15
+set g_pickup_shells_weapon 15
set g_pickup_shells_max 999
set g_pickup_nails 80
+set g_pickup_nails_weapon 80
set g_pickup_nails_max 999
set g_pickup_rockets 15
+set g_pickup_rockets_weapon 15
set g_pickup_rockets_max 999
set g_pickup_cells 25
+set g_pickup_cells_weapon 25
set g_pickup_cells_max 999
set g_pickup_fuel 25
+set g_pickup_fuel_weapon 25
set g_pickup_fuel_jetpack 50
set g_pickup_fuel_max 999
set g_pickup_armorsmall 5
set g_balance_uzi_bulletconstant 115 // 13.1qu
// }}}
// {{{ mortar
-set g_balance_grenadelauncher_primary2secondary 0
-set g_balance_grenadelauncher_primary_sticky 0
+set g_balance_grenadelauncher_primary_type 0
set g_balance_grenadelauncher_primary_damage 70
set g_balance_grenadelauncher_primary_edgedamage 38
set g_balance_grenadelauncher_primary_force 400
set g_balance_grenadelauncher_primary_animtime 0.3
set g_balance_grenadelauncher_primary_ammo 2
set g_balance_grenadelauncher_primary_health 25
-set g_balance_grenadelauncher_secondary_sticky 0
+set g_balance_grenadelauncher_primary_damageforcescale 4
+set g_balance_grenadelauncher_primary_bouncefactor 0.5
+set g_balance_grenadelauncher_primary_bouncestop 0.075
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+
+set g_balance_grenadelauncher_secondary_type 1
set g_balance_grenadelauncher_secondary_damage 70
set g_balance_grenadelauncher_secondary_edgedamage 38
set g_balance_grenadelauncher_secondary_force 400
set g_balance_grenadelauncher_secondary_damageforcescale 4
set g_balance_grenadelauncher_secondary_bouncefactor 0.5
set g_balance_grenadelauncher_secondary_bouncestop 0.075
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
+// }}}
+// {{{ minelayer // TODO
+set g_balance_minelayer_damage 35
+set g_balance_minelayer_edgedamage 30
+set g_balance_minelayer_force 250
+set g_balance_minelayer_radius 175
+set g_balance_minelayer_proximityradius 150
+set g_balance_minelayer_speed 750
+set g_balance_minelayer_lifetime 60
+set g_balance_minelayer_refire 1.5
+set g_balance_minelayer_animtime 0.4
+set g_balance_minelayer_ammo 5
+set g_balance_minelayer_health 15
+set g_balance_minelayer_limit 4 // 0 disables the limit
+set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate
+set g_balance_minelayer_damageforcescale 0
+set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+set g_balance_minelayer_time 0.5
+set g_balance_minelayer_remote_damage 45
+set g_balance_minelayer_remote_edgedamage 40
+set g_balance_minelayer_remote_radius 200
+set g_balance_minelayer_remote_force 300
// }}}
// {{{ electro
set g_balance_electro_lightning 0
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
set g_balance_nex_primary_damagefalloff_forcehalflife 0
set g_balance_nex_secondary 0
+set g_balance_nex_secondary_charge 0
+set g_balance_nex_secondary_charge_rate 0.1
set g_balance_nex_secondary_damage 100
set g_balance_nex_secondary_force 600
set g_balance_nex_secondary_refire 1.5
set g_balance_nex_secondary_damagefalloff_maxdist 0
set g_balance_nex_secondary_damagefalloff_halflife 0
set g_balance_nex_secondary_damagefalloff_forcehalflife 0
+
+set g_balance_nex_charge 0
+set g_balance_nex_charge_start 0
+set g_balance_nex_charge_rate 0.1
+set g_balance_nex_charge_limit 0.5
+set g_balance_nex_charge_shot_multiplier 0.5
+set g_balance_nex_charge_velocity_rate 0.2
+set g_balance_nex_charge_minspeed 400
+set g_balance_nex_charge_maxspeed 1000
// }}}
// {{{ minstanex
set g_balance_minstanex_refire 1
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 0
+set g_balance_campingrifle_primary_tracer 0
set g_balance_campingrifle_primary_damage 60
set g_balance_campingrifle_primary_headshotaddeddamage 100
set g_balance_campingrifle_primary_spread 0
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_tracer 0
set g_balance_campingrifle_secondary_damage 35
set g_balance_campingrifle_secondary_headshotaddeddamage 15 // 50 damage only on head
set g_balance_campingrifle_secondary_spread 0.008
--- /dev/null
+////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_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+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_weapon 20
+set g_pickup_shells_max 45
+set g_pickup_nails 120
+set g_pickup_nails_weapon 120
+set g_pickup_nails_max 300
+set g_pickup_rockets 25
+set g_pickup_rockets_weapon 25
+set g_pickup_rockets_max 150
+set g_pickup_cells 25
+set g_pickup_cells_weapon 25
+set g_pickup_cells_max 200
+set g_pickup_fuel 25
+set g_pickup_fuel_weapon 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 40
+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 -30
+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 17
+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_primary_type 0
+set g_balance_grenadelauncher_primary_damage 65
+set g_balance_grenadelauncher_primary_edgedamage 35
+set g_balance_grenadelauncher_primary_force 310
+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_primary_damageforcescale 0
+set g_balance_grenadelauncher_primary_bouncefactor 0.7
+set g_balance_grenadelauncher_primary_bouncestop 0.12
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+
+set g_balance_grenadelauncher_secondary_type 1
+set g_balance_grenadelauncher_secondary_damage 65
+set g_balance_grenadelauncher_secondary_edgedamage 35
+set g_balance_grenadelauncher_secondary_force 320
+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
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
+// }}}
+// {{{ minelayer // TODO
+set g_balance_minelayer_damage 35
+set g_balance_minelayer_edgedamage 30
+set g_balance_minelayer_force 250
+set g_balance_minelayer_radius 175
+set g_balance_minelayer_proximityradius 150
+set g_balance_minelayer_speed 750
+set g_balance_minelayer_lifetime 60
+set g_balance_minelayer_refire 1.5
+set g_balance_minelayer_animtime 0.4
+set g_balance_minelayer_ammo 5
+set g_balance_minelayer_health 15
+set g_balance_minelayer_limit 4 // 0 disables the limit
+set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate
+set g_balance_minelayer_damageforcescale 0
+set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+set g_balance_minelayer_time 0.5
+set g_balance_minelayer_remote_damage 45
+set g_balance_minelayer_remote_edgedamage 40
+set g_balance_minelayer_remote_radius 200
+set g_balance_minelayer_remote_force 300
+// }}}
+// {{{ electro
+set g_balance_electro_lightning 0
+set g_balance_electro_primary_damage 55
+set g_balance_electro_primary_edgedamage 5
+set g_balance_electro_primary_force 267
+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.78
+set g_balance_electro_primary_animtime 0.4
+set g_balance_electro_primary_ammo 2
+set g_balance_electro_primary_range 800
+set g_balance_electro_primary_falloff_mindist 255
+set g_balance_electro_primary_falloff_maxdist 850
+set g_balance_electro_primary_falloff_halflifedist 0
+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 23
+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 3
+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 19
+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 3
+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 13
+set g_balance_nex_primary_animtime 0.3
+set g_balance_nex_primary_damage 78
+set g_balance_nex_primary_force 600
+set g_balance_nex_primary_refire 1.505
+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_charge 0
+set g_balance_nex_secondary_charge_rate 0.1
+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
+
+set g_balance_nex_charge 0
+set g_balance_nex_charge_start 0
+set g_balance_nex_charge_rate 0.1
+set g_balance_nex_charge_limit 0.5
+set g_balance_nex_charge_shot_multiplier 0.5
+set g_balance_nex_charge_velocity_rate 0.2
+set g_balance_nex_charge_minspeed 400
+set g_balance_nex_charge_maxspeed 1000
+// }}}
+// {{{ 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 94
+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 2
+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 2
+// }}}
+// {{{ rocketlauncher
+set g_balance_rocketlauncher_damage 65
+set g_balance_rocketlauncher_edgedamage 25
+set g_balance_rocketlauncher_force 360
+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 7
+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 65 // 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 17
+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 3
+
+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 11
+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_primary_tracer 0
+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_tracer 0
+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
set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_pickup_ammo_anyway 0
set g_pickup_weapons_anyway 0
set g_pickup_shells 15
+set g_pickup_shells_weapon 15
set g_pickup_shells_max 999
set g_pickup_nails 80
+set g_pickup_nails_weapon 80
set g_pickup_nails_max 999
set g_pickup_rockets 15
+set g_pickup_rockets_weapon 15
set g_pickup_rockets_max 999
set g_pickup_cells 25
+set g_pickup_cells_weapon 25
set g_pickup_cells_max 999
set g_pickup_fuel 25
+set g_pickup_fuel_weapon 25
set g_pickup_fuel_jetpack 50
set g_pickup_fuel_max 999
set g_pickup_armorsmall 5
set g_balance_uzi_bulletconstant 115 // 13.1qu
// }}}
// {{{ mortar
-set g_balance_grenadelauncher_primary2secondary 0
-set g_balance_grenadelauncher_primary_sticky 0
+set g_balance_grenadelauncher_primary_type 0
set g_balance_grenadelauncher_primary_damage 70
set g_balance_grenadelauncher_primary_edgedamage 38
set g_balance_grenadelauncher_primary_force 400
set g_balance_grenadelauncher_primary_animtime 0.3
set g_balance_grenadelauncher_primary_ammo 2
set g_balance_grenadelauncher_primary_health 25
-set g_balance_grenadelauncher_secondary_sticky 0
+set g_balance_grenadelauncher_primary_damageforcescale 4
+set g_balance_grenadelauncher_primary_bouncefactor 0.5
+set g_balance_grenadelauncher_primary_bouncestop 0.075
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+set g_balance_grenadelauncher_secondary_type 1
set g_balance_grenadelauncher_secondary_damage 70
set g_balance_grenadelauncher_secondary_edgedamage 38
set g_balance_grenadelauncher_secondary_force 400
set g_balance_grenadelauncher_secondary_damageforcescale 4
set g_balance_grenadelauncher_secondary_bouncefactor 0.5
set g_balance_grenadelauncher_secondary_bouncestop 0.075
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
+// }}}
+// {{{ minelayer // TODO
+set g_balance_minelayer_damage 35
+set g_balance_minelayer_edgedamage 30
+set g_balance_minelayer_force 250
+set g_balance_minelayer_radius 175
+set g_balance_minelayer_proximityradius 150
+set g_balance_minelayer_speed 750
+set g_balance_minelayer_lifetime 60
+set g_balance_minelayer_refire 1.5
+set g_balance_minelayer_animtime 0.4
+set g_balance_minelayer_ammo 5
+set g_balance_minelayer_health 15
+set g_balance_minelayer_limit 4 // 0 disables the limit
+set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate
+set g_balance_minelayer_damageforcescale 0
+set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+set g_balance_minelayer_time 0.5
+set g_balance_minelayer_remote_damage 45
+set g_balance_minelayer_remote_edgedamage 40
+set g_balance_minelayer_remote_radius 200
+set g_balance_minelayer_remote_force 300
// }}}
// {{{ electro
set g_balance_electro_lightning 0
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
set g_balance_nex_primary_damagefalloff_forcehalflife 1500
set g_balance_nex_secondary 0
+set g_balance_nex_secondary_charge 0
+set g_balance_nex_secondary_charge_rate 0.1
set g_balance_nex_secondary_damage 90
set g_balance_nex_secondary_force 200
set g_balance_nex_secondary_refire 1.5
set g_balance_nex_secondary_damagefalloff_maxdist 3000
set g_balance_nex_secondary_damagefalloff_halflife 1500
set g_balance_nex_secondary_damagefalloff_forcehalflife 1500
+
+set g_balance_nex_charge 0
+set g_balance_nex_charge_start 0
+set g_balance_nex_charge_rate 0.1
+set g_balance_nex_charge_limit 0.5
+set g_balance_nex_charge_shot_multiplier 0.5
+set g_balance_nex_charge_velocity_rate 0.2
+set g_balance_nex_charge_minspeed 400
+set g_balance_nex_charge_maxspeed 1000
// }}}
// {{{ minstanex
set g_balance_minstanex_refire 1
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_tracer 0
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_burstcost 0.35 // require same cooldown as secondary, note it's smaller than primary refire time
set g_balance_campingrifle_primary_bullethail 0
set g_balance_campingrifle_secondary 1
+set g_balance_campingrifle_secondary_tracer 0
set g_balance_campingrifle_secondary_damage 15
set g_balance_campingrifle_secondary_headshotaddeddamage 25
set g_balance_campingrifle_secondary_spread 0.02
set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_pickup_ammo_anyway 1
set g_pickup_weapons_anyway 1
set g_pickup_shells 30
+set g_pickup_shells_weapon 30
set g_pickup_shells_max 120
set g_pickup_nails 80
+set g_pickup_nails_weapon 80
set g_pickup_nails_max 400
set g_pickup_rockets 30
+set g_pickup_rockets_weapon 30
set g_pickup_rockets_max 120
set g_pickup_cells 50
+set g_pickup_cells_weapon 50
set g_pickup_cells_max 200
set g_pickup_fuel 25
+set g_pickup_fuel_weapon 25
set g_pickup_fuel_jetpack 50
set g_pickup_fuel_max 999
set g_pickup_armorsmall 10
set g_balance_uzi_bulletconstant 115 // 13.1qu
// }}}
// {{{ mortar
-set g_balance_grenadelauncher_primary2secondary 0
-set g_balance_grenadelauncher_primary_sticky 0
+set g_balance_grenadelauncher_primary_type 0
set g_balance_grenadelauncher_primary_damage 50
set g_balance_grenadelauncher_primary_edgedamage 38
set g_balance_grenadelauncher_primary_force 400
set g_balance_grenadelauncher_primary_animtime 0.3
set g_balance_grenadelauncher_primary_ammo 2
set g_balance_grenadelauncher_primary_health 25
-set g_balance_grenadelauncher_secondary_sticky 0
+set g_balance_grenadelauncher_primary_damageforcescale 4
+set g_balance_grenadelauncher_primary_bouncefactor 0.5
+set g_balance_grenadelauncher_primary_bouncestop 0.075
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+
+set g_balance_grenadelauncher_secondary_type 1
set g_balance_grenadelauncher_secondary_damage 60
set g_balance_grenadelauncher_secondary_edgedamage 38
set g_balance_grenadelauncher_secondary_force 400
set g_balance_grenadelauncher_secondary_damageforcescale 4
set g_balance_grenadelauncher_secondary_bouncefactor 0.5
set g_balance_grenadelauncher_secondary_bouncestop 0.075
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 1
+// }}}
+// {{{ minelayer // TODO
+set g_balance_minelayer_damage 35
+set g_balance_minelayer_edgedamage 30
+set g_balance_minelayer_force 250
+set g_balance_minelayer_radius 175
+set g_balance_minelayer_proximityradius 150
+set g_balance_minelayer_speed 750
+set g_balance_minelayer_lifetime 60
+set g_balance_minelayer_refire 1.5
+set g_balance_minelayer_animtime 0.4
+set g_balance_minelayer_ammo 5
+set g_balance_minelayer_health 15
+set g_balance_minelayer_limit 4 // 0 disables the limit
+set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate
+set g_balance_minelayer_damageforcescale 0
+set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+set g_balance_minelayer_time 0.5
+set g_balance_minelayer_remote_damage 45
+set g_balance_minelayer_remote_edgedamage 40
+set g_balance_minelayer_remote_radius 200
+set g_balance_minelayer_remote_force 300
// }}}
// {{{ electro
set g_balance_electro_lightning 0
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
set g_balance_nex_primary_damagefalloff_forcehalflife 1500
set g_balance_nex_secondary 0
+set g_balance_nex_secondary_charge 0
+set g_balance_nex_secondary_charge_rate 0.1
set g_balance_nex_secondary_damage 90
set g_balance_nex_secondary_force 300
set g_balance_nex_secondary_refire 1.5
set g_balance_nex_secondary_damagefalloff_maxdist 3000
set g_balance_nex_secondary_damagefalloff_halflife 1500
set g_balance_nex_secondary_damagefalloff_forcehalflife 1500
+
+set g_balance_nex_charge 0
+set g_balance_nex_charge_start 0
+set g_balance_nex_charge_rate 0.1
+set g_balance_nex_charge_limit 0.5
+set g_balance_nex_charge_shot_multiplier 0.5
+set g_balance_nex_charge_velocity_rate 0.2
+set g_balance_nex_charge_minspeed 400
+set g_balance_nex_charge_maxspeed 1000
// }}}
// {{{ minstanex
set g_balance_minstanex_refire 1
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_tracer 0
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_burstcost 0.35 // require same cooldown as secondary, note it's smaller than primary refire time
set g_balance_campingrifle_primary_bullethail 0
set g_balance_campingrifle_secondary 1
+set g_balance_campingrifle_secondary_tracer 0
set g_balance_campingrifle_secondary_damage 15
set g_balance_campingrifle_secondary_headshotaddeddamage 25
set g_balance_campingrifle_secondary_spread 0.02
set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
set g_pickup_ammo_anyway 1
set g_pickup_weapons_anyway 1
set g_pickup_shells 20
+set g_pickup_shells_weapon 10
set g_pickup_shells_max 45
set g_pickup_nails 120
+set g_pickup_nails_weapon 60
set g_pickup_nails_max 300
set g_pickup_rockets 25
+set g_pickup_rockets_weapon 15
set g_pickup_rockets_max 150
set g_pickup_cells 25
+set g_pickup_cells_weapon 15
set g_pickup_cells_max 200
set g_pickup_fuel 25
+set g_pickup_fuel_weapon 15
set g_pickup_fuel_jetpack 50
set g_pickup_fuel_max 100
set g_pickup_armorsmall 5
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
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
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
// }}}
// {{{ uzi
set g_balance_uzi_first 1
-set g_balance_uzi_first_damage 17
+set g_balance_uzi_first_damage 16
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
+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 115 // 13.1qu
// }}}
// {{{ mortar // TODO
-set g_balance_grenadelauncher_primary2secondary 0
-set g_balance_grenadelauncher_primary_sticky 0
-set g_balance_grenadelauncher_primary_damage 60
+set g_balance_grenadelauncher_primary_type 0
+set g_balance_grenadelauncher_primary_damage 50
set g_balance_grenadelauncher_primary_edgedamage 25
set g_balance_grenadelauncher_primary_force 300
set g_balance_grenadelauncher_primary_radius 100
-set g_balance_grenadelauncher_primary_speed 1400
+set g_balance_grenadelauncher_primary_speed 1200
set g_balance_grenadelauncher_primary_speed_up 225
set g_balance_grenadelauncher_primary_speed_z 0
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
-set g_balance_grenadelauncher_secondary_damage 90
+set g_balance_grenadelauncher_primary_health 80
+set g_balance_grenadelauncher_primary_damageforcescale 0
+set g_balance_grenadelauncher_primary_bouncefactor 0.5
+set g_balance_grenadelauncher_primary_bouncestop 0.12
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+
+set g_balance_grenadelauncher_secondary_type 1
+set g_balance_grenadelauncher_secondary_damage 70
set g_balance_grenadelauncher_secondary_edgedamage 32
set g_balance_grenadelauncher_secondary_force 300
set g_balance_grenadelauncher_secondary_radius 150
-set g_balance_grenadelauncher_secondary_speed 1400
+set g_balance_grenadelauncher_secondary_speed 1200
set g_balance_grenadelauncher_secondary_speed_up 225
set g_balance_grenadelauncher_secondary_speed_z 0
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_lifetime 3
+set g_balance_grenadelauncher_secondary_lifetime2 0.65
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
-set g_balance_grenadelauncher_secondary_bouncefactor 0.7
+set g_balance_grenadelauncher_secondary_bouncefactor 0.5
set g_balance_grenadelauncher_secondary_bouncestop 0.12
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
+// }}}
+// {{{ minelayer // TODO
+set g_balance_minelayer_damage 35
+set g_balance_minelayer_edgedamage 30
+set g_balance_minelayer_force 250
+set g_balance_minelayer_radius 175
+set g_balance_minelayer_proximityradius 150
+set g_balance_minelayer_speed 750
+set g_balance_minelayer_lifetime 60
+set g_balance_minelayer_refire 1.5
+set g_balance_minelayer_animtime 0.4
+set g_balance_minelayer_ammo 5
+set g_balance_minelayer_health 15
+set g_balance_minelayer_limit 4 // 0 disables the limit
+set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate
+set g_balance_minelayer_damageforcescale 0
+set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+set g_balance_minelayer_time 0.5
+set g_balance_minelayer_remote_damage 45
+set g_balance_minelayer_remote_edgedamage 40
+set g_balance_minelayer_remote_radius 200
+set g_balance_minelayer_remote_force 300
// }}}
// {{{ electro // TODO
set g_balance_electro_lightning 1
-set g_balance_electro_primary_damage 90
+set g_balance_electro_primary_damage 85
set g_balance_electro_primary_edgedamage 0
-set g_balance_electro_primary_force 550
+set g_balance_electro_primary_force 425
set g_balance_electro_primary_force_up 125
set g_balance_electro_primary_radius 850
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
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
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
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_refire 1.25
+set g_balance_nex_primary_damage 120
+set g_balance_nex_primary_force 500
+set g_balance_nex_primary_refire 1
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_halflife 1000
+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_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_charge 1
+set g_balance_nex_secondary_charge_rate 0.15
+set g_balance_nex_secondary_damage 0
+set g_balance_nex_secondary_force 0
+set g_balance_nex_secondary_refire 0
+set g_balance_nex_secondary_animtime 0
+set g_balance_nex_secondary_ammo 4
+set g_balance_nex_secondary_damagefalloff_mindist 0
+set g_balance_nex_secondary_damagefalloff_maxdist 0
+set g_balance_nex_secondary_damagefalloff_halflife 0
+set g_balance_nex_secondary_damagefalloff_forcehalflife 0
+
+set g_balance_nex_charge 1
+set g_balance_nex_charge_start 0.2
+set g_balance_nex_charge_rate 0.05
+set g_balance_nex_charge_limit 0.5
+set g_balance_nex_charge_shot_multiplier 0.675
+set g_balance_nex_charge_velocity_rate 0.15
+set g_balance_nex_charge_minspeed 400
+set g_balance_nex_charge_maxspeed 1000
// }}}
// {{{ minstanex
set g_balance_minstanex_refire 1.25
// }}}
// {{{ 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
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
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
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_headshotaddeddamage 50
+set g_balance_campingrifle_primary_tracer 1
+set g_balance_campingrifle_primary_damage 75
+set g_balance_campingrifle_primary_headshotaddeddamage 75
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.8
-set g_balance_campingrifle_primary_animtime 0.8
+set g_balance_campingrifle_primary_refire 1.5
+set g_balance_campingrifle_primary_animtime 1.4
set g_balance_campingrifle_primary_ammo 10
set g_balance_campingrifle_primary_bulletconstant 130 // 56.3qu
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_spread 0.008
-set g_balance_campingrifle_secondary_force 1
-set g_balance_campingrifle_secondary_speed 20000
+set g_balance_campingrifle_secondary_tracer 0
+set g_balance_campingrifle_secondary_damage 50
+set g_balance_campingrifle_secondary_headshotaddeddamage 50 // 50 damage only on head
+set g_balance_campingrifle_secondary_spread 0
+set g_balance_campingrifle_secondary_force 2
+set g_balance_campingrifle_secondary_speed 15000
set g_balance_campingrifle_secondary_lifetime 5
-set g_balance_campingrifle_secondary_refire 0.15
-set g_balance_campingrifle_secondary_animtime 0.1
+set g_balance_campingrifle_secondary_refire 1.5
+set g_balance_campingrifle_secondary_animtime 1.4
set g_balance_campingrifle_secondary_ammo 10
-set g_balance_campingrifle_secondary_bulletconstant 130 // 18.3qu
+set g_balance_campingrifle_secondary_bulletconstant 130 // 10.3qu
set g_balance_campingrifle_secondary_burstcost 0
set g_balance_campingrifle_secondary_bullethail 0 // empty magazine on shot
// }}}
--- /dev/null
+/* 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----<lB[++[Bl<----gJ ",
+" Jx&&&&&|y==y|&&&&&xJ ",
+" AN0$$$$B55B$$$$0NA ",
+" KPu(.$TT$.(uPK ",
+" rSVQXXQVSr ",
+" "};
alias movetoteam_yellow "sv_cmd movetoteam $1 yellow"
alias movetoteam_auto "sv_cmd movetoteam $1 auto"
-// merge lightmaps up to 1024x1024 textures
-// the default of 2048x2048 is too heavy for my rig (SavageX)
-mod_q3bsp_lightmapmergepower 3
+// merge lightmaps up to 2048x2048 textures
+mod_q3bsp_lightmapmergepower 4
// player defaults
_cl_color 102
_cl_name Player
_cl_playermodel models/player/umbra.iqm
_cl_playerskin 0
-crosshair 1
+seta crosshair 3
+seta crosshair_color_red 0.6
+seta crosshair_color_green 0.8
+seta crosshair_color_blue 1
+seta crosshair_alpha 1
+seta crosshair_size 0.35
+seta crosshair_dot 1
+seta crosshair_dot_alpha 1
+seta crosshair_dot_size 1
seta crosshair_per_weapon 0 "when 1, each gun will display a different crosshair"
seta crosshair_color_override 0 "when 1, crosshair_color_* overrides the per-weapon color"
seta crosshair_effect_speed -1 "how fast (in seconds) some crosshair effects should take place, 0 = instant, -1 = 2x weapon switch time"
seta crosshair_grenadelauncher_color_blue 0 "crosshair color blue component to display when wielding the mortar"
seta crosshair_grenadelauncher_color_alpha 1.15 "crosshair alpha value to display when wielding the mortar"
seta crosshair_grenadelauncher_size 0.7 "crosshair size when wielding the mortar"
+seta crosshair_minelayer "" "crosshair to display when wielding the mortar"
+seta crosshair_minelayer_color_red 0.75 "crosshair color red component to display when wielding the mortar"
+seta crosshair_minelayer_color_green 0.75 "crosshair color green component to display when wielding the mortar"
+seta crosshair_minelayer_color_blue 0 "crosshair color blue component to display when wielding the mortar"
+seta crosshair_minelayer_color_alpha 1.15 "crosshair alpha value to display when wielding the mortar"
+seta crosshair_minelayer_size 0.9 "crosshair size when wielding the mortar"
seta crosshair_electro "" "crosshair to display when wielding the electro"
seta crosshair_electro_color_red 0.35 "crosshair color red component to display when wielding the electro"
seta crosshair_electro_color_green 0.5 "crosshair color green component to display when wielding the electro"
seta crosshair_campingrifle_color_blue 0.25 "crosshair color blue component to display when wielding the campingrifle"
seta crosshair_campingrifle_color_alpha 1 "crosshair alpha value to display when wielding the campingrifle"
seta crosshair_campingrifle_size 0.65 "crosshair size when wielding the campingrifle"
-seta crosshair_campingrifle_ring_size 1.5 "bullet counter ring size around campingrifle crosshair, multiple of crosshair_campingrifle_size"
seta crosshair_tuba "" "crosshair to display when wielding the tuba"
seta crosshair_tuba_color_red 0.85 "crosshair color red component to display when wielding the tuba"
seta crosshair_tuba_color_green 0.5 "crosshair color green component to display when wielding the tuba"
seta crosshair_fireball_color_blue 0.2 "crosshair color blue component to display when wielding the fireball"
seta crosshair_fireball_color_alpha 1 "crosshair alpha value to display when wielding the fireball"
seta crosshair_fireball_size 1 "crosshair size when wielding the fireball"
+seta crosshair_ring_size 3 "bullet counter ring size for Rifle, velocity ring for Nex"
+seta crosshair_campingrifle_bulletcounter_alpha 0.15
+seta crosshair_nexvelocity_alpha 0.15
seta cl_reticle_stretch 0 "whether to stretch reticles so they fit the screen (brakes image proportions)"
seta cl_reticle_item_nex 1 "draw aiming recticle for the nex weapon's zoom, 0 disables and values between 0 and 1 change alpha"
seta cl_reticle_item_normal 1 "draw recticle when zooming with the zoom button, 0 disables and values between 0 and 1 change alpha"
seta cl_zoomsensitivity 0 "how zoom changes sensitivity (0 = weakest, 1 = strongest)"
freelook 1
sensitivity 6
-v_gamma 1.125000
+v_gamma 1
viewsize 100
bgmvolume 1
volume 0.5
cl_deathfade 1 // fade screen to dark red when dead, value represents how fast the fade is (higher is faster)
cl_bobcycle 0 // how long the cycle of up/down view movement takes (only works if cl_bob is not 0), default is 0.6
cl_bob 0.01 // how much view moves up/down when moving (does not move if cl_bobcycle is 0, but still enables cl_bobmodel), default is 0.02
+cl_bob2cycle 0 // how long the cycle of left/right view movement takes (only works if cl_bob2 is not 0), default is 0.6
+cl_bob2 0.01 // how much view moves left/right when moving (does not move if cl_bob2cycle is 0), default is 0.01
+cl_bobfall 0.05 "how much the view swings down when falling (influenced by the speed you hit the ground with)"
+cl_bobfallcycle 3 "speed of the bobfall swing"
+cl_bobfallspeed 200 "necessary amount of speed for bob-falling to occur"
cl_bobmodel 1 // whether to have gun model move around on screen when moving (only works if cl_bob is not 0), default is 1
cl_leanmodel 1 // enables weapon leaning effect when looking around
cl_leanmodel_side_speed 0.7 "gun leaning sideways speed"
hostname "Xonotic $g_xonoticversion Server"
set sv_mapchange_delay 5
set minplayers 0 "number of players playing at the same time (if not enough real players are there the remaining slots are filled with bots)"
-sv_cullentities_trace 1
-r_cullentities_trace 1
// restart server if all players hit "ready"-button
set sv_ready_restart 0 "if set to 1 allow a map to be restarted once all players pressed the \"ready\" button'"
seta cl_particles_oldnexbeam 0 "Uses the old v2.3 Nexgun beam instead of the new beam, only works if server allows it (g_allow_oldnexbeam 1)"
set sv_qcweaponanimation 0
-set g_telefrags 1
-set g_telefrags_avoid 0
+set g_telefrags 1 "telefragging, i.e. killing someone who stands in the way of someone who is teleporting"
+set g_telefrags_teamplay 1 "never telefrag team mates"
+set g_telefrags_avoid 1 "when teleporters have a random destination, avoid teleporting to locations where a telefrag would happen"
set g_teleport_maxspeed 0 "maximum speed that a player can keep when going through a teleporter (if a misc_teleporter_dest also has a cap the smallest one of these will be used), 0 = don't limit, -1 = keep no speed"
-set g_respawn_ghosts 0 "if 1 dead bodies become ghosts and float away when the player respawns"
+set g_respawn_ghosts 1 "if 1 dead bodies become ghosts and float away when the player respawns"
set g_respawn_ghosts_speed 5 "the speed with which respawn ghosts float and rotate"
set g_respawn_ghosts_maxtime 6 "maximum amount of time a respawn ghost can last, minimum time is half this value. 0 disables and ghosts fade when the body would"
// use default physics
set sv_friction_on_land 0
-exec physicsNoQWBunny-nexbased.cfg
+exec physicsNoQWBunny-xpmbased.cfg
-set sv_player_viewoffset "0 0 35" "view offset of the player model"
+set sv_player_viewoffset "0 0 42" "view offset of the player model"
set sv_player_mins "-16 -16 -24" "playermodel mins"
set sv_player_maxs "16 16 45" "playermodel maxs"
-set sv_player_crouch_viewoffset "0 0 15" "view offset of the player model when crouched"
+set sv_player_crouch_viewoffset "0 0 20" "view offset of the player model when crouched"
set sv_player_crouch_mins "-16 -16 -24" "mins of a crouched playermodel"
set sv_player_crouch_maxs "16 16 25" "maxs of a crouched playermodel"
set bot_ai_aimskill_offset 0.3 "Amount of error induced to the bots aim"
set bot_ai_aimskill_think 1 "Aiming velocity. Use values below 1 for slower aiming"
set bot_ai_custom_weapon_priority_distances "300 850" "Define close and far distances in any order. Based on the distance to the enemy bots will choose different weapons"
-set bot_ai_custom_weapon_priority_far "minstanex nex campingrifle rocketlauncher grenadelauncher electro hagar hlac crylink laser uzi fireball seeker shotgun tuba" "Desired weapons for far distances ordered by priority"
-set bot_ai_custom_weapon_priority_mid "minstanex rocketlauncher nex fireball seeker grenadelauncher electro uzi campingrifle crylink hlac hagar shotgun laser tuba" "Desired weapons for middle distances ordered by priority"
-set bot_ai_custom_weapon_priority_close "minstanex nex uzi hlac tuba seeker hagar crylink grenadelauncher shotgun electro campingrifle rocketlauncher laser fireball" "Desired weapons for close distances ordered by priority"
+set bot_ai_custom_weapon_priority_far "minstanex nex campingrifle rocketlauncher minelayer grenadelauncher electro hagar hlac crylink laser uzi fireball seeker shotgun tuba" "Desired weapons for far distances ordered by priority"
+set bot_ai_custom_weapon_priority_mid "minstanex rocketlauncher nex fireball seeker minelayer grenadelauncher electro uzi campingrifle crylink hlac hagar shotgun laser tuba" "Desired weapons for middle distances ordered by priority"
+set bot_ai_custom_weapon_priority_close "minstanex nex uzi hlac tuba seeker hagar crylink minelayer grenadelauncher shotgun electro campingrifle rocketlauncher laser fireball" "Desired weapons for close distances ordered by priority"
set bot_ai_weapon_combo 1 "Enable bots to do weapon combos"
set bot_ai_weapon_combo_threshold 0.3 "Try to make a combo N seconds after the last attack"
set bot_ai_friends_aware_pickup_radius "500" "Bots will not pickup items if a team mate is this distance near the item"
set g_norecoil 0 "if set to 1 shooting weapons won't make you crosshair to move upwards (recoil)"
set g_maplist_mostrecent "" "contains the name of the maps that were most recently played"
seta g_maplist_mostrecent_count 3 "number of most recent maps that are blocked from being played again"
-seta g_maplist "accident aggressor aneurysm basement basementctf bleach bloodprison bloodprisonctf bluesky cyberparcour01 darkzone desertfactory dieselpower downer eggandbacon evilspace farewell final_rage nr_piece-o-cake ons-reborn racetrack reslimed ruiner runningman runningman_1on1remix runningmanctf silvercity skyway slimepit soylent starship stormkeep2 strength toxic warfare"
+seta g_maplist "g-23" "the list of maps to be cycled among (is autogenerated if empty)"
seta g_maplist_index 0 "this is used internally for saving position in maplist cycle"
seta g_maplist_selectrandom 0 "if 1, a random map will be chosen as next map - DEPRECATED in favor of g_maplist_shuffle"
seta g_maplist_shuffle 1 "new randomization method: like selectrandom, but avoid playing the same maps in short succession. This works by taking out the first element and inserting it into g_maplist with a bias to the end of the list"
seta g_balance_cloaked_alpha 0.25
set g_playerclip_collisions 1 "0 = disable collision testing against playerclips, might be useful on some defrag maps"
+set g_botclip_collisions 1 "0 = disable collision testing against botclips, might be useful on some defrag maps"
set welcome_message_time 8
set g_deathglow 1.25 "when enabled, players stop glowing after they die (the value specifies glow fading speed)"
+set g_multijump 0 "Number of multiple jumps to allow (jumping again in the air), -1 allows for infinite jumps"
+set g_multijump_add 0 "0 = make the current z velocity equal to jumpvelocity, 1 = add jumpvelocity to the current z velocity"
+set g_multijump_speed -999999 "Minimum vertical speed a player must have in order to jump again"
+
// effects
r_picmipsprites 0 // Xonotic uses sprites that should never be picmipped (team mate, typing, waypoints)
r_picmipworld 1
r_mipskins 1
r_shadow_realtime_world_lightmaps 1
seta r_ambient 4
-cl_decals_fadetime 1
+cl_decals_fadetime 5
cl_decals_time 2
seta cl_gunalign 3 "Gun alignment; 1 = right, 2 = left, 3 = center or right, 4 = center or left"
seta cl_nogibs 0 "reduce number of violence effects, or remove them totally"
seta cl_particlegibs 0 "simpler gibs"
seta cl_gibs_damageforcescale 3.5 "force to push around gibs"
-seta cl_gibs_lifetime 14 "average lifetime of gibs"
+seta cl_gibs_lifetime 5 "average lifetime of gibs"
seta cl_gibs_velocity_scale 1 "gib throw velocity force scale"
seta cl_gibs_velocity_random 1 "gib throw velocity randomness scale"
-seta cl_gibs_velocity_up 0 "extra z velocity for gibs"
+seta cl_gibs_velocity_up 1 "extra z velocity for gibs"
seta cl_gibs_ticrate 0.1 "ticrate for gibs"
seta cl_gibs_sloppy 1 "sloppy gibs, may temporarily penetrate walls"
seta cl_casings 1 "enable or disable bullet casings"
set sv_vote_call 1 "users can call a vote for the above commands"
set sv_vote_master 1 "users can call a vote to become master"
set sv_vote_master_password "" "when set, users can use \"vlogin PASSWORD\" to log in as master"
-set sv_vote_change 0 "set to 1 to allow to change you vote/mind"
+set sv_vote_change 1 "set to 1 to allow to change you vote/mind"
set sv_vote_singlecount 0 "set to 1 to count votes once after timeout or to 0 to count with every vote"
-set sv_vote_timeout 60 "a vote will timeout after this many seconds"
+set sv_vote_timeout 30 "a vote will timeout after this many seconds"
set sv_vote_wait 120 "a player can not call a vote again for this many seconds when his vote was not accepted"
set sv_vote_stop 15 "a player can not call a vote again for this many seconds when he stopped this vote (e.g. to correct it)"
set sv_vote_majority_factor 0.5 "which quotient of the PLAYERS constitute a majority? (try: 0.667, 0.75 when using the above)"
-set sv_vote_simple_majority_factor 0 "which quotient of the VOTERS constitute a majority too? (0 = off, otherwise it must be higher than or equal to sv_vote_majority_factor)"
+set sv_vote_simple_majority_factor 0.667 "which quotient of the VOTERS constitute a majority too? (0 = off, otherwise it must be higher than or equal to sv_vote_majority_factor)"
// when disabled, don't allow game type changes "note: set these two equal to JUST support simple majorities"
set sv_vote_override_mostrecent 0
alias vhelp "cmd vote help"
// singleplayer campaign
set g_campaign 0
+set g_campaign_forceteam 0 "Forces the player to a given team in campaign mode, 1 = red, 2 = blue, 3 = yellow, 4 = pink"
seta g_campaign_name "xonotic25"
set g_campaign_skill 0
set g_campaignxonotic20_index 0
cl_curl_enabled 1
cl_curl_maxspeed 300
sv_curl_defaulturl "http://www.xonotic.com/contentdownload/getmap.php?file="
+set sv_curl_serverpackages_auto 0 "automatically add packs with *.serverpackage files to sv_curl_serverpackages"
set sv_motd ""
set cl_gravity 800 "but ignored anyway"
set g_ban_default_bantime 5400 "90 minutes"
-set g_ban_default_masksize 3 "whole 255.255.255.0 networks (set to 4 for single IPs); when UID support is compiled in, masksize 0 means banning by UID"
+set g_ban_default_masksize 3 "masksize 0 means banning by UID only, 1 means banning by /8 (IPv6: /32) network, 2 means banning by /16 (IPv6: /48) network, 3 means banning by /24 (IPv6: /56) network, 4 means banning by single IP (IPv6: /64 network)"
set g_banned_list "" "format: IP remainingtime IP remainingtime ..."
+set g_banned_list_idmode "1" "when set, the IP banning system always uses the ID over the IP address (so a user in a banned IP range can connect if they have a valid signed ID)"
alias bans "sv_cmd bans"
alias ban "sv_cmd ban $*" // usage: ban address(maybe incomplete, like 1.2.3) bantime(seconds)
alias kickban "sv_cmd kickban $*" // usage: kickban # playerno bantime(seconds) masksize(bytes)
alias +userbind "_userbind_call userbind${1}_press"
alias -userbind "_userbind_call userbind${1}_release"
-seta menu_skin "default"
+seta menu_skin "luminos"
set menu_slowmo 1
seta menu_sounds 0 "enables menu sound effects. 1 enables click sounds, 2 also enables hover sounds"
r_textbrightness 0.2
r_textcontrast 0.8
-r_textshadow 1
+r_textshadow 0
+r_font_postprocess_blur 1
+r_font_postprocess_outline 1
// good settings for these fonts
con_chat 5
// hud variables
set _hud_configure 0 "1 = configure the HUD"
-seta hud_configure_teamcolorforced 1 "1 = force display of team colors in configure mode"
+seta hud_configure_teamcolorforced 0 "1 = force display of team colors in configure mode"
seta hud_configure_checkcollisions 1 "check for collisions against other panels when in hud configure mode"
seta hud_configure_bg_minalpha 0.25 "minimum panel background alpha when in hud configure mode"
seta hud_configure_grid_alpha 0.15 "alpha for visible grid when in configure mode"
// hud cvar descriptions
exec _hud_descriptions.cfg
-// exec the default skin config. remember, NO menu_restart in the deafault cfg (dp segfaults at startup otherwise)
-exec hud_default.cfg
+// exec the default skin config
+// please add any new cvars into the hud_save script in qcsrc/client/hud.qc for consistency
+exec hud_luminos.cfg
// user preference cvars (i.e. shouldn't be adjusted by a skin config)
seta hud_panel_weapons_label 1 "1 = show number of weapon, 2 = show bound key of weapon"
seta hud_panel_weapons_ammo_full_cells 80 "show 100% of the status bar at this ammo count"
seta hud_panel_weapons_ammo_full_rockets 80 "show 100% of the status bar at this ammo count"
seta hud_panel_weapons_ammo_full_fuel 100 "show 100% of the status bar at this ammo count"
+seta hud_panel_weapons_timeout "3" "panel disappears if you don't switch weapon for this amount of seconds"
+seta hud_panel_weapons_timeout_effect "1" "disappearance effect: 0) no effect; 1) panel moves out of screen; 2) panel fades out"
seta hud_panel_notify_time 10 "time that a new entry stays until it fades out"
seta hud_panel_notify_fadetime 3 "fade out time"
seta hud_panel_radar_zoommode 0 "zoom mode: 0 = zoomed by default, 1 = zoomed when +zoom, 2 = always zoomed, 3 = always zoomed out"
alias hud_panel_radar_rotate "toggle hud_panel_radar_rotation 0 1 2 3 4"
-seta hud_panel_engineinfo_framecounter_time 1 "time between framerate display updates, smaller values yield less accuracy"
+seta hud_panel_engineinfo_framecounter_time 0.1 "time between framerate display updates"
seta hud_panel_engineinfo_framecounter_decimals 0 "amount of decimals to show"
seta hud_panel_engineinfo_framecounter_exponentialmovingaverage 1 "use an averaging method for calculating fps instead of counting frametime like engine does"
seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_new_weight 0.1 "weight of latest data point"
seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold 0.5 "threshold for fps change when to update instantly, to make big fps changes update faster"
+seta hud_showbinds 1 "the way to show the keys to press in HUD messages: 0 displays commands, 1 bound keys, 2 both"
+seta hud_showbinds_limit 2 "maximum number of bound keys to show for a command. 0 for unlimited"
+
// scoreboard
seta scoreboard_columns default
seta scoreboard_border_thickness 1 "scoreboard border thickness"
seta scoreboard_accuracy_border_thickness 1 "accuracy stats border thickness"
seta scoreboard_accuracy_doublerows 0 "use two rows instead of one"
-seta scoreboard_accuracy 1 "0 = no weapon accuracy stats panel on scoreboard"
-seta scoreboard_color_bg_r 0 "red color component of the HUD background"
-seta scoreboard_color_bg_g 0.25 "green color component of the HUD background"
-seta scoreboard_color_bg_b 0.17 "blue color component of the HUD background"
-seta scoreboard_color_bg_team 0.5 "team color multiplier of the HUD background"
+seta scoreboard_accuracy 1 "show weapon accuracy stats panel on scoreboard"
+seta scoreboard_color_bg_r 0 "red color component of the scoreboard background"
+seta scoreboard_color_bg_g 0.4 "green color component of the scoreboard background"
+seta scoreboard_color_bg_b 0.6 "blue color component of the scoreboard background"
+seta scoreboard_color_bg_team 0.5 "team color multiplier of the scoreboard background"
seta scoreboard_alpha_bg 0.6 "scoreboard background alpha"
seta scoreboard_alpha_fg 1 "scoreboard foreground alpha"
seta scoreboard_alpha_name 0.9 "alpha of player text in scoreboard list other than self"
seta scoreboard_highlight 1 "enable highlighting for rows and columns in the scoreboard"
seta scoreboard_highlight_alpha 0.10 "highlight alpha value (depends on hud_scoreboard_highlight 1)"
seta scoreboard_highlight_alpha_self 0.25 "self highlight alpha value"
+seta scoreboard_offset_left 0.04 "how many pixels the scoreboard is offset from the left screen edge"
+seta scoreboard_offset_right 0.148 "how many pixels the scoreboard is offset from the right screen edge"
+seta scoreboard_bg_scale 0.25 "scale for the tiled scoreboard background"
// for menu server list (eventually make them have engine support?)
seta menu_slist_showfull 1 "show servers even if they are full and have no slots to join"
set con_completion_vmap map
set con_completion_vnextmap map
set con_completion_vdomap map
+set con_completion_playermodel models/player/*.iqm
// these non-saved engine cvars shall be savedG
seta cl_port $cl_port
cl_netfps 60 // should match
sv_gameplayfix_delayprojectiles 0
sv_gameplayfix_q2airaccelerate 1
+sv_gameplayfix_stepmultipletimes 1
// delay for "kill" to prevent abuse
set g_balance_kill_delay 5
cd remap $g_cdtracks_remaplist
set sv_intermission_cdtrack ""
-set g_cdtracks_dontusebydefault ""
-set menu_cdtrack "ninesix"
+set g_cdtracks_dontusebydefault "rising-of-the-phoenix"
+set menu_cdtrack "rising-of-the-phoenix"
// maxidle (in seconds): kick players idle for more than that amount of time
set sv_maxidle 0
// hud: font size
seta hud_fontsize 11
-seta hud_fontsize_spec 16
-seta scr_centersize 11
+seta scr_centersize 12
seta hud_width 560
// alias hud_font "loadfont user1 ${1},gfx/fallback ${2-}; loadfont user2 ${1}-big ${2-}; scoreboard_columns_set"
alias sbar_font "set _requested_sbar_font \"${*}\""
alias allready "sv_cmd allready"
-seta cl_weaponpriority "minstanex rocketlauncher nex grenadelauncher fireball hlac hagar seeker crylink campingrifle uzi electro tuba shotgun laser hook porto" "weapon priority list"
+seta cl_weaponpriority "minstanex rocketlauncher nex minelayer grenadelauncher fireball hlac hagar seeker crylink campingrifle uzi electro tuba shotgun laser hook porto" "weapon priority list"
seta cl_weaponpriority_useforcycling 0 "when set, weapon cycling by the mouse wheel makes use of the weapon priority list (the special value 2 uses the weapon ID list for cycling)"
seta cl_weaponpriority0 "rocketlauncher grenadelauncher hagar seeker fireball" "use impulse 200 for prev gun from this list, 210 for best gun, 220 for next gun. Default value: explosives"
seta cl_weaponpriority1 "minstanex nex crylink hlac electro laser" "use impulse 201 for prev gun from this list, 211 for best gun, 221 for next gun. Default value: energy"
seta cl_weaponpriority2 "minstanex nex campingrifle" "use impulse 202 for prev gun from this list, 212 for best gun, 222 for next gun. Default value: hitscan exact"
seta cl_weaponpriority3 "minstanex nex campingrifle uzi shotgun" "use impulse 203 for prev gun from this list, 213 for best gun, 223 for next gun. Default value: hitscan all"
-seta cl_weaponpriority4 "grenadelauncher hlac hagar crylink seeker shotgun" "use impulse 204 for prev gun from this list, 214 for best gun, 224 for next gun. Default value: spam weapons"
+seta cl_weaponpriority4 "minelayer grenadelauncher hlac hagar crylink seeker shotgun" "use impulse 204 for prev gun from this list, 214 for best gun, 224 for next gun. Default value: spam weapons"
seta cl_weaponpriority5 "laser hook porto" "use impulse 205 for prev gun from this list, 215 for best gun, 225 for next gun. Default value: weapons for moving"
seta cl_weaponpriority6 "" "use impulse 206 for prev gun from this list, 216 for best gun, 226 for next gun"
seta cl_weaponpriority7 "" "use impulse 207 for prev gun from this list, 217 for best gun, 227 for next gun"
set g_weaponreplace_laser ""
set g_weaponreplace_shotgun ""
set g_weaponreplace_uzi ""
+set g_weaponreplace_minelayer ""
set g_weaponreplace_grenadelauncher ""
set g_weaponreplace_electro ""
set g_weaponreplace_crylink ""
scr_conscroll_x -0.1
scr_conscroll_y -0.3
+scr_loadingscreen_background 0
+scr_loadingscreen_barcolor "0 0.5 1"
+scr_loadingscreen_barheight 20
+scr_loadingscreen_count 1
+
// DP cannot properly detect this, so rather turn off the detection
r_texture_dds_load_dxt1_noalpha 1
+
+// particles optimization
+r_drawparticles_nearclip_min 8
+r_drawparticles_nearclip_max 16
+
+// sv_cullentities_trace is 1, so the client doesn't have to
+sv_cullentities_trace 1
+r_cullentities_trace 0
+
+// less "lagging" of other players, but also less PL tolerant... let's try this
+sv_clmovement_inputtimeout 0.05
+
+// exact gloss looks better, e.g. on g-23
+r_shadow_glossexact 1
+
+// use fake light if map has no lightmaps
+r_fakelight 1
+
+// strength sound settings
+set sv_strengthsound_antispam_time 0.1 "minimum distance of strength sounds"
+set sv_strengthsound_antispam_refire_threshold 0.04 "apply minimum distance only if refire of the gun is smaller than this"
+
+// equalize looks better than fullbright
+r_equalize_entities_fullbright 1
type static
color 0x202020 0x404040
size 2 2
-sizeincrease 2
-alpha 256 256 512
+sizeincrease 0.2
+alpha 256 256 256
airfriction -4
velocityjitter 4 4 4
type smoke
tex 62 62
color 0x404040 0x808080
size 1 1
-alpha 256 256 256
+alpha 256 256 128
gravity -0.125
bounce 1.5
liquidfriction 4
effect electro_lightning
count 300
type spark
-color 0x501860 0x501860 // 0x202020 0x404040
+// color 0x501860 0x501860 // 0x202020 0x404040
+color 0x2030FF 0x80C0FF
tex 65 65
size 6 6
alpha 100 206 1724
--- /dev/null
+title Luminos
+author sev
+
+// Colors: 'Red Green Blue'
+// Suffixes: Clicked (_c), Disabled (_d), Focused (_f), Normal (_n)
+
+// Background layer scaling:
+// Crop (c), Letterbox (l), Height (h), Width (w), Stretch (s)
+// Background layer positioning:
+// Top Left (7), Top Center (8) Top Right (9)
+// Middle Left (4), Middle Center (5) Middle Right (6)
+// Bottom Left (1), Bottom Center (2) Bottom Right (3)
+// ALIGN_BACKGROUND(_INGAME) spspsp, s=Scale p=Position
+
+//------------------------------------------------------------------------------
+// Structure (e.g. positions, sizes, margins)
+//------------------------------------------------------------------------------
+// item: color picker
+// uses "colorpicker" images
+MARGIN_COLORPICKER '0 0 0'
+
+// item: dialog
+// uses "border" images
+// uses "closebutton" images
+MARGIN_TOP 8
+MARGIN_BOTTOM 8
+MARGIN_LEFT 8
+MARGIN_RIGHT 8
+MARGIN_COLUMNS 4
+MARGIN_ROWS 4
+HEIGHT_DIALOGBORDER 1
+
+// font sizes (used for everything)
+FONTSIZE_NORMAL 12
+HEIGHT_NORMAL 1.5
+FONTSIZE_TITLE 16
+HEIGHT_TITLE 1.5
+HEIGHT_ZOOMEDTITLE -1
+
+// general
+// uses "background" images
+// uses "background_ingame" images
+ALIGN_BACKGROUND c5h5
+ALIGN_BACKGROUND_INGAME c5h5
+ALPHA_BACKGROUND_INGAME 1
+ALPHA_DISABLED 0.2
+ALPHA_BEHIND 0.5
+ALPHA_TEXT 0.7
+
+// mouse
+// uses "cursor" images
+SIZE_CURSOR '32 32 0'
+OFFSET_CURSOR '0.25 0.125 0'
+ALPHA_CURSOR_INTRO 0
+
+// nexposee positions of windows (they are the scale transformation
+// centers, NOT the actual positions of the windows!)
+POSITION_DIALOG_MULTIPLAYER '0.9 0.4 0'
+POSITION_DIALOG_SINGLEPLAYER '0.15 0.4 0'
+POSITION_DIALOG_SETTINGS '0.5 1 0'
+POSITION_DIALOG_CREDITS '-0.05 1.2 0'
+POSITION_DIALOG_QUIT '1.05 1.2 0'
+
+// tooltips
+// uses "tooltip" images
+MARGIN_TOOLTIP '8 8 0'
+BORDER_TOOLTIP '16 16 0'
+FONTSIZE_TOOLTIP 12
+ALPHA_TOOLTIP 0.7
+WIDTH_TOOLTIP 0.3
+AVOID_TOOLTIP '8 8 0'
+
+//------------------------------------------------------------------------------
+// Colors (e.g. font colors, field colors)
+//------------------------------------------------------------------------------
+// item: campaign
+ALPHA_CAMPAIGN_SELECTABLE 0.8
+COLOR_CAMPAIGN_SELECTABLE '1 1 1'
+ALPHA_CAMPAIGN_CURRENT 1
+COLOR_CAMPAIGN_CURRENT '1 1 1'
+ALPHA_CAMPAIGN_FUTURE 0.2
+COLOR_CAMPAIGN_FUTURE '1 1 1'
+ALPHA_CAMPAIGN_DESCRIPTION 0.7
+
+// item: credits list
+COLOR_CREDITS_TITLE '1 0.4375 0'
+ALPHA_CREDITS_TITLE 1
+COLOR_CREDITS_FUNCTION '0 0.25 0.5'
+ALPHA_CREDITS_FUNCTION 1
+COLOR_CREDITS_PERSON '0.6875 0.84375 1'
+ALPHA_CREDITS_PERSON 1
+ROWS_CREDITS 20
+WIDTH_CREDITS 0.5
+
+// item: cvar list
+ALPHA_CVARLIST_SAVED 1
+ALPHA_CVARLIST_TEMPORARY 0.7
+COLOR_CVARLIST_CHANGED '1 0 0'
+COLOR_CVARLIST_REVERTBUTTON '1 0 0'
+COLOR_CVARLIST_UNCHANGED '1 1 1'
+
+// item: list box
+COLOR_LISTBOX_SELECTED '1 0.4375 0'
+ALPHA_LISTBOX_SELECTED 1
+COLOR_LISTBOX_WAITING '1 1 1'
+ALPHA_LISTBOX_WAITING 0.5
+
+// item: map list
+COLOR_MAPLIST_TITLE '1 1 1'
+COLOR_MAPLIST_AUTHOR '0.6875 0.84375 1'
+COLOR_MAPLIST_INCLUDEDBG '0 0.1875 0.375'
+ALPHA_MAPLIST_INCLUDEDFG 1
+ALPHA_MAPLIST_INCLUDEDBG 0.375
+ALPHA_MAPLIST_NOTINCLUDEDFG 0.25
+
+// item: nexposee
+ALPHAS_MAINMENU '0.8 0.9 1'
+
+// item: player model
+COLOR_MODELTITLE '1 1 1'
+ALPHA_MODELTITLE 1
+
+// item: server info
+COLOR_SERVERINFO_NAME '1 1 1'
+COLOR_SERVERINFO_IP '1 0.4375 0'
+
+// item: server list
+ALPHA_SERVERLIST_FULL 0.4
+ALPHA_SERVERLIST_EMPTY 0.7
+COLOR_SERVERLIST_LOWPING '0 1 0'
+COLOR_SERVERLIST_MEDPING '1 0.75 0'
+COLOR_SERVERLIST_HIGHPING '1 0 0'
+ALPHA_SERVERLIST_HIGHPING 0.4
+ALPHA_SERVERLIST_FAVORITE 0.8
+COLOR_SERVERLIST_FAVORITE '1 1 1'
+
+// item: skin list
+COLOR_SKINLIST_TITLE '1 1 1'
+COLOR_SKINLIST_AUTHOR '0.6875 0.84375 1'
+
+//------------------------------------------------------------------------------
+// Images (colors multiplied to images)
+//------------------------------------------------------------------------------
+// item: button
+// uses "button" images
+// uses "buttongray" images
+// uses "bigbutton" images
+// uses "bigbuttongray" images
+COLOR_BUTTON_N '1 1 1'
+COLOR_BUTTON_C '1 1 1'
+COLOR_BUTTON_F '1 1 1'
+COLOR_BUTTON_D '1 1 1'
+
+// item: checkbox
+// uses "checkbox" images
+COLOR_CHECKBOX_N '1 1 1'
+COLOR_CHECKBOX_C '1 1 1'
+COLOR_CHECKBOX_F '1 1 1'
+COLOR_CHECKBOX_D '1 1 1'
+
+// item: crosshair button
+// uses "crosshairbutton" images
+
+// dialog background colors
+// uses "border" images
+COLOR_DIALOG_MULTIPLAYER '1 1 1'
+COLOR_DIALOG_SETTINGS '1 1 1'
+COLOR_DIALOG_TEAMSELECT '1 1 1'
+COLOR_DIALOG_QUIT '1 1 1'
+COLOR_DIALOG_ADVANCED '1 1 1'
+COLOR_DIALOG_MUTATORS '1 1 1'
+COLOR_DIALOG_MAPINFO '1 1 1'
+COLOR_DIALOG_USERBIND '1 1 1'
+COLOR_DIALOG_SINGLEPLAYER '1 1 1'
+COLOR_DIALOG_CREDITS '1 1 1'
+COLOR_DIALOG_WEAPONS '1 1 1'
+COLOR_DIALOG_RADAR '1 1 1'
+COLOR_DIALOG_SERVERINFO '1 1 1'
+COLOR_DIALOG_CVARS '1 0 0'
+
+// item: input box
+// uses "inputbox" images
+COLOR_INPUTBOX_N '1 1 1'
+COLOR_INPUTBOX_F '1 1 1'
+MARGIN_INPUTBOX_CHARS 1
+
+// item: key grabber
+COLOR_KEYGRABBER_TITLES '1 1 1'
+ALPHA_KEYGRABBER_TITLES 1
+COLOR_KEYGRABBER_KEYS '1 1 1'
+ALPHA_KEYGRABBER_KEYS 0.7
+
+// item: player color button
+// uses "colorbutton" images
+// uses "color" images
+
+// item: player name editor
+// uses "charmap" images
+// uses "charmapbutton" images
+
+// item: radio button
+// uses "radiobutton" images
+COLOR_RADIOBUTTON_N '1 1 1'
+COLOR_RADIOBUTTON_C '1 1 1'
+COLOR_RADIOBUTTON_F '1 1 1'
+COLOR_RADIOBUTTON_D '1 1 1'
+
+// item: scrollbar
+// uses "scrollbar" images
+COLOR_SCROLLBAR_N '1 1 1'
+COLOR_SCROLLBAR_C '1 1 1'
+COLOR_SCROLLBAR_F '1 1 1'
+COLOR_SCROLLBAR_S '1 1 1'
+WIDTH_SCROLLBAR 16
+
+// item: slider
+// uses "slider" images
+COLOR_SLIDER_N '1 1 1'
+COLOR_SLIDER_C '1 1 1'
+COLOR_SLIDER_F '1 1 1'
+COLOR_SLIDER_D '1 1 1'
+COLOR_SLIDER_S '1 1 1'
+WIDTH_SLIDERTEXT 0.333333333333
+TOLERANCE_SLIDER '0.2 2 0'
+++ /dev/null
-seta hud_skin "luminos"
-seta hud_panel_bg "border"
-seta hud_panel_bg_color "0.875 0.375 0"
-seta hud_panel_bg_color_team "1"
-seta hud_panel_bg_alpha "1"
-seta hud_panel_bg_border "6"
-seta hud_panel_bg_padding "2"
-seta hud_panel_fg_alpha "1"
-
-seta hud_dock "dock"
-seta hud_dock_color "0 0.1875 0.4375"
-seta hud_dock_color_team "0.600000"
-seta hud_dock_alpha "1"
-
-seta hud_progressbar_alpha "0.500000"
-seta hud_progressbar_strength_color "0 0 0.6"
-seta hud_progressbar_shield_color "0.6 0 0.6"
-seta hud_progressbar_health_color "0.6 0 0"
-seta hud_progressbar_armor_color "0 0.6 0"
-seta hud_progressbar_fuel_color "0.6 0.6 0"
-seta hud_progressbar_nexball_color "0.7 0.1 0"
-
-seta _hud_panelorder "11 0 9 2 10 14 12 6 3 13 4 8 7 1 5 "
-
-seta hud_configure_grid "1"
-seta hud_configure_grid_xsize "0.005000"
-seta hud_configure_grid_ysize "0.005000"
-
-seta hud_panel_weapons 1
-seta hud_panel_weapons_pos "0.915000 0.085000"
-seta hud_panel_weapons_size "0.060000 0.635000"
-seta hud_panel_weapons_bg ""
-seta hud_panel_weapons_bg_color ""
-seta hud_panel_weapons_bg_color_team ""
-seta hud_panel_weapons_bg_alpha ""
-seta hud_panel_weapons_bg_border ""
-seta hud_panel_weapons_bg_padding ""
-seta hud_panel_weapons_complainbubble "1"
-seta hud_panel_weapons_complainbubble_padding "-10"
-seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
-seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
-seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
-seta hud_panel_weapons_ammo_color "0 1 0"
-seta hud_panel_weapons_ammo_alpha "1"
-seta hud_panel_weapons_aspect "2"
-
-seta hud_panel_ammo 1
-seta hud_panel_ammo_pos "0.190000 0.925000"
-seta hud_panel_ammo_size "0.095000 0.060000"
-seta hud_panel_ammo_bg ""
-seta hud_panel_ammo_bg_color ""
-seta hud_panel_ammo_bg_color_team ""
-seta hud_panel_ammo_bg_alpha ""
-seta hud_panel_ammo_bg_border ""
-seta hud_panel_ammo_bg_padding ""
-seta hud_panel_ammo_onlycurrent "1"
-seta hud_panel_ammo_iconalign "0"
-
-seta hud_panel_powerups 1
-seta hud_panel_powerups_pos "0.365000 0.015000"
-seta hud_panel_powerups_size "0.262500 0.048047"
-seta hud_panel_powerups_bg ""
-seta hud_panel_powerups_bg_color ""
-seta hud_panel_powerups_bg_color_team "1"
-seta hud_panel_powerups_bg_alpha ""
-seta hud_panel_powerups_bg_border ""
-seta hud_panel_powerups_bg_padding ""
-seta hud_panel_powerups_flip "1"
-seta hud_panel_powerups_iconalign "4"
-seta hud_panel_powerups_baralign "4"
-seta hud_panel_powerups_progressbar "1"
-
-seta hud_panel_healtharmor 1
-seta hud_panel_healtharmor_pos "0.305000 0.925000"
-seta hud_panel_healtharmor_size "0.315000 0.060000"
-seta hud_panel_healtharmor_bg ""
-seta hud_panel_healtharmor_bg_color ""
-seta hud_panel_healtharmor_bg_color_team "1"
-seta hud_panel_healtharmor_bg_alpha "1"
-seta hud_panel_healtharmor_bg_border ""
-seta hud_panel_healtharmor_bg_padding ""
-seta hud_panel_healtharmor_flip "0
-seta hud_panel_healtharmor_iconalign "4"
-seta hud_panel_healtharmor_baralign "4"
-seta hud_panel_healtharmor_progressbar "1"
-
-seta hud_panel_notify 1
-seta hud_panel_notify_pos "0.700000 0.740000"
-seta hud_panel_notify_size "0.280000 0.180000"
-seta hud_panel_notify_bg ""
-seta hud_panel_notify_bg_color ""
-seta hud_panel_notify_bg_color_team ""
-seta hud_panel_notify_bg_alpha "0"
-seta hud_panel_notify_bg_border ""
-seta hud_panel_notify_bg_padding ""
-seta hud_panel_notify_flip "0"
-seta hud_panel_notify_print "0"
-
-seta hud_panel_timer 1
-seta hud_panel_timer_pos "0.880000 0.012070"
-seta hud_panel_timer_size "0.100000 0.032520"
-seta hud_panel_timer_bg ""
-seta hud_panel_timer_bg_color ""
-seta hud_panel_timer_bg_color_team ""
-seta hud_panel_timer_bg_alpha ""
-seta hud_panel_timer_bg_border ""
-seta hud_panel_timer_bg_padding "0"
-
-seta hud_panel_radar 1
-seta hud_panel_radar_pos "0.025000 0.025000"
-seta hud_panel_radar_size "0.180000 0.220000"
-seta hud_panel_radar_bg ""
-seta hud_panel_radar_bg_color ""
-seta hud_panel_radar_bg_color_team ""
-seta hud_panel_radar_bg_alpha ""
-seta hud_panel_radar_bg_border ""
-seta hud_panel_radar_bg_padding "-3"
-seta hud_panel_radar_foreground_alpha "0.800000"
-
-seta hud_panel_score 1
-seta hud_panel_score_pos "0.025000 0.925000"
-seta hud_panel_score_size "0.145000 0.060000"
-seta hud_panel_score_bg ""
-seta hud_panel_score_bg_color ""
-seta hud_panel_score_bg_color_team ""
-seta hud_panel_score_bg_alpha ""
-seta hud_panel_score_bg_border ""
-seta hud_panel_score_bg_padding ""
-
-seta hud_panel_racetimer 1
-seta hud_panel_racetimer_pos "0.355000 0.205000"
-seta hud_panel_racetimer_size "0.280000 0.093333"
-seta hud_panel_racetimer_bg ""
-seta hud_panel_racetimer_bg_color ""
-seta hud_panel_racetimer_bg_color_team ""
-seta hud_panel_racetimer_bg_alpha "0"
-seta hud_panel_racetimer_bg_border ""
-seta hud_panel_racetimer_bg_padding ""
-
-seta hud_panel_vote 1
-seta hud_panel_vote_pos "0.025000 0.660000"
-seta hud_panel_vote_size "0.264218 0.102462"
-seta hud_panel_vote_bg ""
-seta hud_panel_vote_bg_color ""
-seta hud_panel_vote_bg_color_team ""
-seta hud_panel_vote_bg_alpha ""
-seta hud_panel_vote_bg_border ""
-seta hud_panel_vote_bg_padding ""
-seta hud_panel_vote_alreadyvoted_alpha "0.750000"
-
-seta hud_panel_modicons 1
-seta hud_panel_modicons_pos "0.040000 0.270000"
-seta hud_panel_modicons_size "0.084766 0.199903"
-seta hud_panel_modicons_bg ""
-seta hud_panel_modicons_bg_color ""
-seta hud_panel_modicons_bg_color_team ""
-seta hud_panel_modicons_bg_alpha ""
-seta hud_panel_modicons_bg_border ""
-seta hud_panel_modicons_bg_padding ""
-
-seta hud_panel_pressedkeys 1
-seta hud_panel_pressedkeys_pos "0.410000 0.545000"
-seta hud_panel_pressedkeys_size "0.177656 0.120531"
-seta hud_panel_pressedkeys_bg ""
-seta hud_panel_pressedkeys_bg_color ""
-seta hud_panel_pressedkeys_bg_color_team "1"
-seta hud_panel_pressedkeys_bg_alpha "0"
-seta hud_panel_pressedkeys_bg_border ""
-seta hud_panel_pressedkeys_bg_padding ""
-seta hud_panel_pressedkeys_aspect "1.600000"
-
-seta hud_panel_chat 1
-seta hud_panel_chat_pos "0.020000 0.775000"
-seta hud_panel_chat_size "0.627968 0.112696"
-seta hud_panel_chat_bg ""
-seta hud_panel_chat_bg_color ""
-seta hud_panel_chat_bg_color_team ""
-seta hud_panel_chat_bg_alpha "0"
-seta hud_panel_chat_bg_border ""
-seta hud_panel_chat_bg_padding ""
-
-seta hud_panel_engineinfo 1
-seta hud_panel_engineinfo_pos "0.860000 0.954667"
-seta hud_panel_engineinfo_size "0.125000 0.035000"
-seta hud_panel_engineinfo_bg ""
-seta hud_panel_engineinfo_bg_color ""
-seta hud_panel_engineinfo_bg_color_team ""
-seta hud_panel_engineinfo_bg_alpha "0"
-seta hud_panel_engineinfo_bg_border ""
-seta hud_panel_engineinfo_bg_padding ""
-
-seta hud_panel_infomessages 1
-seta hud_panel_infomessages_pos "0.340000 0.350000"
-seta hud_panel_infomessages_size "0.320000 0.085000"
-seta hud_panel_infomessages_bg ""
-seta hud_panel_infomessages_bg_color ""
-seta hud_panel_infomessages_bg_color_team ""
-seta hud_panel_infomessages_bg_alpha "0"
-seta hud_panel_infomessages_bg_border ""
-seta hud_panel_infomessages_bg_padding ""
--- /dev/null
+seta hud_skin "luminos"
+seta hud_panel_bg "border_default"
+seta hud_panel_bg_color "1 0.4375 0"
+seta hud_panel_bg_color_team "0"
+seta hud_panel_bg_alpha "1"
+seta hud_panel_bg_border "8"
+seta hud_panel_bg_padding "2"
+seta hud_panel_fg_alpha "1"
+
+seta hud_dock "dock"
+seta hud_dock_color "0 0.1875 0.40625"
+seta hud_dock_color_team "0.700000"
+seta hud_dock_alpha "1"
+
+seta hud_progressbar_alpha "0.500000"
+seta hud_progressbar_strength_color "0 0 0.6"
+seta hud_progressbar_shield_color "0.6 0 0.6"
+seta hud_progressbar_health_color "0.6 0 0"
+seta hud_progressbar_armor_color "0 0.6 0"
+seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_nexball_color "0.7 0.1 0"
+
+seta _hud_panelorder "10 9 6 8 14 5 0 4 13 2 7 1 3 11 12 "
+
+seta hud_configure_grid "1"
+seta hud_configure_grid_xsize "0.010000"
+seta hud_configure_grid_ysize "0.010000"
+
+seta scr_centerpos "0.25"
+
+seta hud_panel_weapons 1
+seta hud_panel_weapons_pos "0.920000 0.090000"
+seta hud_panel_weapons_size "0.060000 0.630000"
+seta hud_panel_weapons_bg ""
+seta hud_panel_weapons_bg_color ""
+seta hud_panel_weapons_bg_color_team ""
+seta hud_panel_weapons_bg_alpha ""
+seta hud_panel_weapons_bg_border ""
+seta hud_panel_weapons_bg_padding ""
+seta hud_panel_weapons_complainbubble "1"
+seta hud_panel_weapons_complainbubble_padding "-10"
+seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
+seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
+seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
+seta hud_panel_weapons_ammo_color "0 1 0"
+seta hud_panel_weapons_ammo_alpha "1"
+seta hud_panel_weapons_aspect "2"
+
+seta hud_panel_ammo 1
+seta hud_panel_ammo_pos "0.190000 0.920000"
+seta hud_panel_ammo_size "0.120000 0.070000"
+seta hud_panel_ammo_bg ""
+seta hud_panel_ammo_bg_color ""
+seta hud_panel_ammo_bg_color_team ""
+seta hud_panel_ammo_bg_alpha ""
+seta hud_panel_ammo_bg_border ""
+seta hud_panel_ammo_bg_padding ""
+seta hud_panel_ammo_onlycurrent "0"
+seta hud_panel_ammo_iconalign "0"
+
+seta hud_panel_powerups 1
+seta hud_panel_powerups_pos "0.660000 0.940000"
+seta hud_panel_powerups_size "0.330000 0.060000"
+seta hud_panel_powerups_bg "0"
+seta hud_panel_powerups_bg_color ""
+seta hud_panel_powerups_bg_color_team ""
+seta hud_panel_powerups_bg_alpha ""
+seta hud_panel_powerups_bg_border ""
+seta hud_panel_powerups_bg_padding ""
+seta hud_panel_powerups_flip "1"
+seta hud_panel_powerups_iconalign "4"
+seta hud_panel_powerups_baralign "4"
+seta hud_panel_powerups_progressbar "1"
+
+seta hud_panel_healtharmor 1
+seta hud_panel_healtharmor_pos "0.330000 0.920000"
+seta hud_panel_healtharmor_size "0.310000 0.070000"
+seta hud_panel_healtharmor_bg ""
+seta hud_panel_healtharmor_bg_color ""
+seta hud_panel_healtharmor_bg_color_team ""
+seta hud_panel_healtharmor_bg_alpha ""
+seta hud_panel_healtharmor_bg_border ""
+seta hud_panel_healtharmor_bg_padding ""
+seta hud_panel_healtharmor_flip "0
+seta hud_panel_healtharmor_iconalign "4"
+seta hud_panel_healtharmor_baralign "4"
+seta hud_panel_healtharmor_progressbar "1"
+
+seta hud_panel_notify 1
+seta hud_panel_notify_pos "0.660000 0.730000"
+seta hud_panel_notify_size "0.320000 0.190000"
+seta hud_panel_notify_bg "0"
+seta hud_panel_notify_bg_color ""
+seta hud_panel_notify_bg_color_team ""
+seta hud_panel_notify_bg_alpha ""
+seta hud_panel_notify_bg_border ""
+seta hud_panel_notify_bg_padding ""
+seta hud_panel_notify_flip "0"
+seta hud_panel_notify_print "1"
+
+seta hud_panel_timer 1
+seta hud_panel_timer_pos "0.870000 0"
+seta hud_panel_timer_size "0.130000 0.060000"
+seta hud_panel_timer_bg "0"
+seta hud_panel_timer_bg_color ""
+seta hud_panel_timer_bg_color_team ""
+seta hud_panel_timer_bg_alpha ""
+seta hud_panel_timer_bg_border ""
+seta hud_panel_timer_bg_padding "0"
+
+seta hud_panel_radar 1
+seta hud_panel_radar_pos "0.030000 0.020000"
+seta hud_panel_radar_size "0.170000 0.220000"
+seta hud_panel_radar_bg ""
+seta hud_panel_radar_bg_color ""
+seta hud_panel_radar_bg_color_team ""
+seta hud_panel_radar_bg_alpha ""
+seta hud_panel_radar_bg_border ""
+seta hud_panel_radar_bg_padding "-3"
+seta hud_panel_radar_foreground_alpha "0.800000"
+
+seta hud_panel_score 1
+seta hud_panel_score_pos "0.020000 0.920000"
+seta hud_panel_score_size "0.150000 0.070000"
+seta hud_panel_score_bg ""
+seta hud_panel_score_bg_color ""
+seta hud_panel_score_bg_color_team ""
+seta hud_panel_score_bg_alpha ""
+seta hud_panel_score_bg_border ""
+seta hud_panel_score_bg_padding ""
+
+seta hud_panel_racetimer 1
+seta hud_panel_racetimer_pos "0.360000 0.090000"
+seta hud_panel_racetimer_size "0.280000 0.090000"
+seta hud_panel_racetimer_bg "0"
+seta hud_panel_racetimer_bg_color ""
+seta hud_panel_racetimer_bg_color_team ""
+seta hud_panel_racetimer_bg_alpha ""
+seta hud_panel_racetimer_bg_border ""
+seta hud_panel_racetimer_bg_padding ""
+
+seta hud_panel_vote 1
+seta hud_panel_vote_pos "0.020000 0.650000"
+seta hud_panel_vote_size "0.230000 0.110000"
+seta hud_panel_vote_bg ""
+seta hud_panel_vote_bg_color ""
+seta hud_panel_vote_bg_color_team ""
+seta hud_panel_vote_bg_alpha ""
+seta hud_panel_vote_bg_border ""
+seta hud_panel_vote_bg_padding ""
+seta hud_panel_vote_alreadyvoted_alpha "0.800000"
+
+seta hud_panel_modicons 1
+seta hud_panel_modicons_pos "0.040000 0.270000"
+seta hud_panel_modicons_size "0.080000 0.200000"
+seta hud_panel_modicons_bg ""
+seta hud_panel_modicons_bg_color ""
+seta hud_panel_modicons_bg_color_team ""
+seta hud_panel_modicons_bg_alpha ""
+seta hud_panel_modicons_bg_border ""
+seta hud_panel_modicons_bg_padding ""
+
+seta hud_panel_pressedkeys 1
+seta hud_panel_pressedkeys_pos "0.410000 0.710000"
+seta hud_panel_pressedkeys_size "0.180000 0.130000"
+seta hud_panel_pressedkeys_bg "0"
+seta hud_panel_pressedkeys_bg_color ""
+seta hud_panel_pressedkeys_bg_color_team ""
+seta hud_panel_pressedkeys_bg_alpha ""
+seta hud_panel_pressedkeys_bg_border ""
+seta hud_panel_pressedkeys_bg_padding ""
+seta hud_panel_pressedkeys_aspect "1.600000"
+
+seta hud_panel_chat 1
+seta hud_panel_chat_pos "0.020000 0.780000"
+seta hud_panel_chat_size "0.630000 0.110000"
+seta hud_panel_chat_bg "0"
+seta hud_panel_chat_bg_color ""
+seta hud_panel_chat_bg_color_team ""
+seta hud_panel_chat_bg_alpha ""
+seta hud_panel_chat_bg_border ""
+seta hud_panel_chat_bg_padding ""
+
+seta hud_panel_engineinfo 1
+seta hud_panel_engineinfo_pos "0.910000 0.970000"
+seta hud_panel_engineinfo_size "0.090000 0.030000"
+seta hud_panel_engineinfo_bg "0"
+seta hud_panel_engineinfo_bg_color ""
+seta hud_panel_engineinfo_bg_color_team ""
+seta hud_panel_engineinfo_bg_alpha ""
+seta hud_panel_engineinfo_bg_border ""
+seta hud_panel_engineinfo_bg_padding ""
+
+seta hud_panel_infomessages 1
+seta hud_panel_infomessages_pos "0.510000 0"
+seta hud_panel_infomessages_size "0.340000 0.090000"
+seta hud_panel_infomessages_bg "0"
+seta hud_panel_infomessages_bg_color ""
+seta hud_panel_infomessages_bg_color_team ""
+seta hud_panel_infomessages_bg_alpha ""
+seta hud_panel_infomessages_bg_border ""
+seta hud_panel_infomessages_bg_padding "0"
+seta hud_panel_infomessages_flip "1"
+
+menu_sync
+++ /dev/null
-seta hud_skin "luminos"
-seta hud_panel_bg "border"
-seta hud_panel_bg_color "0.875 0.375 0"
-seta hud_panel_bg_color_team "1"
-seta hud_panel_bg_alpha "1"
-seta hud_panel_bg_border "6"
-seta hud_panel_bg_padding "2"
-seta hud_panel_fg_alpha "1"
-
-seta hud_dock "dock"
-seta hud_dock_color "0 0.1875 0.4375"
-seta hud_dock_color_team "0.600000"
-seta hud_dock_alpha "1"
-
-seta hud_progressbar_alpha "0.500000"
-seta hud_progressbar_strength_color "0 0 0.6"
-seta hud_progressbar_shield_color "0.6 0 0.6"
-seta hud_progressbar_health_color "0.6 0 0"
-seta hud_progressbar_armor_color "0 0.6 0"
-seta hud_progressbar_fuel_color "0.6 0.6 0"
-seta hud_progressbar_nexball_color "0.7 0.1 0"
-
-seta _hud_panelorder "11 0 9 2 10 14 12 6 3 13 4 8 7 1 5 "
-
-seta hud_configure_grid "1"
-seta hud_configure_grid_xsize "0.005000"
-seta hud_configure_grid_ysize "0.005000"
-
-seta hud_panel_weapons 1
-seta hud_panel_weapons_pos "0.915000 0.085000"
-seta hud_panel_weapons_size "0.060000 0.635000"
-seta hud_panel_weapons_bg ""
-seta hud_panel_weapons_bg_color ""
-seta hud_panel_weapons_bg_color_team ""
-seta hud_panel_weapons_bg_alpha ""
-seta hud_panel_weapons_bg_border ""
-seta hud_panel_weapons_bg_padding ""
-seta hud_panel_weapons_complainbubble "1"
-seta hud_panel_weapons_complainbubble_padding "-10"
-seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
-seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
-seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
-seta hud_panel_weapons_ammo_color "0 1 0"
-seta hud_panel_weapons_ammo_alpha "1"
-seta hud_panel_weapons_aspect "2"
-
-seta hud_panel_ammo 1
-seta hud_panel_ammo_pos "0.190000 0.925000"
-seta hud_panel_ammo_size "0.095000 0.060000"
-seta hud_panel_ammo_bg ""
-seta hud_panel_ammo_bg_color ""
-seta hud_panel_ammo_bg_color_team ""
-seta hud_panel_ammo_bg_alpha ""
-seta hud_panel_ammo_bg_border ""
-seta hud_panel_ammo_bg_padding ""
-seta hud_panel_ammo_onlycurrent "1"
-seta hud_panel_ammo_iconalign "0"
-
-seta hud_panel_powerups 1
-seta hud_panel_powerups_pos "0.365000 0.015000"
-seta hud_panel_powerups_size "0.262500 0.048047"
-seta hud_panel_powerups_bg ""
-seta hud_panel_powerups_bg_color ""
-seta hud_panel_powerups_bg_color_team "1"
-seta hud_panel_powerups_bg_alpha ""
-seta hud_panel_powerups_bg_border ""
-seta hud_panel_powerups_bg_padding ""
-seta hud_panel_powerups_flip "1"
-seta hud_panel_powerups_iconalign "4"
-seta hud_panel_powerups_baralign "4"
-seta hud_panel_powerups_progressbar "1"
-
-seta hud_panel_healtharmor 1
-seta hud_panel_healtharmor_pos "0.305000 0.925000"
-seta hud_panel_healtharmor_size "0.315000 0.060000"
-seta hud_panel_healtharmor_bg ""
-seta hud_panel_healtharmor_bg_color ""
-seta hud_panel_healtharmor_bg_color_team "1"
-seta hud_panel_healtharmor_bg_alpha "1"
-seta hud_panel_healtharmor_bg_border ""
-seta hud_panel_healtharmor_bg_padding ""
-seta hud_panel_healtharmor_flip "0
-seta hud_panel_healtharmor_iconalign "4"
-seta hud_panel_healtharmor_baralign "4"
-seta hud_panel_healtharmor_progressbar "1"
-
-seta hud_panel_notify 1
-seta hud_panel_notify_pos "0.700000 0.740000"
-seta hud_panel_notify_size "0.280000 0.180000"
-seta hud_panel_notify_bg ""
-seta hud_panel_notify_bg_color ""
-seta hud_panel_notify_bg_color_team ""
-seta hud_panel_notify_bg_alpha "0"
-seta hud_panel_notify_bg_border ""
-seta hud_panel_notify_bg_padding ""
-seta hud_panel_notify_flip "0"
-seta hud_panel_notify_print "0"
-
-seta hud_panel_timer 1
-seta hud_panel_timer_pos "0.880000 0.012070"
-seta hud_panel_timer_size "0.100000 0.032520"
-seta hud_panel_timer_bg ""
-seta hud_panel_timer_bg_color ""
-seta hud_panel_timer_bg_color_team ""
-seta hud_panel_timer_bg_alpha ""
-seta hud_panel_timer_bg_border ""
-seta hud_panel_timer_bg_padding "0"
-
-seta hud_panel_radar 1
-seta hud_panel_radar_pos "0.025000 0.025000"
-seta hud_panel_radar_size "0.180000 0.220000"
-seta hud_panel_radar_bg ""
-seta hud_panel_radar_bg_color ""
-seta hud_panel_radar_bg_color_team ""
-seta hud_panel_radar_bg_alpha ""
-seta hud_panel_radar_bg_border ""
-seta hud_panel_radar_bg_padding "-3"
-seta hud_panel_radar_foreground_alpha "0.800000"
-
-seta hud_panel_score 1
-seta hud_panel_score_pos "0.025000 0.925000"
-seta hud_panel_score_size "0.145000 0.060000"
-seta hud_panel_score_bg ""
-seta hud_panel_score_bg_color ""
-seta hud_panel_score_bg_color_team ""
-seta hud_panel_score_bg_alpha ""
-seta hud_panel_score_bg_border ""
-seta hud_panel_score_bg_padding ""
-
-seta hud_panel_racetimer 1
-seta hud_panel_racetimer_pos "0.355000 0.205000"
-seta hud_panel_racetimer_size "0.280000 0.093333"
-seta hud_panel_racetimer_bg ""
-seta hud_panel_racetimer_bg_color ""
-seta hud_panel_racetimer_bg_color_team ""
-seta hud_panel_racetimer_bg_alpha "0"
-seta hud_panel_racetimer_bg_border ""
-seta hud_panel_racetimer_bg_padding ""
-
-seta hud_panel_vote 1
-seta hud_panel_vote_pos "0.025000 0.660000"
-seta hud_panel_vote_size "0.264218 0.102462"
-seta hud_panel_vote_bg ""
-seta hud_panel_vote_bg_color ""
-seta hud_panel_vote_bg_color_team ""
-seta hud_panel_vote_bg_alpha ""
-seta hud_panel_vote_bg_border ""
-seta hud_panel_vote_bg_padding ""
-seta hud_panel_vote_alreadyvoted_alpha "0.750000"
-
-seta hud_panel_modicons 1
-seta hud_panel_modicons_pos "0.040000 0.270000"
-seta hud_panel_modicons_size "0.084766 0.199903"
-seta hud_panel_modicons_bg ""
-seta hud_panel_modicons_bg_color ""
-seta hud_panel_modicons_bg_color_team ""
-seta hud_panel_modicons_bg_alpha ""
-seta hud_panel_modicons_bg_border ""
-seta hud_panel_modicons_bg_padding ""
-
-seta hud_panel_pressedkeys 1
-seta hud_panel_pressedkeys_pos "0.410000 0.545000"
-seta hud_panel_pressedkeys_size "0.177656 0.120531"
-seta hud_panel_pressedkeys_bg ""
-seta hud_panel_pressedkeys_bg_color ""
-seta hud_panel_pressedkeys_bg_color_team "1"
-seta hud_panel_pressedkeys_bg_alpha "0"
-seta hud_panel_pressedkeys_bg_border ""
-seta hud_panel_pressedkeys_bg_padding ""
-seta hud_panel_pressedkeys_aspect "1.600000"
-
-seta hud_panel_chat 1
-seta hud_panel_chat_pos "0.020000 0.775000"
-seta hud_panel_chat_size "0.627968 0.112696"
-seta hud_panel_chat_bg ""
-seta hud_panel_chat_bg_color ""
-seta hud_panel_chat_bg_color_team ""
-seta hud_panel_chat_bg_alpha "0"
-seta hud_panel_chat_bg_border ""
-seta hud_panel_chat_bg_padding ""
-
-seta hud_panel_engineinfo 1
-seta hud_panel_engineinfo_pos "0.860000 0.954667"
-seta hud_panel_engineinfo_size "0.125000 0.035000"
-seta hud_panel_engineinfo_bg ""
-seta hud_panel_engineinfo_bg_color ""
-seta hud_panel_engineinfo_bg_color_team ""
-seta hud_panel_engineinfo_bg_alpha "0"
-seta hud_panel_engineinfo_bg_border ""
-seta hud_panel_engineinfo_bg_padding ""
-
-seta hud_panel_infomessages 1
-seta hud_panel_infomessages_pos "0.340000 0.350000"
-seta hud_panel_infomessages_size "0.320000 0.085000"
-seta hud_panel_infomessages_bg ""
-seta hud_panel_infomessages_bg_color ""
-seta hud_panel_infomessages_bg_color_team ""
-seta hud_panel_infomessages_bg_alpha "0"
-seta hud_panel_infomessages_bg_border ""
-seta hud_panel_infomessages_bg_padding ""
-
-menu_restart
--- /dev/null
+seta hud_skin "old"
+seta hud_panel_bg "border_default"
+seta hud_panel_bg_color "0.299327 1 0.81275"
+seta hud_panel_bg_color_team "0"
+seta hud_panel_bg_alpha "0.700000"
+seta hud_panel_bg_border "8"
+seta hud_panel_bg_padding "0"
+seta hud_panel_fg_alpha "1"
+
+seta hud_dock "dock"
+seta hud_dock_color "0 0.697965 0.418232"
+seta hud_dock_color_team "0.700000"
+seta hud_dock_alpha "0.700000"
+
+seta hud_progressbar_alpha "0.5"
+seta hud_progressbar_strength_color "0 0 0.6"
+seta hud_progressbar_shield_color "0.6 0 0.6"
+seta hud_progressbar_health_color "0.6 0 0"
+seta hud_progressbar_armor_color "0 0.6 0"
+seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_nexball_color "0.7 0.1 0"
+
+seta _hud_panelorder "0 11 8 5 6 14 9 13 7 2 3 1 10 12 4 "
+
+seta hud_configure_grid "1"
+seta hud_configure_grid_xsize "0.01"
+seta hud_configure_grid_ysize "0.01"
+
+seta scr_centerpos "0.25"
+
+seta hud_panel_weapons 1
+seta hud_panel_weapons_pos "0.370000 0.870000"
+seta hud_panel_weapons_size "0.340000 0.060000"
+seta hud_panel_weapons_bg "0"
+seta hud_panel_weapons_bg_color ""
+seta hud_panel_weapons_bg_color_team ""
+seta hud_panel_weapons_bg_alpha ""
+seta hud_panel_weapons_bg_border ""
+seta hud_panel_weapons_bg_padding "-5"
+seta hud_panel_weapons_complainbubble "1"
+seta hud_panel_weapons_complainbubble_padding "-10"
+seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
+seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
+seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
+seta hud_panel_weapons_ammo_color "0 1 0"
+seta hud_panel_weapons_ammo_alpha "1"
+seta hud_panel_weapons_aspect "2"
+
+seta hud_panel_ammo 1
+seta hud_panel_ammo_pos "0.160000 0.910000"
+seta hud_panel_ammo_size "0.190000 0.090000"
+seta hud_panel_ammo_bg "0"
+seta hud_panel_ammo_bg_color ""
+seta hud_panel_ammo_bg_color_team ""
+seta hud_panel_ammo_bg_alpha ""
+seta hud_panel_ammo_bg_border ""
+seta hud_panel_ammo_bg_padding ""
+seta hud_panel_ammo_onlycurrent "0"
+seta hud_panel_ammo_iconalign "0"
+
+seta hud_panel_powerups 1
+seta hud_panel_powerups_pos "0.660000 0.910000"
+seta hud_panel_powerups_size "0.130000 0.090000"
+seta hud_panel_powerups_bg "0"
+seta hud_panel_powerups_bg_color ""
+seta hud_panel_powerups_bg_color_team ""
+seta hud_panel_powerups_bg_alpha ""
+seta hud_panel_powerups_bg_border ""
+seta hud_panel_powerups_bg_padding ""
+seta hud_panel_powerups_flip "1"
+seta hud_panel_powerups_iconalign "0"
+seta hud_panel_powerups_baralign "0"
+seta hud_panel_powerups_progressbar "0"
+
+seta hud_panel_healtharmor 1
+seta hud_panel_healtharmor_pos "0.370000 0.930000"
+seta hud_panel_healtharmor_size "0.300000 0.070000"
+seta hud_panel_healtharmor_bg "0"
+seta hud_panel_healtharmor_bg_color ""
+seta hud_panel_healtharmor_bg_color_team ""
+seta hud_panel_healtharmor_bg_alpha ""
+seta hud_panel_healtharmor_bg_border ""
+seta hud_panel_healtharmor_bg_padding ""
+seta hud_panel_healtharmor_flip "0
+seta hud_panel_healtharmor_iconalign "0"
+seta hud_panel_healtharmor_baralign "0"
+seta hud_panel_healtharmor_progressbar "0"
+
+seta hud_panel_notify 0
+seta hud_panel_notify_pos "0 0.650000"
+seta hud_panel_notify_size "0.300000 0.070000"
+seta hud_panel_notify_bg ""
+seta hud_panel_notify_bg_color ""
+seta hud_panel_notify_bg_color_team ""
+seta hud_panel_notify_bg_alpha "0"
+seta hud_panel_notify_bg_border ""
+seta hud_panel_notify_bg_padding ""
+seta hud_panel_notify_flip "0"
+seta hud_panel_notify_print "1"
+
+seta hud_panel_timer 1
+seta hud_panel_timer_pos "0.850000 0"
+seta hud_panel_timer_size "0.150000 0.060000"
+seta hud_panel_timer_bg ""
+seta hud_panel_timer_bg_color "0 0.5 0.35"
+seta hud_panel_timer_bg_color_team ""
+seta hud_panel_timer_bg_alpha ""
+seta hud_panel_timer_bg_border ""
+seta hud_panel_timer_bg_padding "0"
+
+seta hud_panel_radar 2
+seta hud_panel_radar_pos "0.800000 0"
+seta hud_panel_radar_size "0.200000 0.260000"
+seta hud_panel_radar_bg "border_radar"
+seta hud_panel_radar_bg_color ""
+seta hud_panel_radar_bg_color_team ""
+seta hud_panel_radar_bg_alpha "0.500000"
+seta hud_panel_radar_bg_border "0"
+seta hud_panel_radar_bg_padding "0"
+seta hud_panel_radar_foreground_alpha "1"
+
+seta hud_panel_score 1
+seta hud_panel_score_pos "0.760000 0.910000"
+seta hud_panel_score_size "0.240000 0.090000"
+seta hud_panel_score_bg "0"
+seta hud_panel_score_bg_color ""
+seta hud_panel_score_bg_color_team ""
+seta hud_panel_score_bg_alpha ""
+seta hud_panel_score_bg_border ""
+seta hud_panel_score_bg_padding ""
+
+seta hud_panel_racetimer 1
+seta hud_panel_racetimer_pos "0.360000 0.140000"
+seta hud_panel_racetimer_size "0.280000 0.090000"
+seta hud_panel_racetimer_bg "0"
+seta hud_panel_racetimer_bg_color ""
+seta hud_panel_racetimer_bg_color_team ""
+seta hud_panel_racetimer_bg_alpha ""
+seta hud_panel_racetimer_bg_border ""
+seta hud_panel_racetimer_bg_padding ""
+
+seta hud_panel_vote 1
+seta hud_panel_vote_pos "0.690000 0.750000"
+seta hud_panel_vote_size "0.300000 0.100000"
+seta hud_panel_vote_bg ""
+seta hud_panel_vote_bg_color "0 0.5 0.35"
+seta hud_panel_vote_bg_color_team ""
+seta hud_panel_vote_bg_alpha ""
+seta hud_panel_vote_bg_border ""
+seta hud_panel_vote_bg_padding "-3"
+seta hud_panel_vote_alreadyvoted_alpha "0.750000"
+
+seta hud_panel_modicons 1
+seta hud_panel_modicons_pos "0.010000 0.910000"
+seta hud_panel_modicons_size "0.135000 0.090000"
+seta hud_panel_modicons_bg "0"
+seta hud_panel_modicons_bg_color ""
+seta hud_panel_modicons_bg_color_team ""
+seta hud_panel_modicons_bg_alpha ""
+seta hud_panel_modicons_bg_border ""
+seta hud_panel_modicons_bg_padding ""
+
+seta hud_panel_pressedkeys 1
+seta hud_panel_pressedkeys_pos "0.440000 0.760000"
+seta hud_panel_pressedkeys_size "0.120000 0.094368"
+seta hud_panel_pressedkeys_bg "0"
+seta hud_panel_pressedkeys_bg_color ""
+seta hud_panel_pressedkeys_bg_color_team ""
+seta hud_panel_pressedkeys_bg_alpha ""
+seta hud_panel_pressedkeys_bg_border ""
+seta hud_panel_pressedkeys_bg_padding ""
+seta hud_panel_pressedkeys_aspect "1.600000"
+
+seta hud_panel_chat 1
+seta hud_panel_chat_pos "0 0.760000"
+seta hud_panel_chat_size "0.420000 0.130000"
+seta hud_panel_chat_bg "0"
+seta hud_panel_chat_bg_color ""
+seta hud_panel_chat_bg_color_team ""
+seta hud_panel_chat_bg_alpha ""
+seta hud_panel_chat_bg_border ""
+seta hud_panel_chat_bg_padding ""
+
+seta hud_panel_engineinfo 1
+seta hud_panel_engineinfo_pos "0.887500 0.870000"
+seta hud_panel_engineinfo_size "0.112500 0.030000"
+seta hud_panel_engineinfo_bg "0"
+seta hud_panel_engineinfo_bg_color ""
+seta hud_panel_engineinfo_bg_color_team ""
+seta hud_panel_engineinfo_bg_alpha ""
+seta hud_panel_engineinfo_bg_border ""
+seta hud_panel_engineinfo_bg_padding ""
+
+seta hud_panel_infomessages 1
+seta hud_panel_infomessages_pos "0.700000 0.620000"
+seta hud_panel_infomessages_size "0.300000 0.100000"
+seta hud_panel_infomessages_bg "0"
+seta hud_panel_infomessages_bg_color ""
+seta hud_panel_infomessages_bg_color_team ""
+seta hud_panel_infomessages_bg_alpha ""
+seta hud_panel_infomessages_bg_border ""
+seta hud_panel_infomessages_bg_padding ""
+seta hud_panel_infomessages_flip "1"
+
+menu_sync
+++ /dev/null
-seta hud_skin "old"
-seta hud_bg "border"
-seta hud_bg_color "1 1 1"
-seta hud_bg_color_team "0"
-seta hud_bg_alpha "0.500000"
-seta hud_bg_border "10"
-seta hud_bg_padding "0"
-seta hud_fg_alpha "1"
-
-seta hud_dock "dock"
-seta hud_dock_color "0 0.5 0.35"
-seta hud_dock_color_team "0.700000"
-seta hud_dock_alpha "1"
-
-seta hud_progressbar_alpha "0.5"
-seta hud_progressbar_strength_color "0 0 0.6"
-seta hud_progressbar_shield_color "0.6 0 0.6"
-seta hud_progressbar_health_color "0.6 0 0"
-seta hud_progressbar_armor_color "0 0.6 0"
-seta hud_progressbar_fuel_color "0.6 0.6 0"
-seta hud_progressbar_nexball_color "0.7 0.1 0"
-
-seta _hud_panelorder "3 7 5 6 0 2 14 4 12 11 13 9 1 10 8 "
-
-seta hud_configure_grid "1"
-seta hud_configure_grid_xsize "0.01"
-seta hud_configure_grid_ysize "0.01"
-
-seta hud_panel_weapons 1
-seta hud_panel_weapons_pos "0.370000 0.870000"
-seta hud_panel_weapons_size "0.330000 0.060000"
-seta hud_panel_weapons_bg "0"
-seta hud_panel_weapons_bg_color ""
-seta hud_panel_weapons_bg_color_team ""
-seta hud_panel_weapons_bg_alpha ""
-seta hud_panel_weapons_bg_border ""
-seta hud_panel_weapons_bg_padding "-5"
-seta hud_panel_weapons_complainbubble "1"
-seta hud_panel_weapons_complainbubble_padding "-10"
-seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
-seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
-seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
-seta hud_panel_weapons_ammo_color "0 1 0"
-seta hud_panel_weapons_ammo_alpha "1"
-seta hud_panel_weapons_aspect "1"
-
-seta hud_panel_ammo 1
-seta hud_panel_ammo_pos "0.160000 0.910000"
-seta hud_panel_ammo_size "0.190000 0.090000"
-seta hud_panel_ammo_bg "0"
-seta hud_panel_ammo_bg_color ""
-seta hud_panel_ammo_bg_color_team ""
-seta hud_panel_ammo_bg_alpha ""
-seta hud_panel_ammo_bg_border ""
-seta hud_panel_ammo_bg_padding ""
-seta hud_panel_ammo_onlycurrent "0"
-seta hud_panel_ammo_iconalign "0"
-
-seta hud_panel_powerups 1
-seta hud_panel_powerups_pos "0.670000 0.910000"
-seta hud_panel_powerups_size "0.110000 0.080000"
-seta hud_panel_powerups_bg ""
-seta hud_panel_powerups_bg_color ""
-seta hud_panel_powerups_bg_color_team ""
-seta hud_panel_powerups_bg_alpha ""
-seta hud_panel_powerups_bg_border ""
-seta hud_panel_powerups_bg_padding ""
-seta hud_panel_powerups_flip "1"
-seta hud_panel_powerups_iconalign "0"
-seta hud_panel_powerups_baralign "0"
-seta hud_panel_powerups_progressbar "0"
-
-seta hud_panel_healtharmor 1
-seta hud_panel_healtharmor_pos "0.370000 0.930000"
-seta hud_panel_healtharmor_size "0.300000 0.070000"
-seta hud_panel_healtharmor_bg "0"
-seta hud_panel_healtharmor_bg_color ""
-seta hud_panel_healtharmor_bg_color_team ""
-seta hud_panel_healtharmor_bg_alpha ""
-seta hud_panel_healtharmor_bg_border ""
-seta hud_panel_healtharmor_bg_padding ""
-seta hud_panel_healtharmor_flip "0
-seta hud_panel_healtharmor_iconalign "0"
-seta hud_panel_healtharmor_baralign "0"
-seta hud_panel_healtharmor_progressbar "0"
-
-seta hud_panel_notify 0
-seta hud_panel_notify_pos "0 0.650000"
-seta hud_panel_notify_size "0.300000 0.070000"
-seta hud_panel_notify_bg ""
-seta hud_panel_notify_bg_color ""
-seta hud_panel_notify_bg_color_team ""
-seta hud_panel_notify_bg_alpha "0"
-seta hud_panel_notify_bg_border ""
-seta hud_panel_notify_bg_padding ""
-seta hud_panel_notify_flip "0"
-seta hud_panel_notify_print "0"
-
-seta hud_panel_timer 1
-seta hud_panel_timer_pos "0.860000 0"
-seta hud_panel_timer_size "0.140000 0.045528"
-seta hud_panel_timer_bg "border"
-seta hud_panel_timer_bg_color "0 0.5 0.35"
-seta hud_panel_timer_bg_color_team ""
-seta hud_panel_timer_bg_alpha "0.800000"
-seta hud_panel_timer_bg_border ""
-seta hud_panel_timer_bg_padding "0"
-
-seta hud_panel_radar 2
-seta hud_panel_radar_pos "0.800000 0"
-seta hud_panel_radar_size "0.200000 0.260000"
-seta hud_panel_radar_bg "border_radar"
-seta hud_panel_radar_bg_color ""
-seta hud_panel_radar_bg_color_team ""
-seta hud_panel_radar_bg_alpha "0.3"
-seta hud_panel_radar_bg_border ""
-seta hud_panel_radar_bg_padding "-10"
-seta hud_panel_radar_foreground_alpha "0.800000"
-
-seta hud_panel_score 1
-seta hud_panel_score_pos "0.760000 0.920000"
-seta hud_panel_score_size "0.240000 0.080000"
-seta hud_panel_score_bg "0"
-seta hud_panel_score_bg_color ""
-seta hud_panel_score_bg_color_team ""
-seta hud_panel_score_bg_alpha ""
-seta hud_panel_score_bg_border ""
-seta hud_panel_score_bg_padding ""
-
-seta hud_panel_racetimer 1
-seta hud_panel_racetimer_pos "0.360000 0.140000"
-seta hud_panel_racetimer_size "0.280000 0.093333"
-seta hud_panel_racetimer_bg ""
-seta hud_panel_racetimer_bg_color ""
-seta hud_panel_racetimer_bg_color_team ""
-seta hud_panel_racetimer_bg_alpha "0"
-seta hud_panel_racetimer_bg_border ""
-seta hud_panel_racetimer_bg_padding ""
-
-seta hud_panel_vote 1
-seta hud_panel_vote_pos "0.690000 0.750000"
-seta hud_panel_vote_size "0.300000 0.100000"
-seta hud_panel_vote_bg ""
-seta hud_panel_vote_bg_color "0 0.5 0.35"
-seta hud_panel_vote_bg_color_team ""
-seta hud_panel_vote_bg_alpha "0.800000"
-seta hud_panel_vote_bg_border ""
-seta hud_panel_vote_bg_padding "-3"
-seta hud_panel_vote_alreadyvoted_alpha "0.750000"
-
-seta hud_panel_modicons 1
-seta hud_panel_modicons_pos "0.010000 0.910000"
-seta hud_panel_modicons_size "0.135000 0.090000"
-seta hud_panel_modicons_bg ""
-seta hud_panel_modicons_bg_color ""
-seta hud_panel_modicons_bg_color_team ""
-seta hud_panel_modicons_bg_alpha ""
-seta hud_panel_modicons_bg_border ""
-seta hud_panel_modicons_bg_padding ""
-
-seta hud_panel_pressedkeys 1
-seta hud_panel_pressedkeys_pos "0.440000 0.740000"
-seta hud_panel_pressedkeys_size "0.120000 0.094368"
-seta hud_panel_pressedkeys_bg ""
-seta hud_panel_pressedkeys_bg_color ""
-seta hud_panel_pressedkeys_bg_color_team ""
-seta hud_panel_pressedkeys_bg_alpha "0"
-seta hud_panel_pressedkeys_bg_border ""
-seta hud_panel_pressedkeys_bg_padding ""
-seta hud_panel_pressedkeys_aspect "1.600000"
-
-seta hud_panel_chat 1
-seta hud_panel_chat_pos "0 0.760000"
-seta hud_panel_chat_size "0.420000 0.130000"
-seta hud_panel_chat_bg ""
-seta hud_panel_chat_bg_color ""
-seta hud_panel_chat_bg_color_team ""
-seta hud_panel_chat_bg_alpha "0"
-seta hud_panel_chat_bg_border ""
-seta hud_panel_chat_bg_padding ""
-
-seta hud_panel_engineinfo 1
-seta hud_panel_engineinfo_pos "0.887500 0.870000"
-seta hud_panel_engineinfo_size "0.112500 0.030000"
-seta hud_panel_engineinfo_bg ""
-seta hud_panel_engineinfo_bg_color ""
-seta hud_panel_engineinfo_bg_color_team ""
-seta hud_panel_engineinfo_bg_alpha "0"
-seta hud_panel_engineinfo_bg_border ""
-seta hud_panel_engineinfo_bg_padding ""
-
-seta hud_panel_infomessages 1
-seta hud_panel_infomessages_pos "0.700000 0.620000"
-seta hud_panel_infomessages_size "0.300000 0.090000"
-seta hud_panel_infomessages_bg ""
-seta hud_panel_infomessages_bg_color ""
-seta hud_panel_infomessages_bg_color_team ""
-seta hud_panel_infomessages_bg_alpha "0"
-seta hud_panel_infomessages_bg_border ""
-seta hud_panel_infomessages_bg_padding ""
-
-menu_restart
alias -tuba_c "-crouch; -tuba_$*"
alias +tuba_j "+jump; +tuba_$*"
alias -tuba_j "-jump; -tuba_$*"
-alias +tuba_1 "+attack"
-alias -tuba_1 "-attack"
-alias +tuba_2 "+attack2"
-alias -tuba_2 "-attack2"
+alias +tuba_1 "+fire"
+alias -tuba_1 "-fire"
+alias +tuba_2 "+fire2"
+alias -tuba_2 "-fire2"
alias +tuba_! "echo cannot play this note, sorry"
alias -tuba_! ""
alias +tuba_ ""
//TAG: soldier
//affirmative sound/player/carni-lycan/player/affirmative 0
-attack sound/player/soldier/coms/attack 2
+attack sound/player/soldier/coms/attack 0
//attacking sound/player/carni-lycan/player/attacking 0
attackinfive sound/player/soldier/coms/attackinfive 0
coverme sound/player/soldier/coms/coverme 0
defend sound/player/soldier/coms/defend 0
//defending sound/player/carni-lycan/player/defending 0
//droppedflag sound/player/carni-lycan/player/droppedflag 0
-flagcarriertakingdamage sound/player/soldier/player/flagcarriertakingdamage 0
+flagcarriertakingdamage sound/player/soldier/coms/flagcarriertakingdamage 0
freelance sound/player/soldier/coms/freelance 2
-getflag sound/player/soldier/player/getflag 0
+getflag sound/player/soldier/coms/getflag 0
incoming sound/player/soldier/coms/incoming 0
meet sound/player/soldier/coms/meet 0
needhelp sound/player/soldier/coms/needhelp 2
--- /dev/null
+1 8 20 0 // fire
+9 5 20 0 // fire2
+15 200 20 1 // idle
+215 40 20 0 // reload
-// These have been modified from Nexuiz 2.4.2's physicsQBR.cfg file
-sv_gravity 800
-sv_gravity 802
-sv_maxspeed 417
-sv_maxairspeed 202
+// These have been modified from Nexuiz 2.4.2's physicsQBR.cfg file and a bunch of other crap div0 threw on here :P
+// DO NOT SCREW WITH friction on land, edge friction, step height, or sv_airaccel_qw
+sv_gravity 819
+sv_maxspeed 420
+sv_maxairspeed 283
+
sv_stopspeed 100
-sv_accelerate 5.8
-sv_airaccelerate 5.5
-sv_friction 4.1
-edgefriction 1
-sv_stepheight 34
-sv_jumpvelocity 307
+sv_accelerate 13
+sv_airaccelerate 6
+sv_friction 9.6 // higher values make you slide less
+edgefriction 1 // div0 says no! lol
+sv_stepheight 26
+sv_jumpvelocity 304
sv_wateraccelerate -1
sv_waterfriction -1
-sv_airaccel_sideways_friction 0.207
-sv_airaccel_qw -0.93
+sv_airaccel_sideways_friction 0 // pain in the ass to tweak without screwing up the strafing
+sv_airaccel_qw -0.93 //given a negative value to combat potential cheats, was told by divVerent not to mess with it
+
sv_airstopaccelerate 0
sv_airstrafeaccelerate 0
sv_maxairstrafespeed 0
sv_friction_on_land 0
sv_doublejump 0
sv_jumpspeedcap_min ""
-sv_jumpspeedcap_max ""
+sv_jumpspeedcap_max 0.38
sv_jumpspeedcap_max_disable_on_ramps 0
sv_airaccelerate 2
sv_friction 8
edgefriction 1
-sv_stepheight 34
+sv_stepheight 26
+// Q1: 16+2
+// Nex: 32+2
+// we try: 24+2
// actually, what we want is 266.6666 for 180bpm
// but 260 takes same amount of frames and is nicer to mappers
// "NoQWBunny" physics based on XPM
sv_gravity 800
sv_maxspeed 320
-
-sv_maxairspeed 320
+sv_maxairspeed 400
sv_stopspeed 100
sv_accelerate 15
sv_airaccelerate 2
sv_friction 8
edgefriction 1
-sv_stepheight 34
+sv_stepheight 26
+// Q1: 16+2
+// Nex: 32+2
+// we try: 24+2
-sv_jumpvelocity 250
-sv_wateraccelerate 4
-sv_waterfriction 1
+// actually, what we want is 266.6666 for 180bpm
+// but 260 takes same amount of frames and is nicer to mappers
+sv_jumpvelocity 260
+sv_wateraccelerate -1
+sv_waterfriction -1
sv_airaccel_sideways_friction 0
-sv_airaccel_qw -0.937
+sv_airaccel_qw -0.8
sv_airstopaccelerate 3
-sv_airstrafeaccelerate 20
-sv_maxairstrafespeed 96
-sv_airstrafeaccel_qw -0.979
+sv_airstrafeaccelerate 24
+sv_maxairstrafespeed 100
+sv_airstrafeaccel_qw -0.95
sv_aircontrol 125
-sv_aircontrol_penalty 100
-sv_aircontrol_power 2.5
-sv_airspeedlimit_nonqw 0
+sv_aircontrol_penalty 150
+sv_aircontrol_power 2
+sv_airspeedlimit_nonqw 800
sv_warsowbunny_turnaccel 0
sv_warsowbunny_accel 0.1593
sv_warsowbunny_topspeed 925
float campingrifle_scope;
float nex_scope;
+
+float cr_maxbullets;
+
+float bgmtime;
+
}
Tuba_Precache();
-#ifdef UID
- {
- // find the user ID
- string uid;
- registercvar("_cl_userid", "", CVAR_SAVE);
- uid = cvar_string("_cl_userid");
- if(strlen(uid) < 16)
- {
- uid = "";
- for(i = 0; i < 4; ++i)
- uid = strcat(uid, substring(ftos(floor(10000 + random() * 10000)), 1, -1));
- }
- cvar_set("_cl_userid", uid);
- localcmd(strcat("\ncmd uid ", uid, "\n"));
- }
-#endif
-
get_mi_min_max_texcoords(1); // try the CLEVER way first
minimapname = strcat("gfx/", mi_shortname, "_radar.tga");
shortmapname = mi_shortname;
self.angles = view_angles;
self.angles_x = -self.angles_x;
if not(self.cnt)
- R_AddEntity(self);
+ self.drawmask = MASK_NORMAL;
+ else
+ self.drawmask = 0;
}
void ShotOrg_Draw2D()
{
if(time - floor(time) > 0.5)
{
PolyDrawModel(self);
+ self.drawmask = 0;
}
else
{
self.renderflags = 0;
- R_AddEntity(self);
+ self.drawmask = MASK_NORMAL;
}
}
complain_weapon_type = ReadByte();
complain_weapon_time = time;
+ weapontime = time; // ping the weapon panel
}
// CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
Net_WeaponComplain();
bHandled = true;
break;
+ case TE_CSQC_CR_MAXBULLETS:
+ cr_maxbullets = ReadByte();
+ bHandled = true;
+ break;
default:
// No special logic for this temporary entity; return 0 so the engine can handle it
bHandled = false;
p = p - view_up * 16;
if(idx-1 >= 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;
}
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();
void PostInit(void);
void CSQC_Demo_Camera();
-float HUD_WouldDrawScoreboard ();
+float HUD_WouldDrawScoreboard();
float view_set;
float camera_mode;
float reticle_type;
void CSQC_RAPTOR_HUD();
vector freeze_pmove_org, freeze_input_angles;
+entity nightvision_noise, nightvision_noise2;
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;
input_angles = warpzone_fixview_cl_viewangles;
view_angles = warpzone_fixview_angles;
- if(cvar("cl_lockview") || autocvar__hud_configure)
+ if(cvar("cl_lockview") || (autocvar__hud_configure && spectatee_status <= 0))
{
pmove_org = freeze_pmove_org;
input_angles = view_angles = freeze_input_angles;
view_set = 1;
}
- vid_width = w;
- vid_height = h;
-
#ifdef BLURTEST
if(time > blurtest_time0 && time < blurtest_time1)
{
}
}
- hud_accuracy_hud = cvar_or("hud_accuracy_hud", 1);
ColorTranslateMode = cvar("cl_stripcolorcodes");
activeweapon = getstati(STAT_SWITCHWEAPON);
f = cvar("teamplay");
// 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);
}
// Draw the Crosshair
- float scoreboard_active;
- scoreboard_active = HUD_WouldDrawScoreboard();
R_SetView(VF_DRAWCROSSHAIR, 0); //Make sure engine crosshairs are always hidden
// Draw the Engine Status Bar (the default Quake HUD)
// next R_RenderScene call
drawstring('0 0 0', "", '1 1 0', '1 1 1', 0, 0);
+ if(cvar("r_fakelight") >= 2 || cvar("r_fullbright"))
+ {
+ // apply night vision effect
+ vector rgb, tc_00, tc_01, tc_10, tc_11;
+ float a;
+
+ if(!nightvision_noise)
+ {
+ nightvision_noise = spawn();
+ nightvision_noise.classname = "nightvision_noise";
+ }
+ if(!nightvision_noise2)
+ {
+ nightvision_noise2 = spawn();
+ nightvision_noise2.classname = "nightvision_noise2";
+ }
+
+ // color tint in yellow
+ drawfill('0 0 0', cvar("vid_conwidth") * '1 0 0' + cvar("vid_conheight") * '0 1 0', '0.5 1 0.3', 1, DRAWFLAG_MODULATE);
+
+ // draw BG
+ a = Noise_Pink(nightvision_noise, frametime * 1.5) * 0.05 + 0.15;
+ rgb = '1 1 1';
+ tc_00 = '0 0 0' + '0.2 0 0' * sin(time * 0.3) + '0 0.3 0' * cos(time * 0.7);
+ tc_01 = '0 2.25 0' + '0.6 0 0' * cos(time * 1.2) - '0 0.3 0' * sin(time * 2.2);
+ tc_10 = '1.5 0 0' - '0.2 0 0' * sin(time * 0.5) + '0 0.5 0' * cos(time * 1.7);
+ //tc_11 = '1 1 0' + '0.6 0 0' * sin(time * 0.6) + '0 0.3 0' * cos(time * 0.1);
+ tc_11 = tc_01 + tc_10 - tc_00;
+ R_BeginPolygon("gfx/nightvision-bg.tga", DRAWFLAG_ADDITIVE);
+ R_PolygonVertex('0 0 0', tc_00, rgb, a);
+ R_PolygonVertex(cvar("vid_conwidth") * '1 0 0', tc_10, rgb, a);
+ R_PolygonVertex(cvar("vid_conwidth") * '1 0 0' + cvar("vid_conheight") * '0 1 0', tc_11, rgb, a);
+ R_PolygonVertex(cvar("vid_conheight") * '0 1 0', tc_01, rgb, a);
+ R_EndPolygon();
+
+ // draw FG
+ a = Noise_Pink(nightvision_noise2, frametime * 0.1) * 0.05 + 0.12;
+ rgb = '0.3 0.6 0.4' + '0.1 0.4 0.2' * Noise_White(nightvision_noise2, frametime);
+ tc_00 = '0 0 0' + '1 0 0' * Noise_White(nightvision_noise2, frametime) + '0 1 0' * Noise_White(nightvision_noise2, frametime);
+ tc_01 = tc_00 + '0 3 0' * (1 + Noise_White(nightvision_noise2, frametime) * 0.2);
+ tc_10 = tc_00 + '2 0 0' * (1 + Noise_White(nightvision_noise2, frametime) * 0.3);
+ tc_11 = tc_01 + tc_10 - tc_00;
+ R_BeginPolygon("gfx/nightvision-fg.tga", DRAWFLAG_ADDITIVE);
+ R_PolygonVertex('0 0 0', tc_00, rgb, a);
+ R_PolygonVertex(cvar("vid_conwidth") * '1 0 0', tc_10, rgb, a);
+ R_PolygonVertex(cvar("vid_conwidth") * '1 0 0' + cvar("vid_conheight") * '0 1 0', tc_11, rgb, a);
+ R_PolygonVertex(cvar("vid_conheight") * '0 1 0', tc_01, rgb, a);
+ R_EndPolygon();
+ }
+
// Draw the aiming reticle for weapons that use it
// reticle_type is changed to the item we are zooming / aiming with, to decide which reticle to use
// It must be a persisted float for fading out to work properly (you let go of the zoom button for
// the view to go back to normal, so reticle_type would become 0 as we fade out)
if(spectatee_status || getstati(STAT_HEALTH) <= 0)
reticle_type = 0; // prevent reticle from showing during the respawn zoom effect or for spectators
+ else if(activeweapon == WEP_NEX && (button_zoom || zoomscript_caught) || activeweapon == WEP_CAMPINGRIFLE && (button_zoom || zoomscript_caught) || activeweapon == WEP_MINSTANEX && (button_zoom || zoomscript_caught))
+ reticle_type = 2; // nex zoom
else if(button_zoom || zoomscript_caught)
reticle_type = 1; // normal zoom
else if(activeweapon == WEP_NEX && button_attack2 || activeweapon == WEP_CAMPINGRIFLE && button_attack2)
self.draw2d();
self = e;
- // draw hud
- if(cvar("r_letterbox") == 0) {
- HUD_DrawCenterPrint(); // draw centerprint messages even if viewsize >= 120
- }
+ scoreboard_active = HUD_WouldDrawScoreboard();
float hud;
hud = getstati(STAT_HUD);
if(hud == HUD_SPIDERBOT)
- {
CSQC_SPIDER_HUD();
- }
else if(hud == HUD_WAKIZASHI)
CSQC_WAKIZASHI_HUD();
else if(hud == HUD_RAPTOR)
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;
wcross_scale *= 1 - cvar("_menu_alpha");
wcross_alpha *= 1 - cvar("_menu_alpha");
+ ring_scale = cvar("crosshair_ring_size");
+
+ float f, a;
+ wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
+
+ float nex_charge;
+ nex_charge = getstatf(STAT_NEX_CHARGE);
+
// ring around crosshair representing bullets left in camping rifle clip
- if (activeweapon == WEP_CAMPINGRIFLE)
+ if (activeweapon == WEP_CAMPINGRIFLE && cr_maxbullets)
{
- ring_scale = cvar("crosshair_campingrifle_ring_size");
- bullets = bound(0, getstati(STAT_BULLETS_LOADED), 4);
- }
- else
- bullets = 0;
+ bullets = getstati(STAT_BULLETS_LOADED);
+ f = bound(0, bullets / cr_maxbullets, 1);
-#define CROSSHAIR_DRAW_RING(i,j,sz,wcross_name,wcross_alpha) \
- drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size_x * ring_scale + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size_y * ring_scale + j * wcross_blur)), strcat("gfx/rifle_ring_", ftos(bullets)), sz * wcross_size * ring_scale, wcross_color, wcross_alpha, DRAWFLAG_NORMAL)
+ a = cvar("crosshair_campingrifle_bulletcounter_alpha");
+ DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, "gfx/crosshair_ring.tga", f, wcross_color, wcross_alpha * a, DRAWFLAG_ADDITIVE);
+ }
+ else if (activeweapon == WEP_NEX && nex_charge) // ring around crosshair representing velocity-dependent damage for the nex
+ {
+ a = cvar("crosshair_nexvelocity_alpha");
+ DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, "gfx/crosshair_ring.tga", nex_charge, wcross_color, wcross_alpha * a, DRAWFLAG_ADDITIVE);
+ }
#define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \
do \
}
wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
- if(bullets)
- {
- CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_RING, wcross_resolution, wcross_name, wcross_alpha);
- }
CROSSHAIR_DRAW(wcross_resolution, wcross_name, wcross_alpha * f);
+
+ if(cvar("crosshair_dot"))
+ CROSSHAIR_DRAW(wcross_resolution * cvar("crosshair_dot_size"), "gfx/crosshairdot.tga", wcross_alpha * f * cvar("crosshair_dot_alpha"));
+
wcross_name_alpha_goal_prev = f;
}
}
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
case HUD_NORMAL:
// do some accuracy var caching
float i;
+ if(cvar_string("hud_panel_weapons_accuracy_color_levels") != acc_color_levels)
if(!(gametype == GAME_RACE || gametype == GAME_CTS))
{
- acc_levels = tokenize(cvar_string("hud_panel_weapons_accuracy_color_levels"));
+ if(acc_color_levels)
+ strunzone(acc_color_levels);
+ acc_color_levels = strzone(cvar_string("hud_panel_weapons_accuracy_color_levels"));
+ acc_levels = tokenize(acc_color_levels);
if (acc_levels > MAX_ACCURACY_LEVELS)
acc_levels = MAX_ACCURACY_LEVELS;
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_active) // 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:
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;
var string autocvar_hud_panel_infomessages_bg_border;
var string autocvar_hud_panel_infomessages_bg_padding;
var float autocvar_hud_panel_infomessages_flip;
+
+var float autocvar_scoreboard_border_thickness;
float BGMScript(entity e)
{
- float t;
float amp, vel;
if(e.bgmscript == "")
e.just_toggled = FALSE;
- t = gettime(GETTIME_CDTRACK);
- if(t < 0)
+ if(bgmtime < 0)
return -1;
- if(t < e.bgmscripttime)
+ if(bgmtime < e.bgmscripttime)
{
//print("reset ", e.bgmscript, "\n");
amp = GetCurrentAmplitude(e, e.bgmscripttime - e.bgmscriptstatetime + drawframetime);
e.bgmscriptline = e.bgmscriptline0;
- e.bgmscripttime = t;
+ e.bgmscripttime = bgmtime;
// treat this as a stop event for all notes, to prevent sticking keys
e.bgmscriptstate = FALSE;
e.bgmscriptvolume = 1;
- e.bgmscriptstatetime = t - GetTimeForAmplitude(e, amp);
+ e.bgmscriptstatetime = bgmtime - GetTimeForAmplitude(e, amp);
}
// find the CURRENT line
for(;;)
{
tokenize_console(bufstr_get(bgmscriptbuf, e.bgmscriptline));
- if(stof(argv(1)) >= t || argv(0) != e.bgmscript)
+ if(stof(argv(1)) >= bgmtime || argv(0) != e.bgmscript)
{
- e.bgmscripttime = t;
- return GetCurrentAmplitude(e, t - e.bgmscriptstatetime);
+ e.bgmscripttime = bgmtime;
+ return GetCurrentAmplitude(e, bgmtime - e.bgmscriptstatetime);
}
- else if(t >= stof(argv(1)))
+ else if(bgmtime >= stof(argv(1)))
{
e.bgmscriptline += 1;
e.bgmscripttime = stof(argv(1));
self.alpha = bound(0, self.cnt - time, 1);
if(self.alpha < ALPHA_MIN_VISIBLE)
+ {
Casing_Delete();
- else
- R_AddEntity(self);
+ self.drawmask = 0;
+ }
}
void Casing_Touch()
casing.angles_x = ReadByte() * 360 / 256;
casing.angles_y = ReadByte() * 360 / 256;
casing.angles_z = ReadByte() * 360 / 256;
+ casing.drawmask = MASK_NORMAL;
if(cvar("cl_casings") && isNew) {
casing.draw = Casing_Draw;
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;
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;
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)
self.alpha = bound(0, self.nextthink - time, 1);
if(self.alpha < ALPHA_MIN_VISIBLE)
+ {
+ self.drawmask = 0;
Gib_Delete();
- else
- R_AddEntity(self);
+ }
}
void TossGib (string mdlname, vector org, vector vconst, vector vrand, float specnum, float destroyontouch, float issilent)
gib.damageforcescale = cvar_or("cl_gibs_damageforcescale", 3.5);
gib.nextthink = time + cvar_or("cl_gibs_lifetime", 14) * (1 + prandom() * 0.15);
+ gib.drawmask = MASK_NORMAL;
RubbleLimit("gib", cvar_or("cl_gibs_maxcount",100), Gib_Delete);
}
.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.
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");
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;
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");
InterpolateOrigin_Note();
- if(bIsNew)
+ if(bIsNew || !self.teleport_time)
{
self.draw = Draw_GrapplingHook;
self.entremove = Remove_GrapplingHook;
break;
}
}
+
+ self.teleport_time = time + 10;
}
void Hook_Precache()
#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;
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);
if(havail > vid_conheight - 70)
havail = vid_conheight - 70; // avoid overlapping HUD
- centerprint_start_x = 0;
-
#if 0
float forbiddenmin, forbiddenmax, allowedmin, allowedmax, preferred;
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");
}
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 && scoreboard_active) // 24 = height of Scoreboard text
+ centerprint_start_y = scoreboard_bottom + centerprint_fontsize_y;
+
pos = centerprint_start;
for (i=0; i<centerprint_num; i = i + 1)
{
- pos_x = (vid_conwidth - centerprint_width[i]) * 0.5;
ts = centerprint_messages[i];
+ drawfontscale = sz * '1 1 0';
+ drawfont = hud_bigfont;
+ pos_x = (vid_conwidth - stringwidth(ts, TRUE, centerprint_fontsize)) * 0.5;
if (ts != "")
{
- drawcolorcodedstring(pos, ts, centerprint_fontsize, a, DRAWFLAG_NORMAL);
- // - '0 0.5 0' * (sz - 1) * centerprint_fontsize_x - '0.5 0 0' * (sz - 1) * centerprint_width[i] * centerprint_fontsize_y, centerprint_fontsize * sz
+ drawcolorcodedstring(pos + '0 1 0' * (1 - sz) * 0.5 *centerprint_fontsize_y, ts, centerprint_fontsize, a, DRAWFLAG_NORMAL);
pos_y = pos_y + centerprint_fontsize_y;
}
else
// half height for empty lines looks better
- pos_y = pos_y + centerprint_fontsize_y * 0.5;
+ pos_y = pos_y + sz * centerprint_fontsize_y * 0.5;
+ drawfontscale = '1 1 0';
+ drawfont = hud_font;
}
}
fputs(fh, strcat("seta hud_configure_grid_ysize \"", cvar_string("hud_configure_grid_ysize"), "\"", "\n"));
fputs(fh, "\n");
+ fputs(fh, strcat("seta scr_centerpos \"", cvar_string("scr_centerpos"), "\"", "\n"));
+ fputs(fh, "\n");
+
// common cvars for all panels
float i;
for (i = 0; i < HUD_PANEL_NUM; ++i)
case HUD_PANEL_PRESSEDKEYS:
fputs(fh, strcat("seta hud_panel_", panel_name, "_aspect \"", cvar_string(strcat("hud_panel_", panel_name, "_aspect")), "\"", "\n"));
break;
+ case HUD_PANEL_INFOMESSAGES:
+ fputs(fh, strcat("seta hud_panel_", panel_name, "_flip \"", cvar_string(strcat("hud_panel_", panel_name, "_flip")), "\"", "\n"));
+ break;
}
fputs(fh, "\n");
}
- fputs(fh, strcat("menu_restart", "\n")); // force a menu update when execing config, so that the dialogs are updated
+ fputs(fh, strcat("menu_sync", "\n")); // force the menu to reread the cvars, so that the dialogs are updated
print("^2Successfully exported to hud_", autocvar_hud_skin, "_", cfgname, ".cfg! (Note: It's saved in data/data/)\n");
}
float prevMouseClickedTime; // time during previous mouse click, to check for doubleclicks
vector prevMouseClickedPos; // pos during previous mouse click, to check for doubleclicks
-float menu_enabled;
-float menu_enabled_time;
float pressed_key_time;
void HUD_Panel_Arrow_Action(float nPrimary)
{
HUD_Panel_UpdatePosSizeForId(highlightedPanel)
+ vector prev_pos, prev_size;
+ prev_pos = panel_pos;
+ prev_size = panel_size;
+
if (hudShiftState & S_ALT) // resize
{
highlightedAction = 1;
HUD_Panel_SetPos(pos);
}
+
+ HUD_Panel_UpdatePosSizeForId(highlightedPanel)
+
+ if (prev_pos != panel_pos || prev_size != panel_size)
+ {
+ // backup!
+ panel_pos_backup = prev_pos;
+ panel_size_backup = prev_size;
+ highlightedPanel_backup = highlightedPanel;
+ }
}
float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
{
if (bInputType == 1)
return true;
- disable_menu_alphacheck = 1;
menu_enabled = 1;
menu_enabled_time = time;
localcmd("menu_showhudexit\n");
}
+ else if(hudShiftState & S_CTRL)
+ {
+ if (mouseClicked)
+ return true;
+
+ if(nPrimary == K_SPACE) // enable/disable highlighted panel or dock
+ {
+ if (bInputType == 1)
+ return true;
+
+ if (highlightedPanel_prev != -1)
+ cvar_set(strcat("hud_panel_", panel_name), ftos(!(panel_enabled)));
+ else
+ cvar_set(strcat("hud_dock"), (autocvar_hud_dock == "") ? "dock" : "");
+ }
+ if(nPrimary == 'c') // copy highlighted panel size
+ {
+ if (bInputType == 1)
+ return true;
+
+ if (highlightedPanel_prev != -1)
+ {
+ panel_size_copied = panel_size;
+ highlightedPanel_copied = highlightedPanel_prev;
+ }
+ }
+ else if(nPrimary == 'v') // past copied size on the highlighted panel
+ {
+ if (bInputType == 1)
+ return true;
+
+ if (highlightedPanel_copied == -1 || highlightedPanel_prev == -1)
+ return true;
+
+ HUD_Panel_UpdatePosSizeForId(highlightedPanel_prev)
+
+ // reduce size if it'd go beyond screen boundaries
+ vector tmp_size = panel_size_copied;
+ if (panel_pos_x + panel_size_copied_x > 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)
}
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
- if (menu_enabled == 0) // menu dialog closed, enable normal alpha stuff again
- disable_menu_alphacheck = 0;
if (autocvar__menu_alpha == 0 && time - menu_enabled_time > 0.5)
menu_enabled = 0;
/*
- print("Disable menu_alphacheck: ", ftos(disable_menu_alphacheck), "\n");
+ print("menu_enabled: ", ftos(menu_enabled), "\n");
print("Highlighted: ", ftos(highlightedPanel), "\n");
print("Menu alpha: ", cvar_string("_menu_alpha"), "\n");
*/
- if(mouseClicked == 0 && disable_menu_alphacheck != 2 && highlightedPanel >= 0) { // don't reset these variables in disable_menu_alphacheck mode 2!
+ // instantly hide the editor cursor if we open the HUDExit dialog
+ // as hud_fade_alpha doesn't decrease to 0 in this case
+ // TODO: find a way to fade the cursor out even in this case
+ if(menu_enabled == 1 || (menu_enabled == 2 && !hud_fade_alpha))
+ return;
+
+ if(mouseClicked == 0 && menu_enabled != 2 && highlightedPanel >= 0) { // don't reset these variables in menu_enabled mode 2!
highlightedPanel = -1;
highlightedAction = 0;
}
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);
if(time - prevMouseClickedTime < 0.4 && prevMouseClicked == 0 && prevMouseClickedPos == mousepos && highlightedPanel >= 0)
{
mouseClicked = 0; // to prevent spam, I guess.
- disable_menu_alphacheck = 2;
- menu_enabled = 1;
+ menu_enabled = 2;
menu_enabled_time = time;
HUD_Panel_GetName(highlightedPanel)
localcmd("menu_showhudoptions ", panel_name, "\n");
cursorsize = '32 32 0';
if(highlightcheck == 0)
- drawpic(mousepos, strcat("gfx/menu/", cvar_string("menu_skin"), "/cursor.tga"), '32 32 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+ drawpic(mousepos, strcat("gfx/menu/", cvar_string("menu_skin"), "/cursor.tga"), '32 32 0', '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
else if(highlightcheck == 1)
- drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", cvar_string("menu_skin"), "/cursor_move.tga"), '32 32 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+ drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", cvar_string("menu_skin"), "/cursor_move.tga"), '32 32 0', '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
else if(highlightcheck == 2)
- drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", cvar_string("menu_skin"), "/cursor_resize.tga"), '32 32 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+ drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", cvar_string("menu_skin"), "/cursor_resize.tga"), '32 32 0', '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
else
- drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", cvar_string("menu_skin"), "/cursor_resize2.tga"), '32 32 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+ drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", cvar_string("menu_skin"), "/cursor_resize2.tga"), '32 32 0', '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
prevMouseClicked = mouseClicked;
}
case WEP_UZI: return 1;
case WEP_CAMPINGRIFLE: return 1;
case WEP_GRENADE_LAUNCHER: return 2;
+ case WEP_MINE_LAYER: return 2;
case WEP_ELECTRO: return 3;
case WEP_CRYLINK: return 3;
case WEP_HLAC: return 3;
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)
{
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
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);
vector wpnpos;
vector wpnsize;
+ float show_accuracy;
+ if(autocvar_hud_panel_weapons_accuracy && acc_levels)
+ show_accuracy = true;
+
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;
drawpic_aspect_skin(wpnpos, "weapon_current_bg", wpnsize, '1 1 1', fade * panel_fg_alpha, DRAWFLAG_NORMAL);
// draw the weapon accuracy
- if(acc_levels)
+ if(show_accuracy)
{
float weapon_hit, weapon_damage;
weapon_damage = weapon_fired[self.weapon-WEP_FIRST];
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)
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)
mySize -= '2 2 0' * panel_bg_padding;
}
- if(autocvar__hud_configure)
- {
- strength_time = 15;
- shield_time = 27;
- }
-
vector barpos, barsize;
vector picpos;
vector numpos;
mySize -= '2 2 0' * panel_bg_padding;
}
- float armor, health;
+ float armor, health, fuel;
armor = getstati(STAT_ARMOR);
health = getstati(STAT_HEALTH);
-
- float fuel;
- fuel = getstati(GetAmmoStat(4)); // how much fuel do we have?
+ fuel = getstati(STAT_FUEL);
if(autocvar__hud_configure)
{
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;
}
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) {
} 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)
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
} 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 {
float width_attacker;
string attacker, victim;
- float i, j;
+ float i, j, w;
for(j = 0; j < entries; ++j)
{
s = "";
a = 0;
}
- float w;
+ w = -1;
w = DEATH_WEAPONOF(killnotify_deathtype[j]);
// TODO: maybe print in team colors?
{
s = "notify_teamkill_red";
}
+ else if(killnotify_deathtype[j] == DEATH_TELEFRAG)
+ {
+ s = "notify_telefrag";
+ }
else if(killnotify_deathtype[j] == DEATH_DROWN)
{
s = "notify_water";
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) {
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;
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();
crecordtime_prev = t;
crecordtime_change_time = time;
}
+
+ vector textPos, medalPos;
+ float squareSize;
+ if(mySize_x > mySize_y) {
+ // text on left side
+ squareSize = min(mySize_y, mySize_x/2);
+ textPos = pos + eX * 0.5 * max(0, mySize_x/2 - squareSize) + eY * 0.5 * (mySize_y - squareSize);
+ medalPos = pos + eX * 0.5 * max(0, mySize_x/2 - squareSize) + eX * 0.5 * mySize_x + eY * 0.5 * (mySize_y - squareSize);
+ } else {
+ // text on top
+ squareSize = min(mySize_x, mySize_y/2);
+ textPos = pos + eY * 0.5 * max(0, mySize_y/2 - squareSize) + eX * 0.5 * (mySize_x - squareSize);;
+ medalPos = pos + eY * 0.5 * max(0, mySize_y/2 - squareSize) + eY * 0.5 * mySize_y + eX * 0.5 * (mySize_x - squareSize);
+ }
+
f = time - crecordtime_change_time;
if (f > 1) {
- drawstring_aspect(pos, "Personal best", eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(pos + eY * 0.25 * mySize_y, TIME_ENCODED_TOSTRING(t), eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(textPos, "Personal best", eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(textPos + eY * 0.25 * squareSize, TIME_ENCODED_TOSTRING(t), eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
} else {
- drawstring_aspect(pos, "Personal best", eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(pos + eY * 0.25 * mySize_y, TIME_ENCODED_TOSTRING(t), eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect_expanding(pos, "Personal best", eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
- drawstring_aspect_expanding(pos + eY * 0.25 * mySize_y, TIME_ENCODED_TOSTRING(t), eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
+ drawstring_aspect(textPos, "Personal best", eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(textPos + eY * 0.25 * squareSize, TIME_ENCODED_TOSTRING(t), eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect_expanding(pos, "Personal best", eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
+ drawstring_aspect_expanding(pos + eY * 0.25 * squareSize, TIME_ENCODED_TOSTRING(t), eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
}
// server record
f = time - srecordtime_change_time;
if (f > 1) {
- drawstring_aspect(pos + eY * 0.5 * mySize_y, "Server best", eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(pos + eY * 0.75 * mySize_y, TIME_ENCODED_TOSTRING(t), eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(textPos + eY * 0.5 * squareSize, "Server best", eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(textPos + eY * 0.75 * squareSize, TIME_ENCODED_TOSTRING(t), eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
} else {
- drawstring_aspect(pos + eY * 0.5 * mySize_y, "Server best", eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(pos + eY * 0.75 * mySize_y, TIME_ENCODED_TOSTRING(t), eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect_expanding(pos + eY * 0.5 * mySize_y, "Server best", eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
- drawstring_aspect_expanding(pos + eY * 0.75 * mySize_y, TIME_ENCODED_TOSTRING(t), eX * 0.5 * mySize_x + eY * 0.25 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
+ drawstring_aspect(textPos + eY * 0.5 * squareSize, "Server best", eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(textPos + eY * 0.75 * squareSize, TIME_ENCODED_TOSTRING(t), eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect_expanding(textPos + eY * 0.5 * squareSize, "Server best", eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
+ drawstring_aspect_expanding(textPos + eY * 0.75 * squareSize, TIME_ENCODED_TOSTRING(t), eX * squareSize + eY * 0.25 * squareSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
}
if (race_status != race_status_prev || race_status_name != race_status_name_prev) {
race_status_name_prev = strzone(race_status_name);
}
- pos_x += mySize_x/2;
// race "awards"
float a;
a = bound(0, race_status_time - time, 1);
string s;
- s = textShortenToWidth(race_status_name, mySize_y, '1 1 0' * 0.1 * mySize_y, stringwidth_colors);
+ s = textShortenToWidth(race_status_name, squareSize, '1 1 0' * 0.1 * squareSize, stringwidth_colors);
float rank;
if(race_status > 0)
rankname = race_PlaceName(rank);
vector namepos;
- namepos = pos + '0.5 0.9 0' * mySize_y - eX * stringwidth(s, TRUE, '1 1 0' * 0.1 * mySize_y);
+ namepos = medalPos + '0 0.8 0' * squareSize;
vector rankpos;
- rankpos = pos + '0.5 0.25 0' * mySize_y - eX * stringwidth(rankname, TRUE, '1 1 0' * 0.15 * mySize_y);
+ rankpos = medalPos + '0 0.15 0' * squareSize;
if(race_status == 0)
- drawpic_aspect_skin(pos, "race_newfail", '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(medalPos, "race_newfail", '1 1 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
else if(race_status == 1) {
- drawpic_aspect_skin(pos, "race_newtime", '1 1 0' * 0.9 * mySize_y, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring(namepos, s, '1 1 0' * 0.1 * mySize_y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawstring(rankpos, rankname, '1 1 0' * 0.15 * mySize_y, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newtime", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
} else if(race_status == 2) {
if(race_status_name == GetPlayerName(player_localentnum -1) || !race_myrank || race_myrank < rank)
- drawpic_aspect_skin(pos, "race_newrankgreen", '1 1 0' * 0.9 * mySize_y, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankgreen", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
else
- drawpic_aspect_skin(pos, "race_newrankyellow", '1 1 0' * 0.9 * mySize_y, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring(namepos, s, '1 1 0' * 0.1 * mySize_y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawstring(rankpos, rankname, '1 1 0' * 0.15 * mySize_y, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankyellow", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
} else if(race_status == 3) {
- drawpic_aspect_skin(pos, "race_newrecordserver", '1 1 0' * 0.9 * mySize_y, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring(namepos, s, '1 1 0' * 0.1 * mySize_y, panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawstring(rankpos, rankname, '1 1 0' * 0.15 * mySize_y, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrecordserver", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
}
if (race_status_time - time <= 0) {
{
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
}
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;
}
}
// 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)
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)
{
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";
}
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)) {
//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;
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)
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)
}
}
}
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)
}
}
pos = (vid_conheight - numsize_y) * cvar("cl_showspeed_position");
drawfont = hud_bigfont;
- drawstringcenter(eX + pos * eY, speed, numsize, '1 1 1', autocvar_hud_panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstringcenter(eX + pos * eY, speed, numsize, '1 1 1', autocvar_hud_panel_fg_alpha * hud_fade_alpha, DRAWFLAG_NORMAL);
if (cvar("cl_showspeed_z") == 1) {
zspeed = strcat(ftos(fabs(floor( pmove_vel_z * conversion_factor + 0.5 ))), unit);
- drawstringcenter(eX + pos * eY + numsize_y * eY, zspeed, numsize * 0.5, '1 1 1', autocvar_hud_panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstringcenter(eX + pos * eY + numsize_y * eY, zspeed, numsize * 0.5, '1 1 1', autocvar_hud_panel_fg_alpha * hud_fade_alpha, DRAWFLAG_NORMAL);
}
drawfont = hud_font;
f = bound(0, f * 10, 1);
acc_avg = acc_avg * (1 - f) + acceleration * f;
acceleration = acc_avg / getstatf(STAT_MOVEVARS_MAXSPEED);
+ if (acceleration == 0)
+ return;
pos = top - sz/2 * eY + (cvar("cl_showacceleration_position") * vid_conheight) * eY;
if (cvar("cl_showacceleration_color_custom"))
rgb = stov(cvar_string("cl_showacceleration_color"));
else {
- rgb = '1 1 1';
- if (acceleration < 0) {
+ if (acceleration < 0)
rgb = '1 .5 .5' - '0 .5 .5' * bound(0, -acceleration * 0.2, 1);
- } else if (acceleration > 0) {
+ else
rgb = '.5 1 .5' - '.5 0 .5' * bound(0, +acceleration * 0.2, 1);
- }
}
if (acceleration > 0)
- HUD_Panel_DrawProgressBar(pos, 0, acceleration * scale * '40 0 0' + sz * eY, rgb, alpha * autocvar_hud_panel_fg_alpha, DRAWFLAG_NORMAL);
- else if (acceleration < 0)
- HUD_Panel_DrawProgressBar(pos + acceleration * scale * '40 0 0', 0, -acceleration * scale * '40 0 0' + sz * eY, rgb, alpha * autocvar_hud_panel_fg_alpha, DRAWFLAG_NORMAL);
+ HUD_Panel_DrawProgressBar(pos, 0, acceleration * scale * '40 0 0' + sz * eY, rgb, alpha * autocvar_hud_panel_fg_alpha * hud_fade_alpha, DRAWFLAG_NORMAL);
+ else
+ HUD_Panel_DrawProgressBar(pos + acceleration * scale * '40 0 0', 0, -acceleration * scale * '40 0 0' + sz * eY, rgb, alpha * autocvar_hud_panel_fg_alpha * hud_fade_alpha, DRAWFLAG_NORMAL);
}
void HUD_Reset (void)
{
hud_skin_path = strcat("gfx/hud/", autocvar_hud_skin);
- if(disable_menu_alphacheck == 1)
- menu_fade_alpha = 1;
+ // global hud alpha fade
+ if(menu_enabled == 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);
- hud_border_thickness = bound(0, cvar("hud_border_thickness"), 5);
- hud_accuracy_border_thickness = bound(0, cvar_or("hud_accuracy_border_thickness", 1), 5);
+ 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_fontsize = HUD_GetFontsize("hud_fontsize");
- hud_fontsize_spec = HUD_GetFontsize("hud_fontsize_spec");
+
+ if(!autocvar__hud_configure && !hud_fade_alpha)
+ return;
// Drawing stuff
}
}
- float f;
- vector color;
- if((teamplay) && autocvar_hud_dock_color_team) {
- f = stof(getplayerkey(player_localentnum - 1, "colors"));
- color = colormapPaletteColor(mod(f, 16), 1) * autocvar_hud_dock_color_team;
- }
- else if(autocvar_hud_configure_teamcolorforced && autocvar__hud_configure && autocvar_hud_dock_color_team) {
- color = '1 0 0' * autocvar_hud_dock_color_team;
- }
- else if(autocvar_hud_dock_color == "shirt") {
- f = stof(getplayerkey(player_localentnum - 1, "colors"));
- color = colormapPaletteColor(floor(f / 16), 0);
- }
- else if(autocvar_hud_dock_color == "pants") {
- f = stof(getplayerkey(player_localentnum - 1, "colors"));
- color = colormapPaletteColor(mod(f, 16), 1);
- }
- else
- color = stov(autocvar_hud_dock_color);
-
// draw the dock
if(autocvar_hud_dock != "" && autocvar_hud_dock != "0")
{
+ float f;
+ vector color;
+ if((teamplay) && autocvar_hud_dock_color_team) {
+ f = stof(getplayerkey(player_localentnum - 1, "colors"));
+ color = colormapPaletteColor(mod(f, 16), 1) * autocvar_hud_dock_color_team;
+ }
+ else if(autocvar_hud_configure_teamcolorforced && autocvar__hud_configure && autocvar_hud_dock_color_team) {
+ color = '1 0 0' * autocvar_hud_dock_color_team;
+ }
+ else if(autocvar_hud_dock_color == "shirt") {
+ f = stof(getplayerkey(player_localentnum - 1, "colors"));
+ color = colormapPaletteColor(floor(f / 16), 0);
+ }
+ else if(autocvar_hud_dock_color == "pants") {
+ f = stof(getplayerkey(player_localentnum - 1, "colors"));
+ color = colormapPaletteColor(mod(f, 16), 1);
+ }
+ else
+ color = stov(autocvar_hud_dock_color);
+
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
hud_configure_prev = autocvar__hud_configure;
if (!autocvar__hud_configure) // hud config mode disabled, enable normal alpha stuff again
- disable_menu_alphacheck = 0;
+ if (menu_enabled)
+ menu_enabled = 0;
}
float log(float f);
+vector centerprint_start;
+
float panel_order[HUD_PANEL_NUM];
string hud_panelorder_prev;
#define MAX_ACCURACY_LEVELS 10
float acc_lev[MAX_ACCURACY_LEVELS];
float acc_levels;
+string acc_color_levels;
float complain_weapon;
string complain_weapon_name;
float last_weapon;
float weapontime;
+float weaponprevtime;
float teamnagger;
-float hud_accuracy_hud;
-float hud_border_thickness;
-float hud_accuracy_border_thickness;
float hud_configure_checkcollisions;
float hud_configure_prev;
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 menu_enabled; // 1 showing the entire HUD, 2 showing only the clicked panel
+float menu_enabled_time;
+
+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;
// ----------------------
// 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) {\
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");\
+ }\
}\
}\
}
panel_bg_alpha_str = ftos(autocvar_hud_panel_bg_alpha);\
}\
panel_bg_alpha = stof(panel_bg_alpha_str);\
-if(autocvar__hud_configure && disable_menu_alphacheck == 2 && highlightedPanel == active_panel) {\
+if(autocvar__hud_configure && menu_enabled == 2 && highlightedPanel == active_panel) {\
panel_bg_alpha = (1 - autocvar__menu_alpha) * max(autocvar_hud_configure_bg_minalpha, panel_bg_alpha) + autocvar__menu_alpha * panel_bg_alpha;\
} else if(autocvar__hud_configure) {\
panel_bg_alpha = max(autocvar_hud_configure_bg_minalpha, panel_bg_alpha);\
} 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;\
+} if(!(menu_enabled == 2 && highlightedPanel == active_panel)) {\
+ panel_bg_alpha *= hud_fade_alpha;\
}
// Get value for panel_fg_alpha. Also do various minalpha checks
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;
+if(!(menu_enabled == 2 && highlightedPanel == active_panel))\
+ panel_fg_alpha *= hud_fade_alpha;
// Get border. See comments above, it's similar.
#define HUD_Panel_GetBorder()\
panel_bg_border_str = autocvar_hud_panel_##name##_bg_border; \
panel_bg_padding_str = autocvar_hud_panel_##name##_bg_padding; \
HUD_Panel_StringVars()\
-if(disable_menu_alphacheck == 2 && active_panel == highlightedPanel) {\
+if(menu_enabled == 2 && active_panel == highlightedPanel) {\
HUD_Panel_GetMenuSize()\
HUD_Panel_GetMenuPos()\
}
panel_pos = autocvar_hud_panel_##name##_pos; \
panel_size = autocvar_hud_panel_##name##_size; \
HUD_Panel_GetScaledVectors()\
-if(disable_menu_alphacheck == 2 && active_panel == highlightedPanel) {\
+if(menu_enabled == 2 && active_panel == highlightedPanel) {\
HUD_Panel_GetMenuSize()\
HUD_Panel_GetMenuPos()\
}\
.float itime1, itime2;
void InterpolateOrigin_Reset()
{
- self.iflags &~= (IFLAG_PREVALID | IFLAG_VALID);
+ self.iflags &~= IFLAG_INTERNALMASK;
self.itime1 = self.itime2 = 0;
}
void InterpolateOrigin_Note()
{
float dt;
+ float f0;
dt = time - self.itime2;
+ f0 = self.iflags;
if(self.iflags & IFLAG_PREVALID)
self.iflags |= IFLAG_VALID;
else
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)
{
fixedmakevectors(self.angles);
- self.iforward1 = self.iforward2;
- self.iup1 = self.iup2;
+ if(f0 & IFLAG_VALID)
+ {
+ self.iforward1 = self.iforward2;
+ self.iup1 = self.iup2;
+ }
+ else
+ {
+ self.iforward1 = v_forward;
+ self.iup1 = v_up;
+ }
self.iforward2 = v_forward;
self.iup2 = v_up;
}
InterpolateOrigin_Do();
if(self.count & 0x80)
{
- traceline(self.origin, self.velocity, 0, self);
+ if(self.count & 0x10)
+ {
+ trace_endpos = self.velocity,
+ trace_dphitq3surfaceflags = 0;
+ }
+ else
+ traceline(self.origin, self.velocity, 0, self);
}
else
{
- makevectors(self.angles);
- traceline(self.origin, self.origin + v_forward * 32768, 0, self);
- if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+ if(self.count & 0x10)
+ {
+ makevectors(self.angles);
trace_endpos = self.origin + v_forward * 1048576;
+ trace_dphitq3surfaceflags = Q3SURFACEFLAG_SKY;
+ }
+ else
+ {
+ makevectors(self.angles);
+ traceline(self.origin, self.origin + v_forward * 32768, 0, self);
+ if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+ trace_endpos = self.origin + v_forward * 1048576;
+ }
}
if(self.scale != 0)
{
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))
// 30 bytes, or 13 bytes for just moving
f = ReadByte();
- self.count = (f & 0xE0);
+ self.count = (f & 0xF0);
if(self.count & 0x80)
self.iflags = IFLAG_VELOCITY;
self.scale *= ReadByte() / 16.0; // beam radius
self.modelscale *= ReadByte() / 16.0; // dlight radius
}
- self.cnt = ReadShort() - 1; // effect number
+ if((f & 0x80) || !(f & 0x10))
+ self.cnt = ReadShort() - 1; // effect number
+ else
+ self.cnt = 0;
}
if(f & 2)
{
vector hud_fontsize;
-vector hud_fontsize_spec;
float RANKINGS_RECEIVED_CNT;
string grecordholder[RANKINGS_CNT];
pos_x = pos_x + text_size*0.5 - img_size_x*0.5;
pos_y = pos_y - img_size_y;
- pos += hud_border_thickness * '1 1 0';
- img_size -= (hud_border_thickness * 2) * '1 1 0';
+ pos += autocvar_scoreboard_border_thickness * '1 1 0';
+ img_size -= (autocvar_scoreboard_border_thickness * 2) * '1 1 0';
if(pic == "")
{
drawfill(pos, img_size, '.5 .5 .5', .7, DRAWFLAG_NORMAL);
{
drawpic(pos, pic, img_size, '1 1 1', 1, DRAWFLAG_NORMAL);
}
-
- drawpic(pos + '1 0 0', strcat("gfx/hud/num_", ftos(id+1)), (img_size_y / 5) * '1 1 0', '1 1 1', 0.6, DRAWFLAG_NORMAL);
- if(id == mv_ownvote || pic == "")
- {
- drawborderlines(hud_border_thickness, pos, img_size, rgb, 1, DRAWFLAG_NORMAL);
- drawpic(pos + '1 0 0', strcat("gfx/hud/num_", ftos(id+1)), (img_size_y / 5) * '1 1 0', rgb, 0.6, DRAWFLAG_NORMAL);
- }
+ if(id == mv_ownvote)
+ drawborderlines(autocvar_scoreboard_border_thickness, pos, img_size, rgb, 1, DRAWFLAG_NORMAL);
else
- {
- drawborderlines(hud_border_thickness, pos, img_size, '0 0 0', 1, DRAWFLAG_NORMAL);
- drawpic(pos + '1 0 0', strcat("gfx/hud/num_", ftos(id+1)), (img_size_y / 5) * '1 1 0', '1 1 1', 0.6, DRAWFLAG_NORMAL);
- }
+ drawborderlines(autocvar_scoreboard_border_thickness, pos, img_size, '0 0 0', 1, DRAWFLAG_NORMAL);
+
+ if(id == mv_selection)
+ drawfill(pos, img_size, '1 1 1', 0.1, DRAWFLAG_NORMAL);
}
void MapVote_DrawAbstain(vector pos, float isize, float tsize, float count, float id)
// 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 = "";
}
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;
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);
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);
}
}
//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);
}
}
}
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;
}
}
}
+
+void DrawCircleClippedPic(vector centre, float radius, string pic, float f, vector rgb, float a, float drawflag)
+{
+ float x, y, q, d;
+ vector ringsize, v, t;
+ ringsize = radius * '1 1 0';
+
+ x = cos(f * 2 * M_PI);
+ y = sin(f * 2 * M_PI);
+ q = fabs(x) + fabs(y);
+ x /= q;
+ y /= q;
+
+ if(f >= 1)
+ {
+ // draw full rectangle
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y += 0.5 * ringsize_y; t += '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y -= 0.5 * ringsize_y; t -= '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ R_EndPolygon();
+
+ d = q - 1;
+ if(d > 0)
+ {
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ }
+ }
+ else if(f > 0.75)
+ {
+ // draw upper and first triangle
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y += 0.5 * ringsize_y; t += '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ R_EndPolygon();
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y -= 0.5 * ringsize_y; t -= '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ d = q - 0.75;
+ if(d <= 0)
+ R_EndPolygon();
+ }
+ else if(f > 0.5)
+ {
+ // draw upper triangle
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y += 0.5 * ringsize_y; t += '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ R_EndPolygon();
+
+ d = q - 0.5;
+ if(d > 0)
+ {
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ }
+ }
+ else if(f > 0.25)
+ {
+ // draw first triangle
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y += 0.5 * ringsize_y; t += '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ d = q - 0.25;
+ if(d <= 0)
+ R_EndPolygon();
+ }
+ else
+ {
+ d = q;
+ if(d > 0)
+ {
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ }
+ }
+
+ if(d > 0)
+ {
+ v = centre; t = '0.5 0.5 0';
+ v_x += x * 0.5 * ringsize_x; t += x * '0.5 0.5 0';
+ v_y += y * 0.5 * ringsize_y; t += y * '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ R_EndPolygon();
+ }
+}
remove(self);
return;
}
+ self.drawmask = MASK_NORMAL;
if(self.scale <= 0)
+ {
+ self.drawmask = 0;
return;
- R_AddEntity(self);
+ }
}
void Ent_ModelEffect(float isNew)
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;
}
void Net_ReadNexgunBeamParticle()
{
vector shotorg, endpos;
+ float charge;
shotorg_x = ReadCoord(); shotorg_y = ReadCoord(); shotorg_z = ReadCoord();
endpos_x = ReadCoord(); endpos_y = ReadCoord(); endpos_z = ReadCoord();
+ charge = ReadByte() / 255.0;
pointparticles(particleeffectnum("nex_muzzleflash"), shotorg, normalize(endpos - shotorg) * 1000, 1);
//draw either the old v2.3 beam or the new beam
+ charge = sqrt(charge); // divide evenly among trail spacing and alpha
+ particles_alphamin = particles_alphamax = charge;
if (cvar("cl_particles_oldnexbeam") && (getstati(STAT_ALLOW_OLDNEXBEAM) || isdemo()))
- WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3"), shotorg, endpos);
+ WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("TE_TEI_G3"), shotorg, endpos, charge, 1);
else
- WarpZone_TrailParticles(world, particleeffectnum("nex_beam"), shotorg, endpos);
+ WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("nex_beam"), shotorg, endpos, charge, 1);
}
interpolate.qh
teamradar.qh
hud.qh
+scoreboard.qh
waypointsprites.qh
movetypes.qh
prandom.qh
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
{
else
Projectile_ResetTrail(trailorigin);
+ self.drawmask = 0;
+
if(!drawn)
return;
break;
}
- R_AddEntity(self);
+ self.drawmask = MASK_NORMAL;
}
void loopsound(entity e, float ch, string samp, float vol, float attn)
case PROJECTILE_ELECTRO_BEAM: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
case PROJECTILE_GRENADE: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
case PROJECTILE_GRENADE_BOUNCING: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
+ case PROJECTILE_MINE: setmodel(self, "models/mine.md3");self.traileffect = particleeffectnum(""); break;
case PROJECTILE_LASER: setmodel(self, "models/laser.mdl");self.traileffect = particleeffectnum(""); break;
case PROJECTILE_HLAC: setmodel(self, "models/hlac_bullet.md3");self.traileffect = particleeffectnum(""); break;
case PROJECTILE_PORTO_RED: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_WIZSPIKE"); self.scale = 4; break;
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;
self.move_bounce_stopspeed = g_balance_grenadelauncher_secondary_bouncestop;
break;
+ case PROJECTILE_MINE:
+ self.mins = '-4 -4 -4';
+ self.maxs = '4 4 4';
+ break;
case PROJECTILE_PORTO_RED:
self.colormod = '2 1 1';
self.alphamod = 0.5;
precache_model("models/ebomb.mdl");
precache_model("models/elaser.mdl");
precache_model("models/grenademodel.md3");
+ precache_model("models/mine.md3");
precache_model("models/hagarmissile.mdl");
precache_model("models/hlac_bullet.md3");
precache_model("models/laser.mdl");
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)
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;
+ tmp_y += autocvar_scoreboard_border_thickness;
tmp_y += body_table_height;
- drawborderlines(hud_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg, DRAWFLAG_NORMAL); // more transparency for the scoreboard
+ drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg, DRAWFLAG_NORMAL); // more transparency for the scoreboard
// separator header/table
pos_y += 1.25 * hud_fontsize_y;
- tmp_y = hud_border_thickness;
+ tmp_y = autocvar_scoreboard_border_thickness;
drawfill(pos, tmp, '0 0 0', scoreboard_alpha_bg, DRAWFLAG_NORMAL);
- pos_y += hud_border_thickness;
+ pos_y += autocvar_scoreboard_border_thickness;
// 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);
// go back to the top to make alternated columns highlighting and to print the strings
pos_y -= 1.25 * hud_fontsize_y;
- pos_y -= hud_border_thickness;
+ pos_y -= autocvar_scoreboard_border_thickness;
pos += '1 1 0';
if (scoreboard_highlight)
{
column_dim_y = 1.25 * hud_fontsize_y; // header
- column_dim_y += hud_border_thickness;
+ column_dim_y += autocvar_scoreboard_border_thickness;
column_dim_y += body_table_height;
}
pos_x = xmin;
pos_y += 1.25 * hud_fontsize_y; // skip the header
- pos_y += hud_border_thickness;
+ pos_y += autocvar_scoreboard_border_thickness;
// fill the table and draw the rows
i = 0;
return 1;
else if (intermission == 1)
return 1;
- else if (intermission == 2)
- return 1;
else if (getstati(STAT_HEALTH) <= 0 && cvar("cl_deathscoreboard"))
return 1;
- else if(scoreboard_showscores_force)
+ else if (scoreboard_showscores_force)
return 1;
return 0;
}
{
float i;
float weapon_hit, weapon_damage, weapon_stats;
- float fontsize = 40 * 1/3;
float weapon_cnt = WEP_COUNT - 3; // either minstanex/nex are hidden, no port-o-launch, no tuba
float rows;
if(cvar("scoreboard_accuracy_doublerows"))
else
rows = 1;
float height = 40;
-
- if(warmup_stage)
- {
- return pos;
- }
+ float fontsize = height * 1/3;
+ float weapon_height = height * 2/3;
+ float weapon_width = sbwidth / weapon_cnt;
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);
- drawborderlines(hud_accuracy_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, 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(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
// column highlighting
for(i = 0; i < weapon_cnt/rows; ++i)
{
if(!mod(i, 2))
- drawfill(pos + '1 0 0' * (sbwidth/weapon_cnt) * rows * i, '0 1 0' * height * rows + '1 0 0' * (sbwidth/weapon_cnt) * rows, '0 0 0', scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
+ drawfill(pos + '1 0 0' * weapon_width * rows * i, '0 1 0' * height * rows + '1 0 0' * weapon_width * rows, '0 0 0', scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
}
// row highlighting
for(i = 0; i < rows; ++i)
{
- drawfill(pos + '0 1 0' * height * (2/3) + '0 1 0' * height * i, '1 0 0' * sbwidth + '0 1 0' * fontsize, '1 1 1', scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
+ drawfill(pos + '0 1 0' * weapon_height + '0 1 0' * height * i, '1 0 0' * sbwidth + '0 1 0' * fontsize, '1 1 1', scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
}
drawfont = hud_bigfont;
float weapons_with_stats;
weapons_with_stats = 0;
if(rows == 2)
- pos_x += sbwidth/weapon_cnt / 2;
+ pos_x += weapon_width / 2;
if(getstati(STAT_SWITCHWEAPON) == WEP_MINSTANEX)
g_minstagib = 1; // TODO: real detection for minstagib?
+ if (!acc_levels)
+ rgb = '1 1 1';
+
for(i = WEP_FIRST; i <= WEP_LAST; ++i)
{
self = get_weaponinfo(i);
weapon_alpha = 0.2 * scoreboard_alpha_fg;
// weapon icon
- drawpic_aspect_skin(pos, strcat("weapon", self.netname), '1 0 0' * sbwidth * (1/weapon_cnt) + '0 1 0' * height * (2/3), '1 1 1', weapon_alpha, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(pos, strcat("weapon", self.netname), '1 0 0' * weapon_width + '0 1 0' * weapon_height, '1 1 1', weapon_alpha, DRAWFLAG_NORMAL);
// the accuracy
if(weapon_damage) {
weapons_with_stats += 1;
s = strcat(ftos(weapon_stats),"%");
float padding;
- padding = ((sbwidth/weapon_cnt) - stringwidth(s, FALSE, '1 0 0' * fontsize)) / 2; // center the accuracy value
+ padding = (weapon_width - stringwidth(s, FALSE, '1 0 0' * fontsize)) / 2; // center the accuracy value
float weapon_hit, weapon_damage;
weapon_damage = weapon_fired[self.weapon-WEP_FIRST];
weapon_stats = floor(100 * weapon_hit / weapon_damage);
}
- // find the max level lower than weapon_stats
- float j;
- j = acc_levels-1;
- while ( j && weapon_stats < acc_lev[j] )
- --j;
-
- // inject color j+1 in color j, how much depending on how much weapon_stats is higher than level j
- float factor;
- factor = (weapon_stats - acc_lev[j]) / (acc_lev[j+1] - acc_lev[j]);
- rgb = acc_color(j);
- rgb = rgb + factor * (acc_color(j+1) - rgb);
+ if (acc_levels)
+ {
+ // find the max level lower than weapon_stats
+ float j;
+ j = acc_levels-1;
+ while ( j && weapon_stats < acc_lev[j] )
+ --j;
+
+ // inject color j+1 in color j, how much depending on how much weapon_stats is higher than level j
+ float factor;
+ factor = (weapon_stats - acc_lev[j]) / (acc_lev[j+1] - acc_lev[j]);
+ rgb = acc_color(j);
+ rgb = rgb + factor * (acc_color(j+1) - rgb);
+ }
- drawstring(pos + '1 0 0' * padding + '0 1 0' * height * (2/3), s, '1 1 0' * fontsize, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+ drawstring(pos + '1 0 0' * padding + '0 1 0' * weapon_height, s, '1 1 0' * fontsize, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
}
- pos_x += sbwidth/weapon_cnt * rows;
+ pos_x += weapon_width * rows;
if(rows == 2 && i == 6) {
pos_x -= sbwidth;
pos_y += height;
average_accuracy = floor(average_accuracy / weapons_with_stats);
if(rows == 2)
- pos_x -= sbwidth/weapon_cnt / 2;
+ pos_x -= weapon_width / 2;
pos_x -= sbwidth;
pos_y += height;
+
+ pos_y += 1.25 * hud_fontsize_y;
return pos;
}
{
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;
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);
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);
- drawborderlines(hud_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, 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(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
// row highlighting
for(i = 0; i<RANKINGS_RECEIVED_CNT; ++i)
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()
{
- HUD_UpdatePlayerTeams();
-
float hud_woulddrawscoreboard;
- hud_woulddrawscoreboard = HUD_WouldDrawScoreboard();
+ hud_woulddrawscoreboard = scoreboard_active;
if(hud_woulddrawscoreboard != hud_woulddrawscoreboard_prev) {
hud_woulddrawscoreboard_change = time;
hud_woulddrawscoreboard_prev = hud_woulddrawscoreboard;
}
- float scoreboard_fadeinspeed = cvar_or("scoreboard_fadeinspeed", 10);
- float scoreboard_fadeoutspeed = cvar_or("scoreboard_fadeoutspeed", 5);
if(hud_woulddrawscoreboard) {
+ float scoreboard_fadeinspeed = cvar_or("scoreboard_fadeinspeed", 10);
if (scoreboard_fadeinspeed)
scoreboard_fade_alpha = bound (0, (time - hud_woulddrawscoreboard_change) * scoreboard_fadeinspeed, 1);
else
scoreboard_fade_alpha = 1;
}
- else
+ else {
+ float scoreboard_fadeoutspeed = cvar_or("scoreboard_fadeoutspeed", 5);
if (scoreboard_fadeoutspeed)
scoreboard_fade_alpha = bound (0, (1/scoreboard_fadeoutspeed - (time - hud_woulddrawscoreboard_change)) * scoreboard_fadeoutspeed, 1);
else
scoreboard_fade_alpha = 0;
+ }
if not(scoreboard_fade_alpha)
return;
+ HUD_UpdatePlayerTeams();
+
scoreboard_alpha_bg = cvar("scoreboard_alpha_bg") * scoreboard_fade_alpha * (1 - cvar("_menu_alpha"));
scoreboard_alpha_fg = cvar_or("scoreboard_alpha_fg", 1.0) * scoreboard_fade_alpha * (1 - cvar("_menu_alpha"));
scoreboard_highlight = cvar("scoreboard_highlight");
vector rgb, pos, tmp;
entity pl, tm;
- sbwidth = HUD_GetWidth(6.5 * hud_fontsize_y);
+ xmin = cvar("scoreboard_offset_left") * vid_conwidth;
+ ymin = cvar("con_notify") * cvar("con_notifysize");
- xmin = 0.5 * (vid_conwidth - sbwidth);
- ymin = SCOREBOARD_OFFSET;
+ xmax = (1 - cvar("scoreboard_offset_right")) * vid_conwidth;
+ ymax = vid_conheight - ymin;
- xmax = vid_conwidth - xmin;
- ymax = vid_conheight - 0.2*vid_conheight;
+ sbwidth = xmax - xmin;
// Initializes position
pos_x = xmin;
// 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;
// Draw the scoreboard
- vector bg_size;
- bg_size = drawgetimagesize("gfx/hud/scoreboard_scoreboard_bg");
+ vector bg_size = drawgetimagesize("gfx/scoreboard/scoreboard_bg") * cvar("scoreboard_bg_scale");
if(teamplay)
{
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);
}
}
pos = HUD_DrawScoreboardRankings(pos, pl, rgb, bg_size);
}
- else if(cvar("scoreboard_accuracy") && spectatee_status != -1) {
+ else if(cvar("scoreboard_accuracy") && spectatee_status != -1 && !warmup_stage) {
if(teamplay)
pos = HUD_DrawScoreboardAccuracyStats(pos, GetTeamRGB(myteam), bg_size);
else
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;
// background
drawpic(pos, "gfx/scoreboard/accuracy_bg", fill_size , fill_colour, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
- drawborderlines(hud_border_thickness, pos, fill_size, border_colour, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+ drawborderlines(autocvar_scoreboard_border_thickness, pos, fill_size, border_colour, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
// the weapon
drawpic(pos, strcat("gfx/weapons/weapon", self.netname), '1 0.5 0' * fill_size_x , '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
// background
drawpic(pos, "gfx/scoreboard/accuracy_bg", fill_size , fill_colour, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
- drawborderlines(hud_border_thickness, pos, fill_size, border_colour, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+ drawborderlines(autocvar_scoreboard_border_thickness, pos, fill_size, border_colour, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
// the weapon
drawpic(pos, strcat("gfx/weapons/weapon", self.netname), '1 0.5 0' * fill_size_x , '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
--- /dev/null
+float HUD_WouldDrawScoreboard(void);
+float scoreboard_active;
+float scoreboard_fade_alpha;
}
}
music_trigger = world;
+
+ if(best)
+ bgmtime = getsoundtime(best, CHAN_VOICE);
+ else
+ bgmtime = gettime(GETTIME_CDTRACK);
}
void Net_TargetMusic()
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();
};
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();
}
{
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;
.float lip;
.float bgmscriptangular;
+.float lodmodelindex0, lodmodelindex1, lodmodelindex2;
+.float loddistance1, loddistance2;
+.vector saved;
void Ent_Wall_Draw()
{
float f;
+ float d;
vector save;
var .vector fld;
+ if(self.bgmscriptangular)
+ self.angles = self.saved;
+ else
+ self.origin = self.saved;
+
+ if(self.lodmodelindex1)
+ {
+ d = cvar("loddebug");
+ if(d > 0)
+ {
+ if(d == 1)
+ self.modelindex = self.lodmodelindex0;
+ else if(d == 2 || !self.lodmodelindex2)
+ self.modelindex = self.lodmodelindex1;
+ else // if(d == 3)
+ self.modelindex = self.lodmodelindex2;
+ }
+ else
+ {
+ d = vlen(NearestPointOnBox(self, view_origin) - view_origin);
+ if(d < self.loddistance1)
+ self.modelindex = self.lodmodelindex0;
+ else if(!self.lodmodelindex2 || d < self.loddistance2)
+ self.modelindex = self.lodmodelindex1;
+ else
+ self.modelindex = self.lodmodelindex2;
+ }
+ }
+
InterpolateOrigin_Do();
if(self.bgmscriptangular)
- fld = angles;
+ self.saved = self.angles;
else
- fld = origin;
-
- save = self.fld;
+ self.saved = self.origin;
+
f = BGMScript(self);
if(f >= 0)
{
self.alpha = 1;
if(self.alpha >= ALPHA_MIN_VISIBLE)
- R_AddEntity(self);
-
- self.fld = save;
+ self.drawmask = MASK_NORMAL;
+ else
+ self.drawmask = 0;
}
void Ent_Wall_Remove()
InterpolateOrigin_Undo();
self.iflags = IFLAG_ANGLES;
+ if(self.bgmscriptangular)
+ self.angles = self.saved;
+ else
+ self.origin = self.saved;
+
f = ReadByte();
if(f & 1)
if(f & 8)
{
- self.modelindex = ReadShort();
+ if(f & 0x80)
+ {
+ self.lodmodelindex0 = ReadShort();
+ self.loddistance1 = ReadShort();
+ self.lodmodelindex1 = ReadShort();
+ self.loddistance2 = ReadShort();
+ self.lodmodelindex2 = ReadShort();
+ }
+ else
+ {
+ self.modelindex = ReadShort();
+ self.loddistance1 = 0;
+ self.loddistance2 = 0;
+ }
self.solid = ReadByte();
- self.scale = ReadByte() / 16.0;
+ self.scale = ReadShort() / 256.0;
if(f & 0x20)
{
self.mins_x = ReadCoord();
InterpolateOrigin_Note();
+ if(self.bgmscriptangular)
+ self.saved = self.angles;
+ else
+ self.saved = self.origin;
+
self.entremove = Ent_Wall_Remove;
self.draw = Ent_Wall_Draw;
}
{
float dh, n, i, o, f;
string s, sname, sframes;
+
dh = search_begin("models/sprites/*_frame*.tga", FALSE, FALSE);
n = search_getsize(dh);
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));
+ sframes = substring(s, o + 6, strlen(s) - o - 6);
+ f = stof(sframes) + 1;
+ db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
+ }
+ search_end(dh);
+
+ dh = search_begin("models/sprites/*_frame*.jpg", FALSE, FALSE);
+ n = search_getsize(dh);
+ for(i = 0; i < n; ++i)
+ {
+ s = search_getfilename(dh, i);
+ s = substring(s, 15, strlen(s) - 15 - 4); // strip models/sprites/ and .jpg
o = strstrofs(s, "_frame", 0);
sname = strcat("/spriteframes/", substring(s, 0, o));
const float TE_CSQC_WEAPONCOMPLAIN = 113;
const float TE_CSQC_CAMPINGRIFLE_SCOPE = 115;
const float TE_CSQC_NEX_SCOPE = 116;
+const float TE_CSQC_CR_MAXBULLETS = 117;
const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
const float RACE_NET_CHECKPOINT_CLEAR = 1;
const float STAT_SHOTORG = 46; // compressShotOrigin
const float STAT_LEADLIMIT = 47;
const float STAT_BULLETS_LOADED = 48;
+const float STAT_NEX_CHARGE = 49;
// see DP source, quakedef.h
const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
// 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
// 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
float PROJECTILE_ELECTRO_BEAM = 6;
float PROJECTILE_GRENADE = 7;
float PROJECTILE_GRENADE_BOUNCING = 8;
-float PROJECTILE_LASER = 9;
-float PROJECTILE_HLAC = 10;
-float PROJECTILE_SEEKER = 11;
-float PROJECTILE_FLAC = 12;
-float PROJECTILE_PORTO_RED = 13;
-float PROJECTILE_PORTO_BLUE = 14;
-float PROJECTILE_HOOKBOMB = 15;
-float PROJECTILE_HAGAR = 16;
-float PROJECTILE_HAGAR_BOUNCING = 17;
-float PROJECTILE_BULLET_GLOWING = 18;
-float PROJECTILE_CRYLINK_BOUNCING = 19;
-float PROJECTILE_FIREBALL = 20;
-float PROJECTILE_FIREMINE = 21;
-float PROJECTILE_BULLET_GLOWING_TRACER = 22;
+float PROJECTILE_MINE = 9;
+float PROJECTILE_LASER = 10;
+float PROJECTILE_HLAC = 11;
+float PROJECTILE_SEEKER = 12;
+float PROJECTILE_FLAC = 13;
+float PROJECTILE_PORTO_RED = 14;
+float PROJECTILE_PORTO_BLUE = 15;
+float PROJECTILE_HOOKBOMB = 16;
+float PROJECTILE_HAGAR = 17;
+float PROJECTILE_HAGAR_BOUNCING = 18;
+float PROJECTILE_BULLET_GLOWING = 19;
+float PROJECTILE_CRYLINK_BOUNCING = 20;
+float PROJECTILE_FIREBALL = 21;
+float PROJECTILE_FIREMINE = 22;
+float PROJECTILE_BULLET_GLOWING_TRACER = 23;
float SPECIES_HUMAN = 0;
float SPECIES_ROBOT_SOLID = 1;
else
fputs(fh, strcat("cdtrack ", _MapInfo_Map_worldspawn_music, "\n"));
}
- else if(_MapInfo_Map_worldspawn_music)
+ else
{
n = tokenize_console(cvar_string("g_cdtracks_remaplist"));
s = strcat(" ", cvar_string("g_cdtracks_dontusebydefault"), " ");
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)
return 1;
}
+
+vector vec2(vector v)
+{
+ v_z = 0;
+ return v;
+}
+
+#ifndef MENUQC
+vector NearestPointOnBox(entity box, vector org)
+{
+ vector m1, m2, nearest;
+
+ m1 = box.mins + box.origin;
+ m2 = box.maxs + box.origin;
+
+ nearest_x = bound(m1_x, org_x, m2_x);
+ nearest_y = bound(m1_y, org_y, m2_y);
+ nearest_z = bound(m1_z, org_z, m2_z);
+
+ return nearest;
+}
+#endif
case HUD_PANEL_CHAT: panel_name = HUD_PANELNAME_CHAT; break; \
}\
HUD_Panel_GetName_Part2(id)
+
+vector vec2(vector v);
+
+#ifndef MENUQC
+vector NearestPointOnBox(entity box, vector org);
+#endif
#include "xonotic/dialog_hudpanel_engineinfo.c"
#include "xonotic/dialog_hudpanel_infomessages.c"
#include "xonotic/dialog_hudpanel_weapons.c"
+#include "xonotic/slider_picmip.c"
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);
}
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));
}
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);
}
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));
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);
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));
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));
float log(float f) = #532;
string(string format, ...) sprintf = #627;
+
+//DP_CRYPTO
+//idea: divVerent
+//darkplaces implementation: divVerent
+//field definitions: (MENUQC)
+string crypto_getkeyfp(string serveraddress) = #633; // retrieves the cached host key's CA fingerprint of a server given by IP address
+string crypto_getidfp(string serveraddress) = #634; // retrieves the cached host key fingerprint of a server given by IP address
+string crypto_getencryptlevel(string serveraddress) = #635; // 0 if never encrypting, 1 supported, 2 requested, 3 required, appended by list of allowed methods in order of preference ("AES128"), preceded by a space each
+//description:
SKINFLOAT(ALPHA_SERVERLIST_HIGHPING, 0.4);
SKINFLOAT(ALPHA_SERVERLIST_FAVORITE, 0.8);
SKINVECTOR(COLOR_SERVERLIST_FAVORITE, '1 1 1');
+ SKINFLOAT(ALPHA_SERVERLIST_IMPOSSIBLE, 0.7);
+ SKINVECTOR(COLOR_SERVERLIST_IMPOSSIBLE, '0.3 0.3 0.3');
// item: server info
SKINVECTOR(COLOR_SERVERINFO_NAME, '1 1 1');
ATTRIB(XonoticCrosshairButton, useDownAsChecked, float, 1)
ATTRIB(XonoticCrosshairButton, src3, string, string_null)
+ ATTRIB(XonoticCrosshairButton, src4, string, string_null)
ATTRIB(XonoticCrosshairButton, cvarName, string, string_null)
ATTRIB(XonoticCrosshairButton, cvarValueFloat, float, 0)
me.configureRadioButton(me, string_null, me.fontSize, me.image, theGroup, 0);
me.srcMulti = 1;
me.src3 = strzone(strcat("/gfx/crosshair", ftos(me.cvarValueFloat)));
+ me.src4 = "/gfx/crosshairdot";
}
void XonoticCrosshairButton_setChecked(entity me, float val)
{
sz = draw_PictureSize(me.src3);
sz = globalToBoxSize(sz, draw_scale);
- sz = sz * cvar("crosshair_size");
+ sz = (10 * '1 1 0' + sz * cvar("crosshair_size")) * 0.05; // (10 * '1 1 0' + ...) * 0.05 here to make visible size changes happen also at bigger sizes
if(sz_x > 0.95)
sz = sz * (0.95 / sz_x);
if(sz_y > 0.95)
sz = sz * (0.95 / sz_y);
draw_Picture('0.5 0.5 0' - 0.5 * sz, me.src3, sz, rgb, a);
+ if(cvar("crosshair_dot"))
+ draw_Picture('0.5 0.5 0' - 0.5 * sz * cvar("crosshair_dot_size"), me.src4, sz * cvar("crosshair_dot_size"), rgb, a * cvar("crosshair_dot_alpha"));
}
#endif
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)
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);
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);
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
me.TDempty(me, 0.2);
me.TD(me, 1, 2, e = makeXonoticRadioButton(1, "g_start_weapon_laser", "0", "No start weapons"));
e.cvarOffValue = "-1";
- makeMulti(e, "g_start_weapon_shotgun g_start_weapon_uzi g_start_weapon_grenadelauncher g_start_weapon_electro g_start_weapon_crylink g_start_weapon_nex g_start_weapon_hagar g_start_weapon_rocketlauncher g_start_weapon_campingrifle g_start_weapon_hlac g_start_weapon_seeker g_start_weapon_minstanex g_start_weapon_hook g_start_weapon_porto g_start_weapon_tuba");
+ makeMulti(e, "g_start_weapon_shotgun g_start_weapon_uzi g_start_weapon_grenadelauncher g_start_weapon_minelayer g_start_weapon_electro g_start_weapon_crylink g_start_weapon_nex g_start_weapon_hagar g_start_weapon_rocketlauncher g_start_weapon_campingrifle g_start_weapon_hlac g_start_weapon_seeker g_start_weapon_minstanex g_start_weapon_hook g_start_weapon_porto g_start_weapon_tuba");
me.gotoRC(me, me.rows - 1, 0);
me.TD(me, 1, me.columns, e = makeXonoticButton("OK", '0 0 0'));
ATTRIB(XonoticServerInfoDialog, title, string, "Server Information")
ATTRIB(XonoticServerInfoDialog, color, vector, SKINCOLOR_DIALOG_SERVERINFO)
ATTRIB(XonoticServerInfoDialog, intendedWidth, float, 0.68)
- ATTRIB(XonoticServerInfoDialog, rows, float, 11)
+ ATTRIB(XonoticServerInfoDialog, rows, float, 14)
ATTRIB(XonoticServerInfoDialog, columns, float, 12)
ATTRIB(XonoticServerInfoDialog, currentServerName, string, string_null)
ATTRIB(XonoticServerInfoDialog, currentServerMod, string, string_null)
ATTRIB(XonoticServerInfoDialog, currentServerVersion, string, string_null)
ATTRIB(XonoticServerInfoDialog, currentServerPing, string, string_null)
+ ATTRIB(XonoticServerInfoDialog, currentServerKey, string, string_null)
+ ATTRIB(XonoticServerInfoDialog, currentServerID, string, string_null)
+ ATTRIB(XonoticServerInfoDialog, currentServerEncrypt, string, string_null)
+ ATTRIB(XonoticServerInfoDialog, currentServerCanConnect, string, string_null)
ATTRIB(XonoticServerInfoDialog, nameLabel, entity, NULL)
ATTRIB(XonoticServerInfoDialog, cnameLabel, entity, NULL)
ATTRIB(XonoticServerInfoDialog, modLabel, entity, NULL)
ATTRIB(XonoticServerInfoDialog, versionLabel, entity, NULL)
ATTRIB(XonoticServerInfoDialog, pingLabel, entity, NULL)
+ ATTRIB(XonoticServerInfoDialog, keyLabel, entity, NULL)
+ ATTRIB(XonoticServerInfoDialog, idLabel, entity, NULL)
+ ATTRIB(XonoticServerInfoDialog, encryptLabel, entity, NULL)
+ ATTRIB(XonoticServerInfoDialog, canConnectLabel, entity, NULL)
ENDCLASS(XonoticServerInfoDialog)
float SLIST_FIELD_NAME;
me.currentServerType = strzone(typestr);
me.typeLabel.setText(me.typeLabel, me.currentServerType);
-
SLIST_FIELD_MAP = gethostcacheindexforkey("map");
me.currentServerMap = strzone(gethostcachestring(SLIST_FIELD_MAP, i));
me.mapLabel.setText(me.mapLabel, me.currentServerMap);
s = ftos(gethostcachenumber(SLIST_FIELD_PING, i));
me.currentServerPing = strzone(s);
me.pingLabel.setText(me.pingLabel, me.currentServerPing);
+
+ print(me.currentServerCName, "\n");
+
+ s = crypto_getidfp(me.currentServerCName);
+ if not(s)
+ s = "N/A";
+ me.currentServerID = strzone(s);
+ me.idLabel.setText(me.idLabel, me.currentServerID);
+
+ s = crypto_getkeyfp(me.currentServerCName);
+ if not(s)
+ s = "N/A";
+ me.currentServerKey = strzone(s);
+ me.keyLabel.setText(me.keyLabel, me.currentServerKey);
+
+ s = crypto_getencryptlevel(me.currentServerCName);
+ if(s == "")
+ {
+ if(cvar("crypto_aeslevel") >= 3)
+ me.currentServerEncrypt = "N/A (can't connect)";
+ else
+ me.currentServerEncrypt = "N/A";
+ }
+ else switch(stof(substring(s, 0, 1)))
+ {
+ case 0:
+ if(cvar("crypto_aeslevel") >= 3)
+ me.currentServerEncrypt = "not supported (can't connect)";
+ else
+ me.currentServerEncrypt = "not supported";
+ break;
+ case 1:
+ me.currentServerEncrypt = "supported";
+ break;
+ case 2:
+ me.currentServerEncrypt = "requested";
+ break;
+ case 3:
+ if(cvar("crypto_aeslevel") <= 0)
+ me.currentServerEncrypt = "required (can't connect)";
+ else
+ me.currentServerEncrypt = "required";
+ break;
+ }
+ me.encryptLabel.setText(me.encryptLabel, me.currentServerEncrypt);
}
void XonoticServerInfoDialog_fill(entity me)
e.allowCut = 1;
me.pingLabel = e;
+ me.TR(me);
+ me.TD(me, 1, 1.75, e = makeXonoticTextLabel(0, "CA:"));
+ me.TD(me, 1, 4.0, e = makeXonoticTextLabel(0, ""));
+ e.allowCut = 1;
+ me.keyLabel = e;
+
+ me.TR(me);
+ me.TD(me, 1, 1.75, e = makeXonoticTextLabel(0, "Key:"));
+ me.TD(me, 1, 4.0, e = makeXonoticTextLabel(0, ""));
+ e.allowCut = 1;
+ me.idLabel = e;
+
+ me.TR(me);
+ me.TD(me, 1, 1.75, e = makeXonoticTextLabel(0, "Encryption:"));
+ me.TD(me, 1, 4.0, e = makeXonoticTextLabel(0, ""));
+ e.allowCut = 1;
+ me.encryptLabel = e;
+
me.gotoRC(me, me.rows - 1, 0);
me.TD(me, 1, me.columns - 6, e = makeXonoticButton("Close", '0 0 0'));
}
me.gotoRC(me, 0, 3.5); me.setFirstColumn(me, me.currentColumn);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Field of View:"));
+ me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Field of view:"));
me.TD(me, 1, 2, e = makeXonoticSlider(60, 130, 1, "fov"));
me.TR(me);
me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Damage kick:"));
me.TR(me);
sl = makeXonoticSlider(0.45, 0.75, 0.01, "cl_bobcycle");
me.TD(me, 1, 1, e = makeXonoticSliderCheckBox(0, 1, sl, "View bobbing:"));
- me.TD(me, 1, 2, sl);
-
- me.TR(me);
+ me.TD(me, 1, 2, sl);
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Zoom Factor:"));
+ me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Zoom factor:"));
me.TD(me, 1, 2, e = makeXonoticSlider(2, 16, 0.5, "cl_zoomfactor"));
me.TR(me);
sl = makeXonoticSlider(1, 8, 0.5, "cl_zoomspeed");
e0.textEntity = main.weaponsDialog;
e0.allowCut = 1;
me.TR(me);
- me.TR(me);
- me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "crosshair_per_weapon", "Per weapon crosshairs"));
- me.TD(me, 1, 1.3, e = makeXonoticCheckBox(1, "crosshair_color_override", "& crosshair colors"));
+ me.TD(me, 1, 0.75, e = makeXonoticTextLabel(0, "Crosshair:"));
+ me.TD(me, 1, 1.00, e = makeXonoticCheckBox(0, "crosshair_per_weapon", "Per weapon"));
+ me.TD(me, 1, 1.25, e = makeXonoticCheckBox(1, "crosshair_color_override", "& Per weapon colors"));
setDependent(e, "crosshair_per_weapon", 1, 1);
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair:"));
+ me.TDempty(me, 0.5);
for(i = 1; i <= 10; ++i) {
me.TDNoMargin(me, 1, 2 / 10, e = makeXonoticCrosshairButton(3, i), '1 1 0');
setDependent(e, "crosshair_per_weapon", 0, 0);
}
me.TR(me);
- me.TDempty(me, 1);
+ me.TDempty(me, 0.5);
for(i = 11; i <= 20; ++i) {
me.TDNoMargin(me, 1, 2 / 10, e = makeXonoticCrosshairButton(3, i), '1 1 0');
setDependent(e, "crosshair_per_weapon", 0, 0);
}
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair Size:"));
- me.TD(me, 1, 2, e = makeXonoticSlider(0.40, 2, 0.05, "crosshair_size"));
+ me.TDempty(me, 0.2);
+ me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair size:"));
+ me.TD(me, 1, 1.8, e = makeXonoticSlider(0.10, 1.5, 0.05, "crosshair_size"));
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair Alpha:"));
- me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.01, "crosshair_color_alpha"));
+ me.TDempty(me, 0.2);
+ me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair alpha:"));
+ me.TD(me, 1, 1.8, e = makeXonoticSlider(0, 1, 0.1, "crosshair_color_alpha"));
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair Red:"));
- me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.01, "crosshair_color_red"));
+ me.TDempty(me, 0.2);
+ me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair red:"));
+ me.TD(me, 1, 1.8, e = makeXonoticSlider(0, 1, 0.01, "crosshair_color_red"));
setDependentOR(e, "crosshair_per_weapon", 0, 0, "crosshair_color_override", 1, 1);
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair Green:"));
- me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.01, "crosshair_color_green"));
+ me.TDempty(me, 0.2);
+ me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair green:"));
+ me.TD(me, 1, 1.8, e = makeXonoticSlider(0, 1, 0.01, "crosshair_color_green"));
setDependentOR(e, "crosshair_per_weapon", 0, 0, "crosshair_color_override", 1, 1);
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair Blue:"));
- me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.01, "crosshair_color_blue"));
+ me.TDempty(me, 0.2);
+ me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair blue:"));
+ me.TD(me, 1, 1.8, e = makeXonoticSlider(0, 1, 0.01, "crosshair_color_blue"));
setDependentOR(e, "crosshair_per_weapon", 0, 0, "crosshair_color_override", 1, 1);
+ me.TR(me);
+ me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_dot", "Enable centered dot"));
+ me.TR(me);
+ me.TDempty(me, 0.2);
+ me.TD(me, 1, 0.5, e = makeXonoticTextLabel(0, "Size:"));
+ me.TD(me, 1, 0.9, e = makeXonoticSlider(0.2, 2, 0.1, "crosshair_dot_size"));
+ setDependent(e, "crosshair_dot", 1, 1);
+ me.TD(me, 1, 0.5, e = makeXonoticTextLabel(0, "Alpha:"));
+ me.TD(me, 1, 0.9, e = makeXonoticSlider(0.10, 1, 0.1, "crosshair_dot_alpha"));
+ setDependent(e, "crosshair_dot", 1, 1);
me.TR(me);
me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Hit test:"));
me.TD(me, 1, 2/3, e = makeXonoticRadioButton(1, "crosshair_hittest", "0", "None"));
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);
me.TR(me);
me.TDempty(me, 0.4);
- me.TD(me, 1, 2.2, e = makeXonoticButton("HUD Setup", '0 0 0'));
+ me.TD(me, 1, 2.2, e = makeXonoticButton("Enter HUD editor", '0 0 0'));
e.onClick = HUDSetup_Join_Click;
e.onClickEntity = me;
me.TDempty(me, 0.5);
me.TR(me);
#ifdef ALLOW_FORCEMODELS
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Force Models:"));
+ me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Force models:"));
me.TD(me, 1, 2/3, e = makeXonoticRadioButton(2, string_null, string_null, "None"));
me.TD(me, 1, 2/3, e = makeXonoticRadioButton(2, "cl_forceplayermodelsfromxonotic", string_null, "Custom"));
me.TD(me, 1, 2/3, e = makeXonoticRadioButton(2, "cl_forceplayermodels", string_null, "All"));
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));
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");
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);
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))
{
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");
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
float IsFavorite(string srv)
{
+ string p;
float i, n;
+ if(srv == "")
+ return FALSE;
srv = netaddress_resolve(srv, 26000);
+ p = crypto_getidfp(srv);
n = tokenize_console(cvar_string("net_slist_favorites"));
for(i = 0; i < n; ++i)
- if(srv == netaddress_resolve(argv(i), 26000))
- return TRUE;
+ {
+ if(substring(argv(i), 0, 1) != "[" && strlen(argv(i)) == 44 && strstrofs(argv(i), ".", 0) < 0)
+ {
+ if(p)
+ if(argv(i) == p)
+ return TRUE;
+ }
+ else
+ {
+ if(srv == netaddress_resolve(argv(i), 26000))
+ return TRUE;
+ }
+ }
return FALSE;
}
void ToggleFavorite(string srv)
{
- string s, s0, s1, s2, srv_resolved;
- float i, n;
+ string s, s0, s1, s2, srv_resolved, p;
+ float i, n, f;
srv_resolved = netaddress_resolve(srv, 26000);
+ p = crypto_getidfp(srv_resolved);
s = cvar_string("net_slist_favorites");
n = tokenize_console(s);
+ f = 0;
for(i = 0; i < n; ++i)
- if(srv_resolved == netaddress_resolve(argv(i), 26000))
+ {
+ if(substring(argv(i), 0, 1) != "[" && strlen(argv(i)) == 44 && strstrofs(argv(i), ".", 0) < 0)
{
- s0 = s1 = s2 = "";
- if(i > 0)
- s0 = substring(s, 0, argv_end_index(i - 1));
- if(i < n-1)
- s2 = substring(s, argv_start_index(i + 1), -1);
- if(s0 != "" && s2 != "")
- s1 = " ";
- print("s0 = >>", s0, "<<\ns1 = >>", s1, "<<\ns2 = >>", s2, "<<\n");
- cvar_set("net_slist_favorites", strcat(s0, s1, s2));
- return;
+ if(p)
+ if(argv(i) != p)
+ continue;
}
+ else
+ {
+ if(srv_resolved != netaddress_resolve(argv(i), 26000))
+ continue;
+ }
+ s0 = s1 = s2 = "";
+ if(i > 0)
+ s0 = substring(s, 0, argv_end_index(i - 1));
+ if(i < n-1)
+ s2 = substring(s, argv_start_index(i + 1), -1);
+ if(s0 != "" && s2 != "")
+ s1 = " ";
+ cvar_set("net_slist_favorites", strcat(s0, s1, s2));
+ s = cvar_string("net_slist_favorites");
+ n = tokenize_console(s);
+ f = 1;
+ --i;
+ }
- s1 = "";
- if(s != "")
- s1 = " ";
- cvar_set("net_slist_favorites", strcat(s, " ", srv));
+ if(!f)
+ {
+ s1 = "";
+ if(s != "")
+ s1 = " ";
+ if(p)
+ cvar_set("net_slist_favorites", strcat(s, s1, p));
+ else
+ cvar_set("net_slist_favorites", strcat(s, s1, srv));
+ }
resorthostcache();
}
{
// layout: Ping, Server name, Map name, NP, TP, MP
string s;
- float p;
+ float p, q;
vector theColor;
float theAlpha;
theAlpha = theAlpha * (1 - SKINALPHA_SERVERLIST_FAVORITE) + SKINALPHA_SERVERLIST_FAVORITE;
}
+ s = gethostcachestring(SLIST_FIELD_CNAME, i);
+ q = stof(substring(crypto_getencryptlevel(s), 0, 1));
+ if((q <= 0 && cvar("crypto_aeslevel") >= 3) || (q >= 3 && cvar("crypto_aeslevel") <= 0))
+ {
+ theColor = SKINCOLOR_SERVERLIST_IMPOSSIBLE;
+ theAlpha = SKINALPHA_SERVERLIST_IMPOSSIBLE;
+ }
+ // TODO show an icon for encryption status
+
s = ftos(p);
draw_Text(me.realUpperMargin * eY + (me.columnPingSize - draw_TextWidth(s, 0, me.realFontSize)) * eX, s, me.realFontSize, theColor, theAlpha, 0);
s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_NAME, i), me.columnNameSize, 0, me.realFontSize);
--- /dev/null
+#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
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))
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)
{
<Unit filename="w_electro.qc" />
<Unit filename="w_fireball.qc" />
<Unit filename="w_grenadelauncher.qc" />
+ <Unit filename="w_minelayer.qc" />
<Unit filename="w_hagar.qc" />
<Unit filename="w_hlac.qc" />
<Unit filename="w_hook.qc" />
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
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));
}
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)
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);
//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;
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)
{
// 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);
local float nex ; nex =-1000;
local float hagar ; hagar =-1000;
local float grenade ; grenade =-1000;
+ local float mine ; mine =-1000;
local float electro ; electro =-1000;
local float crylink ; crylink =-1000;
local float uzi ; uzi =-1000;
grenade = (cvar("g_balance_grenadelauncher_primary_damage")/cvar("g_balance_grenadelauncher_primary_refire")*1.0)
* bound(0,(cvar("g_balance_grenadelauncher_primary_speed")/distance*maxdelaytime),1)*1.1;
+ if (client_hasweapon(self, WEP_MINE_LAYER, TRUE, FALSE) &&
+ !(
+ cvar("bot_ai_weapon_combo") && self.weapon == WEP_MINE_LAYER &&
+ af > combo_time
+ )
+ )
+ mine = (cvar("g_balance_minelayer_damage")/cvar("g_balance_minelayer_refire")*1.0)
+ * bound(0,(cvar("g_balance_minelayer_speed")/distance*maxdelaytime),1)*1.1;
+
if (client_hasweapon(self, WEP_ELECTRO, TRUE, FALSE) &&
!( cvar("bot_ai_weapon_combo") && self.weapon == WEP_ELECTRO &&
af > combo_time
dprint("Nex: " , ftos(nex ), "\n");
dprint("Hagar: " , ftos(hagar ), "\n");
dprint("Grenade: ", ftos(grenade ), "\n");
+ dprint("Mine: " , ftos(mine ), "\n");
dprint("Electro: ", ftos(electro ), "\n");
dprint("Crylink: ", ftos(crylink ), "\n");
dprint("Uzi: " , ftos(uzi ), "\n");
w = WEP_NEX ;s = nex ;if (s > bestscore){bestscore = s;bestweapon = w;} if (self.switchweapon == w) currentscore = s;
w = WEP_HAGAR ;s = hagar ;if (s > bestscore){bestscore = s;bestweapon = w;} if (self.switchweapon == w) currentscore = s;
w = WEP_GRENADE_LAUNCHER ;s = grenade ;if (s > bestscore){bestscore = s;bestweapon = w;} if (self.switchweapon == w) currentscore = s;
+ w = WEP_MINE_LAYER ;s = mine ;if (s > bestscore){bestscore = s;bestweapon = w;} if (self.switchweapon == w) currentscore = s;
w = WEP_ELECTRO ;s = electro ;if (s > bestscore){bestscore = s;bestweapon = w;} if (self.switchweapon == w) currentscore = s;
w = WEP_CRYLINK ;s = crylink ;if (s > bestscore){bestscore = s;bestweapon = w;} if (self.switchweapon == w) currentscore = s;
w = WEP_UZI ;s = uzi ;if (s > bestscore){bestscore = s;bestweapon = w;} if (self.switchweapon == w) currentscore = s;
}
w = spawn();
- w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+ w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
w.classname = "waypoint";
w.wpflags = f;
setorigin(w, (m1 + m2) * 0.5);
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);
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)
// 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
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;
}
WriteByte(0, TE_CSQC_TEAMNAGGER);
}
+void send_CSQC_cr_maxbullets(entity e) {
+ msg_entity = e;
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_CR_MAXBULLETS);
+ WriteByte(MSG_ONE, cvar("g_balance_campingrifle_magazinecapacity"));
+}
+
void Announce(string snd) {
WriteByte(MSG_ALL, SVC_TEMPENTITY);
WriteByte(MSG_ALL, TE_CSQC_ANNOUNCE);
self.iscreature = TRUE;
self.movetype = MOVETYPE_WALK;
self.solid = SOLID_SLIDEBOX;
+ self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
if(cvar("g_playerclip_collisions"))
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
- else
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
+ self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP;
+ if(clienttype(self) == CLIENTTYPE_BOT && cvar("g_botclip_collisions"))
+ self.dphitcontentsmask |= DPCONTENTS_BOTCLIP;
self.frags = FRAGS_PLAYER;
if(independent_players)
MAKE_INDEPENDENT_PLAYER(self);
self.effects = 0;
self.air_finished = time + 12;
self.dmg = 2;
+ if(cvar("g_balance_nex_charge"))
+ self.nex_charge = cvar("g_balance_nex_charge_start");
if(inWarmupStage)
{
if(g_race || g_cts)
stuffcmd(e, "cl_cmd settemp cl_movecliptokeyboard 2\n");
if(cvar("g_antilag") == 3) // client side hitscan
- //stuffcmd(e, "cl_cmd settemp cl_prydoncursor -1\ncl_cmd settemp cl_prydoncursor_notrace 0\n");
stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n");
+ if(sv_gentle)
+ stuffcmd(e, "cl_cmd settemp cl_gentle 1\n");
/*
* we no longer need to stuff this. Remove this comment block if you feel
* 2.3 and higher (or was it 2.2.3?) don't need these any more
string ColoredTeamName(float t);
void DecodeLevelParms (void);
//void dom_player_join_team(entity pl);
-#ifdef UID
-.float uid_kicktime;
-.string uid;
-#endif
void ClientConnect (void)
{
float t;
else
self.hitplotfh = -1;
-#ifdef UID
- if(clienttype(self) == CLIENTTYPE_REAL)
- if not(self.uid)
- self.uid_kicktime = time + 60;
-#endif
-
if(g_race || g_cts) {
string rr;
if(g_cts)
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();
+ send_CSQC_cr_maxbullets(self);
+
CheatInitClient();
}
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;
}
self.stat_count -= 1;
}
-#ifdef UID
- if(self.uid_kicktime)
- if(time > self.uid_kicktime)
- {
- bprint("^3", self.netname, "^3 was kicked for missing UID.\n");
- dropclient(self);
- return;
- }
-#endif
-
if(sv_maxidle && frametime)
{
// WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
.float wasFlying;
.float spectatorspeed;
+.float multijump_count;
+.float multijump_ready;
+.float prevjumpbutton;
+
+.float nexspeed;
+
/*
=============
PlayerJump
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))
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;
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;
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)
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
if (self.waterlevel == WATERLEVEL_SWIMMING)
CheckWaterJump ();
+ self.prevjumpbutton = self.BUTTON_JUMP;
}
if (self.flags & FL_WATERJUMP )
}
}
}
+
+ float xyspeed;
+ xyspeed = vlen('1 0 0' * self.velocity_x + '0 1 0' * self.velocity_y);
+ if(self.weapon == WEP_NEX && cvar("g_balance_nex_charge") && cvar("g_balance_nex_charge_velocity_rate") && xyspeed > cvar("g_balance_nex_charge_minspeed"))
+ {
+ // add a maximum of charge_velocity_rate when going fast (f = 1), gradually increasing from minspeed (f = 0) to maxspeed
+ xyspeed = min(xyspeed, cvar("g_balance_nex_charge_maxspeed"));
+ f = (xyspeed - cvar("g_balance_nex_charge_minspeed")) / (cvar("g_balance_nex_charge_maxspeed") - cvar("g_balance_nex_charge_minspeed"));
+ // add the extra charge
+ self.nex_charge = min(1, self.nex_charge + cvar("g_balance_nex_charge_velocity_rate") * f * frametime);
+ }
:end
if(self.flags & FL_ONGROUND)
self.lastground = time;
// 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)
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);
// server framerate is very low and the weapon fire rate very high
local float c;
c = 0;
- while (c < 5)
+ while (c < W_TICSPERFRAME)
{
c = c + 1;
if(wb && ((self.weapons & wb) == 0))
// this function calculates w_shotorg and w_shotdir based on the weapon model
// offset, trueaim and antilag, and won't put w_shotorg inside a wall.
// make sure you call makevectors first (FIXME?)
+.float prevstrengthsound;
+.float prevstrengthsoundattempt;
void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float maxdamage, float range)
{
float nudge = 1; // added to traceline target and subtracted from result
sound (ent, CHAN_WEAPON, snd, VOL_BASE, ATTN_NORM);
}
- if (ent.items & IT_STRENGTH)
- if (!g_minstagib)
- sound (ent, CHAN_AUTO, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM);
+ if(ent.items & IT_STRENGTH)
+ if(!g_minstagib)
+ if(
+ (time > ent.prevstrengthsound + cvar("sv_strengthsound_antispam_time"))
+ ||
+ (time > ent.prevstrengthsoundattempt + cvar("sv_strengthsound_antispam_refire_threshold"))
+ ) // prevent insane sound spam
+ {
+ sound(ent, CHAN_AUTO, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM);
+ ent.prevstrengthsound = time;
+ }
+ ent.prevstrengthsoundattempt = time;
// nudge w_shotend so a trace to w_shotend hits
w_shotend = w_shotend + normalize(w_shotend - w_shotorg) * nudge;
self = cl;
f = weapon_action(wpn, WR_CHECKAMMO1);
f = f + weapon_action(wpn, WR_CHECKAMMO2);
+
+ // always allow selecting the Mine Layer if we placed mines, so that we can detonate them
+ local entity mine;
+ if(wpn == WEP_MINE_LAYER)
+ for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
+ f = 1;
+
self = oldself;
}
if (!f)
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
if (!weapon_action(self.weapon, WR_CHECKAMMO1 + secondary))
{
+ // always keep the Mine Layer if we placed mines, so that we can detonate them
+ local entity mine;
+ if(self.weapon == WEP_MINE_LAYER)
+ for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
+ return FALSE;
+
+ if(self.weapon == self.switchweapon) // only play once BEFORE starting to switch weapons
+ sound (self, CHAN_AUTO, "weapons/dryfire.wav", VOL_BASE, ATTN_NORM);
+
W_SwitchToOtherWeapon(self);
return FALSE;
}
tokens = tokenize_console(s);
}
GetCvars(1);
-#ifdef UID
- } else if(cmd == "uid") {
- if not(self.uid)
- {
- self.uid = strzone(argv(1));
- self.uid_kicktime = 0;
- print("Client ", etos(self), " has UID ", self.uid, "\n");
- Ban_MaybeEnforceBan(self);
- }
-#endif
} else if(cmd == "sentcvar") { // new system
if(tokens == 2) // undefined cvar: use the default value on the server then
{
self.nextthink = time + 0.1;
self.cnt = FLAG_BASE;
self.mangle = self.angles;
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+ self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
//self.effects = self.effects | EF_DIMLIGHT;
if(self.noalign)
{
float WS_INUSE = 3; // fire state
float WS_READY = 4; // idle frame
+// there is 2 weapon tics that can run in one server frame
+#define W_TICSPERFRAME 2
+
void weapon_defaultspawnfunc(float wpn);
string w_deathtypestring;
.entity flagcarried;
.entity lastrocket;
+.entity lastmine;
.float playerid;
float playerid_last;
// TODO implemented fall and falling
#define ALLPLAYERSOUNDS \
_VOICEMSG(death) \
+ _VOICEMSG(fall) \
_VOICEMSG(drown) \
_VOICEMSG(gasp) \
_VOICEMSG(jump) \
.float selectweapon; // last selected weapon of the player
.float ballistics_density; // wall piercing factor, larger = bullet can pass through more
+
+#define ACTIVE_NOT 0
+#define ACTIVE_ACTIVE 1
+#define ACTIVE_IDLE 2
+#define ACTIVE_BUSY 2
+#define ACTIVE_TOGGLE 3
+.float active;
+.float (float act_state) setactive;
+.entity realowner;
+
+.float nex_charge;
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);
//description:
//various physics properties can be defined in an entity and are executed via
//ODE
+
+//DP_CRYPTO
+//idea: divVerent
+//darkplaces implementation: divVerent
+//field definitions: (SVQC)
+.string crypto_keyfp; // fingerprint of CA key the player used to authenticate, or string_null if not verified
+.string crypto_mykeyfp; // fingerprint of CA key the server used to authenticate to the player, or string_null if not verified
+.string crypto_idfp; // fingerprint of ID used by the player entity, or string_null if not identified
+.string crypto_encryptmethod; // the string "AES128" if encrypting, and string_null if plaintext
+.string crypto_signmethod; // the string "HMAC-SHA256" if signing, and string_null if plaintext
+// there is no field crypto_myidfp, as that info contains no additional information the QC may have a use for
+//description:
// 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);
//
{
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;
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;
}
self.takedamage = DAMAGE_NO;
self.event_damage = SUB_Null;
self.state = 1;
- setsize(self, '0 0 0', '0 0 0');
func_breakable_colormod();
}
self.takedamage = DAMAGE_AIM;
self.event_damage = func_breakable_damage;
self.state = 0;
- setsize(self, self.mins_save, self.maxs_save);
func_breakable_colormod();
}
string oldmsg;
activator = self.owner;
+ self.owner = world; // set by W_PrepareExplosionByDamage
// now throw around the debris
n = tokenize_console(self.debris);
self.mdl = self.model;
SetBrushEntityModel();
- self.mins_save = self.mins;
- self.maxs_save = self.maxs;
self.use = func_breakable_restore;
precache_sound(self.noise);
self.team_saved = self.team;
+ self.dropped_origin = self.origin;
self.reset = func_breakable_reset;
func_breakable_reset();
// 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);
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) {
}
}
-vector NearestPointOnBox(entity box, vector org)
-{
- vector m1, m2, nearest;
-
- m1 = box.mins + box.origin;
- m2 = box.maxs + box.origin;
-
- nearest_x = bound(m1_x, org_x, m2_x);
- nearest_y = bound(m1_y, org_y, m2_y);
- nearest_z = bound(m1_z, org_z, m2_z);
-
- return nearest;
-}
-
void Damage_RecordDamage(entity attacker, float deathtype, float damage)
{
float weaponid;
if not(Fire_IsBurning(e))
return;
- o = e.owner;
- while(o.owner)
- o = o.owner;
+ for(t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t);
if(clienttype(o) == CLIENTTYPE_NOTACLIENT)
o = e.fire_owner;
sf |= 0x20;
if(self.colormap != 0)
sf |= 0x40;
+ if(self.lodmodelindex1)
+ sf |= 0x80;
WriteByte(MSG_ENTITY, ENT_CLIENT_WALL);
WriteByte(MSG_ENTITY, sf);
if(sf & 8)
{
- WriteShort(MSG_ENTITY, self.modelindex);
+ if(sf & 0x80)
+ {
+ WriteShort(MSG_ENTITY, self.lodmodelindex0);
+ WriteShort(MSG_ENTITY, bound(0, self.loddistance1, 65535));
+ WriteShort(MSG_ENTITY, self.lodmodelindex1);
+ WriteShort(MSG_ENTITY, bound(0, self.loddistance2, 65535));
+ WriteShort(MSG_ENTITY, self.lodmodelindex2);
+ }
+ else
+ WriteShort(MSG_ENTITY, self.modelindex);
WriteByte(MSG_ENTITY, self.solid);
- WriteByte(MSG_ENTITY, floor(self.scale * 16));
+ WriteShort(MSG_ENTITY, floor(self.scale * 256));
if(sf & 0x20)
{
WriteCoord(MSG_ENTITY, self.mins_x);
if(!self.solid) self.solid = (sol); else if(self.solid < 0) self.solid = SOLID_NOT;
#define G_CLIENTMODEL_INIT(sol) \
- SetBrushEntityModelNoLOD(); \
+ SetBrushEntityModel(); \
if(!self.scale) self.scale = self.modelscale; \
self.use = g_clientmodel_setcolormaptoactivator; \
InitializeEntity(self, g_clientmodel_dropbyspawnflags, INITPRIO_DROPTOFLOOR); \
.float loddistance1;
.float loddistance2;
-vector NearestPointOnBox(entity box, vector org);
float LOD_customize()
{
float d;
d = cvar("loddebug");
if(d == 1)
self.modelindex = self.lodmodelindex0;
- else if(d == 2)
+ else if(d == 2 || !self.lodmodelindex2)
self.modelindex = self.lodmodelindex1;
else // if(d == 3)
self.modelindex = self.lodmodelindex2;
}
if(self.lodmodelindex1)
- SetCustomizer(self, LOD_customize, LOD_uncustomize);
+ if not(self.SendEntity)
+ SetCustomizer(self, LOD_customize, LOD_uncustomize);
}
void SetBrushEntityModel()
.float triggerhurttime;
void trigger_hurt_touch()
{
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
if (other.iscreature)
{
void spawnfunc_trigger_hurt()
{
EXACTTRIGGER_INIT;
+ self.active = ACTIVE_ACTIVE;
self.touch = trigger_hurt_touch;
if (!self.dmg)
self.dmg = 1000;
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;
.float triggerhealtime;
void trigger_heal_touch()
{
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
if (other.iscreature)
{
void spawnfunc_trigger_heal()
{
+ self.active = ACTIVE_ACTIVE;
+
EXACTTRIGGER_INIT;
self.touch = trigger_heal_touch;
if (!self.health)
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
{
float laser_SendEntity(entity to, float fl)
{
WriteByte(MSG_ENTITY, ENT_CLIENT_LASER);
- fl = fl - (fl & 0xE0); // use that bit to indicate finite length laser
+ fl = fl - (fl & 0xF0); // use that bit to indicate finite length laser
if(self.spawnflags & 2)
fl |= 0x80;
if(self.alpha)
fl |= 0x40;
if(self.scale != 1 || self.modelscale != 1)
fl |= 0x20;
+ if(self.spawnflags & 4)
+ fl |= 0x10;
WriteByte(MSG_ENTITY, fl);
if(fl & 1)
{
WriteByte(MSG_ENTITY, bound(0, self.scale * 16.0, 255));
WriteByte(MSG_ENTITY, bound(0, self.modelscale * 16.0, 255));
}
- WriteShort(MSG_ENTITY, self.cnt + 1);
+ if((fl & 0x80) || !(fl & 0x10)) // effect doesn't need sending if the laser is infinite and has collision testing turned off
+ WriteShort(MSG_ENTITY, self.cnt + 1);
}
if(fl & 2)
{
self.scale = 1;
if(!self.modelscale)
self.modelscale = 1;
+ else if(self.modelscale < 0)
+ self.modelscale = 0;
self.think = misc_laser_think;
self.nextthink = time;
InitializeEntity(self, misc_laser_init, INITPRIO_FINDTARGET);
float pushdeltatime;
float str;
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// FIXME: Better checking for what to push and not.
if not(other.iscreature)
if (other.classname != "corpse")
if(!pushdeltatime) return;
other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime;
- other.flags &~= FL_ONGROUND;
+ other.flags &~= FL_ONGROUND;
+ UpdateCSQCProjectile(other);
}
// Directionless (accelerator/decelerator) mode
{
float pushdeltatime;
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// FIXME: Better checking for what to push and not.
if not(other.iscreature)
if (other.classname != "corpse")
// div0: ticrate independent, 1 = identity (not 20)
other.velocity = other.velocity * pow(self.strength, pushdeltatime);
+ UpdateCSQCProjectile(other);
}
// Spherical (gravity/repulsor) mode
float pushdeltatime;
float str;
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// FIXME: Better checking for what to push and not.
if not(other.iscreature)
if (other.classname != "corpse")
str = self.strength;
other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime;
+ UpdateCSQCProjectile(other);
}
/*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ?
void spawnfunc_trigger_impulse()
{
+ self.active = ACTIVE_ACTIVE;
+
EXACTTRIGGER_INIT;
if(self.radius)
{
// target:
// what to trigger
}
+
+void relay_activators_use()
+{
+ entity trg, os;
+
+ os = self;
+
+ for(trg = world; (trg = find(trg, targetname, os.target)); )
+ {
+ self = trg;
+ if (trg.setactive)
+ trg.setactive(os.cnt);
+ else
+ {
+ //bprint("Not using setactive\n");
+ if(os.cnt == ACTIVE_TOGGLE)
+ if(trg.active == ACTIVE_ACTIVE)
+ trg.active = ACTIVE_NOT;
+ else
+ trg.active = ACTIVE_ACTIVE;
+ else
+ trg.active = os.cnt;
+ }
+ }
+ self = os;
+}
+
+void spawnfunc_relay_activate()
+{
+ self.cnt = ACTIVE_ACTIVE;
+ self.use = relay_activators_use;
+}
+
+void spawnfunc_relay_deactivate()
+{
+ self.cnt = ACTIVE_NOT;
+ self.use = relay_activators_use;
+}
+
+void spawnfunc_relay_activatetoggle()
+{
+ self.cnt = ACTIVE_TOGGLE;
+ self.use = relay_activators_use;
+}
+
+.string chmap, gametype;
+void spawnfunc_target_changelevel_use()
+{
+ if(self.gametype != "")
+ MapInfo_SwitchGameType(MapInfo_Type_FromString(self.gametype));
+
+ if (self.chmap == "")
+ localcmd("endmatch\n");
+ else
+ localcmd(strcat("changelevel ", self.chmap, "\n"));
+};
+
+void spawnfunc_target_changelevel()
+{
+ self.use = spawnfunc_target_changelevel_use;
+};
e.classname = "gibsplash";
e.cnt = amount;
e.state = type; // should stay smaller than 15
- if(sv_gentle)
- e.state |= 0x80; // "force gentle" bit
if(!sound_allowed(MSG_BROADCAST, gibowner) || !sound_allowed(MSG_BROADCAST, attacker))
e.state |= 0x40; // "silence" bit
e.state |= 8 * self.species; // gib type, ranges from 0 to 15
addstat(STAT_LEADLIMIT, AS_FLOAT, stat_leadlimit);
addstat(STAT_BULLETS_LOADED, AS_INT, campingrifle_bulletcounter);
+ addstat(STAT_NEX_CHARGE, AS_FLOAT, nex_charge);
+
// g_movementspeed hack
addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
addstat(STAT_MOVEVARS_AIRACCEL_QW, AS_FLOAT, stat_sv_airaccel_qw);
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;
}
TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 666 - TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 0));
- if(ent.cnt == 1) // this was the second round
+ if(ent.cnt == 1 || cvar("g_campaign")) // this was the second round
{
status = WINNING_YES;
}
continue;
l = strlen(ip);
- for(j = 0; j < l; ++j)
- if(strstrofs("0123456789.", substring(ip, j, 1), 0) == -1)
- {
- print("Invalid character ", substring(ip, j, 1), " in IP address ", ip, ". Skipping this ban.\n");
- goto skip;
- }
+ if(l != 44) // length 44 is a cryptographic ID
+ {
+ for(j = 0; j < l; ++j)
+ if(strstrofs("0123456789.", substring(ip, j, 1), 0) == -1)
+ {
+ print("Invalid character ", substring(ip, j, 1), " in IP address ", ip, ". Skipping this ban.\n");
+ goto skip;
+ }
+ }
if(cvar("g_ban_sync_trusted_servers_verify"))
if((strstrofs(strcat(";", OnlineBanList_Servers, ";"), strcat(";", serverip, ";"), 0) == -1))
string ban_ip2;
string ban_ip3;
string ban_ip4;
-#ifdef UID
-string ban_uid;
-#endif
+string ban_idfp;
void Ban_SaveBans()
{
float i1, i2, i3, i4;
string s;
+ if(client.crypto_keyfp)
+ ban_idfp = client.crypto_idfp;
+ else
+ ban_idfp = string_null;
+
s = client.netaddress;
-
+
i1 = strstrofs(s, ".", 0);
if(i1 < 0)
- return FALSE;
+ goto ipv6;
i2 = strstrofs(s, ".", i1 + 1);
if(i2 < 0)
return FALSE;
return FALSE;
i4 = strstrofs(s, ".", i3 + 1);
if(i4 >= 0)
- return FALSE;
+ s = substring(s, 0, i4);
- ban_ip1 = substring(s, 0, i1);
- ban_ip2 = substring(s, 0, i2);
- ban_ip3 = substring(s, 0, i3);
- ban_ip4 = strcat1(s);
-#ifdef UID
- ban_uid = client.uid;
-#endif
+ ban_ip1 = substring(s, 0, i1); // 8
+ ban_ip2 = substring(s, 0, i2); // 16
+ ban_ip3 = substring(s, 0, i3); // 24
+ ban_ip4 = strcat1(s); // 32
+ return TRUE;
+
+:ipv6
+ i1 = strstrofs(s, ":", 0);
+ if(i1 < 0)
+ return FALSE;
+ i1 = strstrofs(s, ":", i1 + 1);
+ if(i1 < 0)
+ return FALSE;
+ i2 = strstrofs(s, ":", i1 + 1);
+ if(i2 < 0)
+ return FALSE;
+ i3 = strstrofs(s, ":", i2 + 1);
+ if(i3 < 0)
+ return FALSE;
+
+ ban_ip1 = strcat(substring(s, 0, i1), "::/32"); // 32
+ ban_ip2 = strcat(substring(s, 0, i2), "::/48"); // 48
+ ban_ip4 = strcat(substring(s, 0, i3), "::/64"); // 64
+
+ if(i3 - i2 > 3) // means there is more than 2 digits and a : in the range
+ ban_ip3 = strcat(substring(s, 0, i2), ":", substring(s, i2 + 1, i3 - i2 - 3), "00::/56");
+ else
+ ban_ip3 = strcat(substring(s, 0, i2), ":0::/56");
return TRUE;
}
float Ban_IsClientBanned(entity client, float idx)
{
- float i, b, e;
+ float i, b, e, ipbanned;
if(!ban_loaded)
Ban_LoadBans();
if(!Ban_GetClientIP(client))
b = idx;
e = idx + 1;
}
+ ipbanned = FALSE;
for(i = b; i < e; ++i)
{
string s;
if(time > ban_expire[i])
continue;
s = ban_ip[i];
- if(ban_ip1 == s) return TRUE;
- if(ban_ip2 == s) return TRUE;
- if(ban_ip3 == s) return TRUE;
- if(ban_ip4 == s) return TRUE;
-#ifdef UID
- if(ban_uid == s) return TRUE;
-#endif
+ if(ban_ip1 == s) ipbanned = TRUE;
+ if(ban_ip2 == s) ipbanned = TRUE;
+ if(ban_ip3 == s) ipbanned = TRUE;
+ if(ban_ip4 == s) ipbanned = TRUE;
+ if(ban_idfp == s) return TRUE;
}
+ if(ipbanned)
+ if(!cvar("g_banned_list_idmode") || !ban_idfp)
+ return TRUE;
return FALSE;
}
default:
Ban_Insert(ban_ip4, bantime, reason, 1);
break;
-#ifdef UID
- case 0:
- Ban_Insert(ban_uid, bantime, reason, 1);
- break;
-#endif
}
+ if(ban_idfp)
+ Ban_Insert(ban_idfp, bantime, reason, 1);
/*
* not needed, as we enforce the ban in Ban_Insert anyway
// and kick him
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)
if (g_weaponarena)
{
start_weapons = g_weaponarena;
- if (g_weaponarena & (WEPBIT_GRENADE_LAUNCHER | WEPBIT_HAGAR | WEPBIT_ROCKET_LAUNCHER))
+ if (g_weaponarena & (WEPBIT_GRENADE_LAUNCHER | WEPBIT_MINE_LAYER | WEPBIT_HAGAR | WEPBIT_ROCKET_LAUNCHER))
start_ammo_rockets = 999;
if (g_weaponarena & WEPBIT_SHOTGUN)
start_ammo_shells = 999;
precache_sound ("weapons/weapon_switch.wav");
precache_sound ("weapons/weaponpickup.wav");
precache_sound ("weapons/unavailable.wav");
+ precache_sound ("weapons/dryfire.wav");
if (g_grappling_hook)
{
precache_sound ("weapons/hook_fire.wav"); // hook
if (time >= 2)
{
spawnedexitmonsters = TRUE;
- e = find(world, classname, "trigger_changelevel");
+ e = find(world, classname, "target_changelevel");
while (e)
{
spawnmonster(e.origin + (e.mins + e.maxs) * 0.5, 8, 8, "monster_hellfish", monster_hellfish, '-16 -16 -24', '16 16 32');
- e = find(e, classname, "trigger_changelevel");
+ e = find(e, classname, "target_changelevel");
}
}
return;
key.modelindex = kh_key_dropped;
key.model = "key";
key.kh_dropperteam = 0;
- key.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+ key.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
setsize(key, KH_KEY_MIN, KH_KEY_MAX);
key.colormod = TeamColor(initial_owner.team) * KH_KEY_BRIGHTNESS;
key.reset = key_reset;
+#ifdef TURRET_DEBUG
void mark_error(vector where,float lifetime);
void mark_info(vector where,float lifetime);
entity mark_misc(vector where,float lifetime);
-
+#endif
void pathlib_showpath(entity start)
{
void __showpath2_think()
{
- mark_info(self.origin,1);
+ #ifdef TURRET_DEBUG
+ mark_info(self.origin,1);
+ #endif
if(self.path_next)
{
self.path_next.think = __showpath2_think;
node = pathlib_nodeatpoint(where);
if(node)
{
+ #ifdef TURRET_DEBUG
mark_error(where, 60);
+ #endif
return node;
}
string rr;
float grecordtime[RANKINGS_CNT];
string grecordholder[RANKINGS_CNT];
-#ifdef UID
string grecorduid[RANKINGS_CNT];
-#endif
float worst_time; // last ranked time
float have_recs; // have we already read the records from the database before?
float race_GetTime(float pos) {
for(i=0;i<RANKINGS_CNT;++i) {
grecordtime[i] = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i))));
grecordholder[i] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i))));
-#ifdef UID
- grecorduid[i] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i))));
-#endif
+ grecorduid[i] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i))));
}
grecordtime[0] = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time")));
grecordholder[0] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "netname")));
-#ifdef UID
- grecorduid[0] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "uid")));
-#endif
+ grecorduid[0] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp")));
worst_time = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, strcat("time", ftos(RANKINGS_CNT-1)))));
have_recs = 1;
}
return grecordholder[pos-1];
}
-#ifdef UID
float race_CheckUID(string myuid, string net_name) { // return existing UID or player name ranking pos, else 0
float i;
+ if(myuid)
+ {
+ for (i=RANKINGS_CNT-1;i>=0;--i)
+ if(grecorduid[i] == myuid)
+ return i+1;
+ }
for (i=RANKINGS_CNT-1;i>=0;--i)
- if(grecorduid[i] == myuid)
- return i+1;
- for (i=RANKINGS_CNT-1;i>=0;--i)
- if(grecordholder[i] == net_name)
- return i+1;
- return 0;
-}
-#endif
-
-float race_CheckName(string net_name) { // Does the name already exist in rankings? In that case, where? (otherwise 0)
- float i;
- for (i=RANKINGS_CNT-1;i>=0;--i)
- if(grecordholder[i] == net_name)
- return i+1;
+ if(!grecorduid[i])
+ if(grecordholder[i] == net_name)
+ return i+1;
return 0;
}
void race_SetTime(entity e, float t, float match_rec) {
float pos, prevpos;
pos = race_GetPos(t);
-#ifdef UID
- prevpos = race_CheckUID(e.uid, e.netname);
-#else
- prevpos = race_CheckName(e.netname);
-#endif
+ prevpos = race_CheckUID(e.crypto_idfp, e.netname);
float oldrec;
string recorddifference;
for (i=prevpos-1;i>pos-1;--i) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i-1]));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i-1]);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), grecorduid[i-1]);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i-1]);
grecordtime[i] = grecordtime[i-1];
if (grecordholder[i])
strunzone(grecordholder[i]);
grecordholder[i] = strzone(grecordholder[i-1]);
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[i]);
grecorduid[i] = strzone(grecorduid[i-1]);
-#endif
}
} else { // player has no ranked record yet
for (i=RANKINGS_CNT-1;i>pos-1;--i) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i-1]));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i-1]);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), grecorduid[i-1]);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i-1]);
grecordtime[i] = grecordtime[i-1];
if (grecordholder[i])
strunzone(grecordholder[i]);
grecordholder[i] = strzone(grecordholder[i-1]);
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[i]);
grecorduid[i] = strzone(grecorduid[i-1]);
-#endif
}
}
if (pos == 1) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(t));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), e.netname);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid"), e.uid);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp"), e.crypto_idfp);
grecordtime[0] = t;
if (grecordholder[0])
strunzone(grecordholder[0]);
grecordholder[0] = strzone(e.netname);
-#ifdef UID
if (grecorduid[0])
strunzone(grecorduid[0]);
- grecorduid[0] = strzone(e.uid);
-#endif
+ grecorduid[0] = strzone(e.crypto_idfp);
write_recordmarker(e, time - TIME_DECODE(t), TIME_DECODE(t));
race_send_recordtime(MSG_ALL);
} else {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(pos-1)), ftos(t));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(pos-1)), e.netname);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(pos-1)), e.uid);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(pos-1)), e.crypto_idfp);
grecordtime[pos-1] = t;
if (grecordholder[pos-1])
strunzone(grecordholder[pos-1]);
grecordholder[pos-1] = strzone(e.netname);
-#ifdef UID
if (grecorduid[pos-1])
strunzone(grecorduid[pos-1]);
- grecorduid[pos-1] = strzone(e.uid);
-#endif
+ grecorduid[pos-1] = strzone(e.crypto_idfp);
}
if (pos == RANKINGS_CNT)
if (i == 0) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(grecordtime[1]));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), grecordholder[1]);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid"), grecorduid[1]);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp"), grecorduid[1]);
grecordtime[0] = grecordtime[1];
if (grecordholder[i])
strunzone(grecordholder[0]);
grecordholder[0] = strzone(grecordholder[1]);
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[0]);
grecorduid[0] = strzone(grecorduid[1]);
-#endif
}
else if (i == RANKINGS_CNT-1) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), string_null);
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), string_null);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), string_null);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), string_null);
grecordtime[i] = 0;
if (grecordholder[i])
strunzone(grecordholder[i]);
grecordholder[i] = string_null;
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[i]);
grecorduid[i] = string_null;
-#endif
}
else {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i+1]));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i+1]);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), grecorduid[i+1]);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i+1]);
grecordtime[i] = grecordtime[i+1];
if (grecordholder[i])
strunzone(grecordholder[i]);
grecordholder[i] = strzone(grecordholder[i+1]);
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[i]);
grecorduid[i] = strzone(grecorduid[i+1]);
-#endif
}
}
if (dm > 0)
{
Damage (self, world, world, dm, DEATH_FALL, self.origin, '0 0 0');
+ // this must be allowed to cut the normal pain sounds (played after them and on the same channel)
+ // there's no way to detect falling damage and prevent the pain sounds for this to be played instead
+ if(self.health > 0)
+ PlayerSound(playersound_fall, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
}
}
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)
{
ammofield = Item_CounterField(j);
if(!self.ammofield)
- self.ammofield = cvar(strcat("g_pickup_", Item_CounterFieldName(j)));
+ self.ammofield = cvar(strcat("g_pickup_", Item_CounterFieldName(j), "_weapon"));
}
}
}
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) {
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) {
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) {
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) {
void trigger_push_touch()
{
+ if (self.active == ACTIVE_NOT)
+ return;
+
// FIXME: add a .float for whether an entity should be tossed by jumppads
if (!other.iscreature)
if (other.classname != "corpse")
};
.vector dest;
-
void trigger_push_findtarget()
{
local entity e;
SetMovedir ();
EXACTTRIGGER_INIT;
-
+
+ self.active = ACTIVE_ACTIVE;
self.use = trigger_push_use;
self.touch = trigger_push_touch;
// TODO make a reset function for this one
};
+void func_rotating_setactive(float astate)
+{
+
+ if (astate == ACTIVE_TOGGLE)
+ {
+ if(self.active == ACTIVE_ACTIVE)
+ self.active = ACTIVE_NOT;
+ else
+ self.active = ACTIVE_ACTIVE;
+ }
+ else
+ self.active = astate;
+
+ if(self.active == ACTIVE_NOT)
+ self.avelocity = '0 0 0';
+ else
+ self.avelocity = self.pos1;
+}
+
/*QUAKED spawnfunc_func_rotating (0 .5 .8) ? - - X_AXIS Y_AXIS
Brush model that spins in place on one axis (default Z).
speed : speed to rotate (in degrees per second)
precache_sound(self.noise);
ambientsound(self.origin, self.noise, VOL_BASE, ATTN_IDLE);
}
+
+ self.active = ACTIVE_ACTIVE;
+ self.setactive = func_rotating_setactive;
+
if (!self.speed)
self.speed = 100;
// FIXME: test if this turns the right way, then remove this comment (negate as needed)
// FIXME: test if this turns the right way, then remove this comment (negate as needed)
else // Z
self.avelocity = '0 1 0' * self.speed;
-
+
+ self.pos1 = self.avelocity;
+
if(self.dmg & (!self.message))
self.message = " was squished";
if(self.dmg && (!self.message2))
{
local vector v;
self.nextthink = time + 0.1;
+
+ if not (self.owner.active == ACTIVE_ACTIVE)
+ {
+ self.owner.velocity = '0 0 0';
+ return;
+ }
+
// calculate sinewave using makevectors
makevectors((self.nextthink * self.owner.cnt + self.owner.phase * 360) * '0 1 0');
v = self.owner.destvec + self.owner.movedir * v_forward_y;
- // * 10 so it will arrive in 0.1 sec
- self.owner.velocity = (v - self.owner.origin) * 10;
+ if(self.owner.classname == "func_bobbing") // don't brake stuff if the func_bobbing was killtarget'ed
+ // * 10 so it will arrive in 0.1 sec
+ self.owner.velocity = (v - self.owner.origin) * 10;
};
void bobbing_blocked()
// time scale to get degrees
self.cnt = 360 / self.speed;
+ self.active = ACTIVE_ACTIVE;
+
// damage when blocked
self.blocked = bobbing_blocked;
if(self.dmg & (!self.message))
// dprint(activator.classname);
// dprint(" triggered a button\n");
// }
+
+ if not (self.active == ACTIVE_ACTIVE)
+ return;
+
self.enemy = activator;
button_fire ();
};
if(self.noise != "")
precache_sound(self.noise);
+ self.active = ACTIVE_ACTIVE;
+
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
self.flags |= FL_NOTARGET;
float n, i, t;
self.nextthink = time + 0.1;
+ if not (self.owner.active == ACTIVE_ACTIVE)
+ {
+ self.owner.velocity = '0 0 0';
+ return;
+ }
+
n = floor((tokenize_console(self.owner.netname)) / 5);
t = self.nextthink * self.owner.cnt + self.owner.phase * 360;
v = v + ('1 0 0' * stof(argv(i*5+2)) + '0 1 0' * stof(argv(i*5+3)) + '0 0 1' * stof(argv(i*5+4))) * self.owner.height * v_forward_y;
}
- // * 10 so it will arrive in 0.1 sec
- self.owner.velocity = (v - self.owner.origin) * 10;
+ if(self.owner.classname == "func_fourier") // don't brake stuff if the func_fourier was killtarget'ed
+ // * 10 so it will arrive in 0.1 sec
+ self.owner.velocity = (v - self.owner.origin) * 10;
};
void spawnfunc_func_fourier()
if not(InitMovingBrushTrigger())
return;
+ self.active = ACTIVE_ACTIVE;
+
// wait for targets to spawn
controller = spawn();
controller.classname = "func_fourier_controller";
void func_vectormamamam_controller_think()
{
self.nextthink = time + 0.1;
- self.owner.velocity = (self.owner.destvec + func_vectormamamam_origin(self.owner, 0.1) - self.owner.origin) * 10;
+
+ if not (self.owner.active == ACTIVE_ACTIVE)
+ {
+ self.owner.velocity = '0 0 0';
+ return;
+ }
+
+ if(self.owner.classname == "func_vectormamamam") // don't brake stuff if the func_vectormamamam was killtarget'ed
+ self.owner.velocity = (self.owner.destvec + func_vectormamamam_origin(self.owner, 0.1) - self.owner.origin) * 10;
}
void func_vectormamamam_findtarget()
// Savage: Reduce bandwith, critical on e.g. nexdm02
self.effects |= EF_LOWPRECISION;
+ self.active = ACTIVE_ACTIVE;
+
InitializeEntity(self, func_vectormamamam_findtarget, INITPRIO_FINDTARGET);
}
// 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
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;
{
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');
}
#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)
{
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
player.pushltime = 0;
}
- if(player.isbot)
- player.lastteleporttime = time;
+ player.lastteleporttime = time;
// stop player name display
{
entity oldself, e;
vector o;
float p;
+ string s;
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
if (other.health < 1)
return;
if not(other.flags & FL_CLIENT) // FIXME: Make missiles firable through the teleport too
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)
self.angles = '0 0 0';
EXACTTRIGGER_INIT;
-
+
+ self.active = ACTIVE_ACTIVE;
+
self.use = trigger_teleport_use;
// this must be called to spawn the teleport waypoints for bots
{
// 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;
}
}
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;
modifications = strcat(modifications, ", Low gravity");
if(g_cloaked)
modifications = strcat(modifications, ", Cloaked");
- if(g_footsteps)
- modifications = strcat(modifications, ", Steps");
if(g_grappling_hook)
modifications = strcat(modifications, ", Hook");
if(g_laserguided_missile)
}
// 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)
if(IsTeamBalanceForced() == 1)
return 1;
return 1;
+ // FIXME: it always returns 1...
}
// c1...c4 should be set to -1 (not allowed) or 0 (allowed).
if(c4 >= 0)
totalteams = totalteams + 1;
- if(cvar("bot_vs_human"))
+ if(cvar("bot_vs_human") && totalteams == 1)
totalteams += 1;
if(totalteams <= 1)
// 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)
smallest = FindSmallestTeam(pl, TRUE);
- if(!only_return_best)
+ if(!only_return_best && !pl.bot_forced_team)
{
TeamchangeFrags(self);
if(smallest == 1)
/// Dont aim.
#define TFL_AIM_NO 1
/// Go for ground, not direct hit
-#define TFL_AIM_GROUND 2
+//#define TFL_AIM_GROUND 2
/// Go for ground, not direct hit, but only if target is on ground.
#define TFL_AIM_GROUND2 4
/// Use balistic aim. FIXME: not implemented
#define TFL_AIM_INFRONT 64
/// Aim slightly behind target
#define TFL_AIM_BEHIND 128
-/// blend real and predicted z positions. (fake bounce prediction)
-#define TFL_AIM_ZEASE 256
+/// blend real and predicted z positions. (fake bounce prediction)
+// #define TFL_AIM_ZEASE 256
/// Try to do real prediction of targets z pos at impact.
#define TFL_AIM_ZPREDICT 512
/// Simply aim at target's current location
/// on/off toggle.
.float tur_active;
-// Aim from this point,
-//.vector tur_aimorg;
-
/// and shoot from here. (can be non constant, think MLRS)
.vector tur_shotorg;
.float target_range;
/// Dont consider targets closer then
.float target_range_min;
-// Engage fire routine on targets within
-//.float target_range_fire; // no practical use aymore, work with target_range insted.
/// Targets closer to this are prefered
.float target_range_optimal;
*/
/// Maximum offset between impact and aim spot to fire
.float aim_firetolerance_dist;
-// Maximum angular offset between head and aimspot to fire
-//.float aim_firetolerance_angle;
/// How fast can i rotate/pitch (per second in stepmotor mode, base force in smooth modes)
.float aim_speed;
/// cant aim higher/lower then this
.void() turret_firefunc;
/// prefire checks go here. return 1 to go bang, 0 not to.
.float() turret_firecheckfunc;
-// Execure BEFORE main ai loop. return 0 to cancel any following proccessing.
-//.float() turret_prethink;
/// Execure AFTER main AI loop
.void() turret_postthink;
/// Add a target
.float(entity e_target,entity e_sender) turret_addtarget;
-//.float call_diehook;
-//.float call_respwnhook;
.void() turret_diehook;
.void() turret_respawnhook;
.float(float event_id) turret_eventhook;
*/
-/*
-* Some turrets need other aimsystems then other.
-* This should return the place to aim at, not acctualy turn or
-* pitch anyting.
-*
-* use turret_stdproc_aim* or Make your own.
-* Make sure you update tur_enemy_dist and tur_enemy_adist
-* with the apropriate info, if you do.
-
-removed.
-*/
-// function used to aim, usualy turret_stdproc_aim_generic
-//.vector() turret_aim;
-
-/*
-* This is where the acctual turret turning should take place
-* Use turret_stdproc_track or make your own.
-wkacked to save mem.
-*/
-// Function used to turn and pitch the .tur_head usualy turret_stdproc_track
-//.void() turret_track;
/*
* Target selection, preferably but not nessesarely
/// Function to use for target evaluation. usualy turret_stdproc_targetscore_generic
.float(entity e_turret, entity e_target) turret_score_target;
-/*
-* Damage, death and respawn.
-*/
-//void turret_gibs_precash();
-// generalized so save mem (on fields)
-// Function to handle incomming damage. usualy turret_stdproc_damage
-//.void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce) turret_damagefunc;
-// Function to handle the event of death. usualy turret_stdproc_die
-//.void() turret_diefunc;
-// Function that handles rebirth. usualy turret_stdproc_respawn
-//.void() turret_spawnfunc;
-
-/*
-* Stuff to plug into requierd but unused callbacks.
-*/
-/// Always return 1
-//float turret_stdproc_true();
-/// Always return 0
-//float turret_stdproc_false();
-/// Always return nothing at all
-//void turret_stdproc_nothing();
/*
* Target selection
*/
-// noting uses the following atm.
-// "closeer is beter" selection
-//float turret_stdproc_targetscore_close(entity e_turret, entity e_target);
-// "further is beter" selection
-//float turret_stdproc_targetscore_far(entity e_turret, entity e_target);
-// only target_range_optimal
-//float turret_stdproc_targetscore_optimal(entity e_turret, entity e_target);
-// defendpos
-//float turret_stdproc_targetscore_defend(entity e_turret, entity e_target);
-/// Generic fairly smart bias-aware target selection.
+/// Generic, fairly smart, bias-aware target selection.
float turret_stdproc_targetscore_generic(entity e_turret, entity e_target);
/// Experimental supportunits targetselector
float turret_stdproc_targetscore_support(entity e_turret,entity e_target);
* Aim functions
*/
/// Generic aimer guided by self.aim_flags
-vector turret_stdproc_aim_generic()
-// Straight line, current location
-//vector turret_stdproc_aim_simple()
+vector turret_stdproc_aim_generic();
/*
* Turret turning & pitch
/// updates aim org, shot org, shot dir and enemy org for selected turret
void turret_do_updates(entity e_turret);
-//.vector tur_aimorg_updated; // creates to much aim issues. using tur_shotorg_updated insted.
-//.vector tur_shotorg_updated; // DP8815 fixes gettaginfo, no longer needed.
.vector tur_shotdir_updated;
void turrets_precash();
supports:
TFL_AIM_NO
-TFL_AIM_GROUND
+TFL_AIM_GROUND2
TFL_AIM_LEAD
TFL_AIM_SHOTTIMECOMPENSATE
TFL_AIM_INFRONT
TFL_AIM_BEHIND
-TFL_AIM_ZEASE
not supported:
TFL_AIM_BALISTIC
+
+removed
+TFL_AIM_ZEASE
+TFL_AIM_GROUND
*/
vector turret_stdproc_aim_generic()
{
if(self.aim_flags & TFL_AIM_SIMPLE)
return real_origin(self.enemy);
- // Keep track of when we can shoot the next time and
- // try to predict where the target will be then, so we can put our aimpoint there.
- // + sys_frametime, becouse spawned REMOVE THIS IF sv_gameplayfix_delayprojectiles are 0!
- // projectiles dont move during the first tic of their life.
- //if (self.turrcaps_flags & TFL_TURRCAPS_HITSCAN)
- // mintime = max(self.attack_finished_single - time,0) + sys_frametime;
- //else
-
- mintime = max(self.attack_finished_single - time,0) + sys_frametime;
+ mintime = max(self.attack_finished_single - time,0) + sys_frametime ;
// Baseline
pre_pos = real_origin(self.enemy);
// Lead?
if (self.aim_flags & TFL_AIM_LEAD)
- if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE) // Need to conpensate for shot traveltime
- {
- // FIXME: this cant be the best way to do this..
- prep = pre_pos;
- for(i = 0; i < 4; ++i)
- {
- distance = vlen(prep - self.tur_shotorg);
- impact_time = distance / self.shot_speed;
- prep = pre_pos + self.enemy.velocity * impact_time;
- }
-
-
- // tnx to Rudolf "div0" Polzer for this solution.
- // hmm tobad it dont work.
- /*
- vector q;
- q = solve_quadratic(self.enemy.velocity*self.enemy.velocity - self.shot_speed*self.shot_speed, 2*(pre_pos*self.enemy.velocity), pre_pos * pre_pos);
- if(q_x > 0)
- impact_time = q_x;
- else
- impact_time = q_y;
- */
-
- prep = pre_pos + (self.enemy.velocity * (impact_time + mintime));
-
- if(self.aim_flags & TFL_AIM_ZPREDICT)
- if not(self.enemy.flags & FL_ONGROUND)
- if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
- {
- float vz;
- prep_z = pre_pos_z;
- vz = self.enemy.velocity_z;
- for(i = 0; i < impact_time; i += sys_frametime)
- {
- vz = vz - (sv_gravity * sys_frametime);
- prep_z = prep_z + vz * sys_frametime;
- }
- }
- pre_pos = prep;
- }
- else
- pre_pos = pre_pos + self.enemy.velocity * mintime;
-
- // Smooth out predict-Z?
- /*
- if (self.aim_flags & TFL_AIM_ZEASE)
- if (self.enemy.flags & FL_CLIENT)
- {
- vector v;
- v = real_origin(self.enemy);
- pre_pos_z = (pre_pos_z + v_z) * 0.5;
+ {
+ if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE) // Need to conpensate for shot traveltime
+ {
+ // FIXME: this cant be the best way to do this..
+ prep = pre_pos;
+ for(i = 0; i < 4; ++i)
+ {
+ distance = vlen(prep - self.tur_shotorg);
+ impact_time = distance / self.shot_speed;
+ prep = pre_pos + self.enemy.velocity * impact_time;
+ }
+
+ prep = pre_pos + (self.enemy.velocity * (impact_time + mintime));
+
+ if(self.aim_flags & TFL_AIM_ZPREDICT)
+ if not(self.enemy.flags & FL_ONGROUND)
+ if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
+ {
+ float vz;
+ prep_z = pre_pos_z;
+ vz = self.enemy.velocity_z;
+ for(i = 0; i < impact_time; i += sys_frametime)
+ {
+ vz = vz - (sv_gravity * sys_frametime);
+ prep_z = prep_z + vz * sys_frametime;
+ }
+ }
+ pre_pos = prep;
+ }
+ else
+ pre_pos = pre_pos + self.enemy.velocity * mintime;
}
- */
-
+
if(self.aim_flags & TFL_AIM_GROUND2)
{
//tracebox(pre_pos + '0 0 32',self.enemy.mins,self.enemy.maxs,pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
pre_pos = trace_endpos;
}
- /*
- // This turret should hit the ground neer a target rather the do a direct hit
- if (self.aim_flags & TFL_AIM_GROUND)
- {
- traceline(pre_pos + '0 0 8',pre_pos - '0 0 10000',MOVE_WORLDONLY,self.enemy);
- pre_pos = trace_endpos;
- }
- */
-
return pre_pos;
}
gib = spawn();
gib.classname = "turret_gib";
- setmodel(gib,smodel);
- setorigin(gib,v_from);
- SUB_SetFade(gib,time + f_lifetime,2);
+ setmodel(gib, smodel);
+ setorigin(gib, v_from);
+ SUB_SetFade(gib,time + f_lifetime, 2);
gib.solid = SOLID_BBOX;
-
gib.movetype = MOVETYPE_BOUNCE;
gib.takedamage = DAMAGE_YES;
gib.event_damage = turret_gib_damage;
burn.effects = EF_LOWPRECISION;//|EF_FLAME;
setattachment(burn,gib,"");
setorigin(burn,(gib.mins + gib.maxs) * 0.5);
- SUB_SetFade(burn,time + (f_lifetime * 0.5) ,2);
+ SUB_SetFade(burn,time + (f_lifetime * 0.5), 2);
}
}
s = strcat("models/turrets/head-gib",ftos(i));
s = strcat(s,".md3");
- // bprint("s:",s,"\n");
- setmodel(gib,s);
+ setmodel(gib, s);
setorigin(gib,self.origin);
SUB_SetFade(gib,time + 5,2);
gib.solid = SOLID_BBOX;
-
gib.movetype = MOVETYPE_BOUNCE;
gib.gravity = 0.5;
gib.damageforcescale = 2;
makevectors(self.angles);
if (random() > 0.5)
{
- turret_trowgib(self.origin, '0 0 0','1 1 1',"models/turrets/base-gib2.md3",min(self.respawntime,20),1,1);
+ turret_trowgib(self.origin, '0 0 0', '1 1 1', "models/turrets/base-gib2.md3", min(self.respawntime, 20), 1, 1);
+
+ t_dir = (v_up * 700) + (randomvec() * 300);
+ turret_trowgib(self.origin, t_dir, '1 1 1', "models/turrets/base-gib3.md3", min(self.respawntime, 10), 1, 1);
+
t_dir = (v_up * 700) + (randomvec() * 300);
- turret_trowgib(self.origin, t_dir,'1 1 1',"models/turrets/base-gib3.md3",min(self.respawntime,10),1,1);
- t_dir = (v_up * 700) + (randomvec() * 300);
- turret_trowgib(self.origin, t_dir,'1 1 1',"models/turrets/base-gib4.md3",min(self.respawntime,10),1,1);
+ turret_trowgib(self.origin, t_dir, '1 1 1', "models/turrets/base-gib4.md3", min(self.respawntime, 10), 1, 1);
}
else
{
- turret_trowgib(self.origin, '0 0 0','1 1 1',"models/turrets/base-gib1.md3",min(self.respawntime,20),1,1);
+ turret_trowgib(self.origin, '0 0 0', '1 1 1', "models/turrets/base-gib1.md3", min(self.respawntime, 20), 1, 1);
}
// Blow the top part up into the air
- turret_trowgib2( self.origin + (v_up * 50),
- v_up * 150 + randomvec() * 50,
- '0.2 0.2 0.2',
- self.tur_head,time + 0.5 + (random() * 0.5));
+ turret_trowgib2( self.origin + (v_up * 50), v_up * 150 + randomvec() * 50, '0.2 0.2 0.2', self.tur_head,time + 0.5 + (random() * 0.5));
}
// Go boom
}
else
{
- // Setup respawn
+ // Setup respawn
self.nextthink = time + self.respawntime;
- //self.think = self.turret_spawnfunc;
self.think = turret_stdproc_respawn;
+
if (self.turret_diehook)
self.turret_diehook();
}
-
}
+var const float SUB_NullFloat();
void turret_stdproc_respawn()
{
// Make sure all parts belong to the same team since
// this function doubles as "teamchange" function.
- self.tur_head.team = self.team;
-
- /*
- COLOR_TEAM1 = 4; // red
- COLOR_TEAM2 = 13; // blue
- COLOR_TEAM3 = 12; // yellow
- COLOR_TEAM4 = 9; // pink
- */
-
- self.colormod = '0 0 0';
+ self.tur_head.team = self.team;
+ self.colormod = '0 0 0';
switch(self.team)
{
}
self.deadflag = DEAD_NO;
- self.effects = 0;
+ self.effects = EF_LOWPRECISION;
self.tur_head.effects = self.effects;
-
self.solid = SOLID_BBOX;
-
- self.alpha = 1;
+ self.alpha = 1;
self.tur_head.alpha = self.alpha;
- self.customizeentityforclient = SUB_True;
- self.tur_head.customizeentityforclient = SUB_True;
+
+ self.customizeentityforclient = SUB_NullFloat;
+ self.tur_head.customizeentityforclient = SUB_NullFloat;
- self.takedamage = DAMAGE_AIM;
+ self.takedamage = DAMAGE_AIM;
self.event_damage = turret_stdproc_damage;
self.avelocity = '0 0 0';
}
*/
-void load_unit_settings(entity ent,string unitname,float is_reload)
+void load_unit_settings(entity ent, string unitname, float is_reload)
{
string sbase;
- // dprint("Reloading turret ",e_turret.netname,"\n");
-
if (ent == world)
return;
ent.target_range = cvar(strcat(sbase,"_target_range")) * ent.turret_scale_range;
ent.target_range_min = cvar(strcat(sbase,"_target_range_min")) * ent.turret_scale_range;
- //ent.target_range_fire = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range;
ent.target_range_optimal = cvar(strcat(sbase,"_target_range_optimal")) * ent.turret_scale_range;
+ //ent.target_range_fire = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range;
ent.target_select_rangebias = cvar(strcat(sbase,"_target_select_rangebias"));
ent.target_select_samebias = cvar(strcat(sbase,"_target_select_samebias"));
if(is_reload)
if(ent.turret_respawnhook)
ent.turret_respawnhook();
-
-}
-
-/*
-float turret_stdproc_true()
-{
- return 1;
}
-float turret_stdproc_false()
-{
- return 0;
-}
-
-
-void turret_stdproc_nothing()
-{
- return;
-}
-*/
/**
** updates enemy distances, predicted impact point/time
**/
void turret_do_updates(entity t_turret)
{
- vector enemy_pos,oldpos;
+ vector enemy_pos, oldpos;
entity oldself;
oldself = self;
turret_tag_fire_update();
- self.tur_shotdir_updated = normalize(v_forward);
-
+ self.tur_shotdir_updated = v_forward;
self.tur_dist_enemy = vlen(self.tur_shotorg - enemy_pos);
self.tur_dist_aimpos = vlen(self.tur_shotorg - self.tur_aimpos);
if(trace_ent == self.enemy)
self.tur_dist_impact_to_aimpos = 0;
else
- self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos);// - (vlen(self.enemy.maxs - self.enemy.mins)*0.5);
+ self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos);
- self.tur_impactent = trace_ent;
- self.tur_impacttime = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
}
else
- tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1',self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos),MOVE_NORMAL,self);
- //traceline(self.tur_shotorg, self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos),MOVE_NORMAL,self);
-
- self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins)*0.5);
- self.tur_impactent = trace_ent;
- self.tur_impacttime = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
-
+ tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos),MOVE_NORMAL,self);
+
+ self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins) * 0.5);
+ self.tur_impactent = trace_ent;
+ self.tur_impacttime = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
self = oldself;
}
** Handles head rotation according to
** the units .track_type and .track_flags
**/
-//.entity aim_mark;
void turret_stdproc_track()
{
vector target_angle; // This is where we want to aim
}
else
{
- // Find the direction
- target_angle = normalize(self.tur_aimpos - self.tur_shotorg);
- target_angle = vectoangles(target_angle); // And make a angle
+ target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg));
}
-
- self.tur_head.angles_x = safeangle(self.tur_head.angles_x);
- self.tur_head.angles_y = safeangle(self.tur_head.angles_y);
+
+ self.tur_head.angles_x = anglemods(self.tur_head.angles_x);
+ self.tur_head.angles_y = anglemods(self.tur_head.angles_y);
// Find the diffrence between where we currently aim and where we want to aim
move_angle = target_angle - (self.angles + self.tur_head.angles);
move_angle = shortangle_vxy(move_angle,(self.angles + self.tur_head.angles));
-
-
-
switch(self.track_type)
{
case TFL_TRACKTYPE_STEPMOTOR:
case TFL_TRACKTYPE_FLUIDINERTIA:
f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
- move_angle_x = bound(-self.aim_speed, move_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed);
- move_angle_y = bound(-self.aim_speed, move_angle_y * self.track_accel_rot * f_tmp,self.aim_speed);
+ move_angle_x = bound(-self.aim_speed, move_angle_x * self.track_accel_pitch * f_tmp, self.aim_speed);
+ move_angle_y = bound(-self.aim_speed, move_angle_y * self.track_accel_rot * f_tmp, self.aim_speed);
move_angle = (self.tur_head.avelocity * self.track_blendrate) + (move_angle * (1 - self.track_blendrate));
break;
self.tur_head.avelocity_x = 0;
self.tur_head.angles_x = self.aim_maxpitch;
}
+
if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) < -self.aim_maxpitch)
{
self.tur_head.avelocity_x = 0;
- self.tur_head.angles_x = self.aim_maxpitch;
+ self.tur_head.angles_x = -self.aim_maxpitch;
}
-
}
// rot
if((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) < -self.aim_maxrot)
{
self.tur_head.avelocity_y = 0;
- self.tur_head.angles_y = self.aim_maxrot;
+ self.tur_head.angles_y = -self.aim_maxrot;
}
-
}
-
}
// Ready?
if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)
- if (self.attack_finished_single >= time) return 0;
+ if (self.attack_finished_single > time) return 0;
// Special case: volly fire turret that has to fire a full volly if a shot was fired.
if (self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
- if not (self.volly_counter == self.shot_volly)
- return 1;
+ if (self.volly_counter != self.shot_volly)
+ if(self.ammo >= self.shot_dmg)
+ return 1;
// Lack of zombies makes shooting dead things unnecessary :P
if (self.firecheck_flags & TFL_FIRECHECK_DEAD)
if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)
if (self.enemy.ammo >= self.enemy.ammo_max)
return 0;
+
+ // Target of opertunity?
+ if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
+ {
+ self.enemy = self.tur_impactent;
+ return 1;
+ }
if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)
{
- // Not close enougth?
- //if (self.tur_dist_aimpos > self.target_range_fire) return 0;
-
// To close?
if (self.tur_dist_aimpos < self.target_range_min)
- return 0;
+ if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
+ return 1; // Target of opertunity?
+ else
+ return 0;
}
// Try to avoid FF?
if (self.tur_dist_impact_to_aimpos > self.aim_firetolerance_dist)
return 0;
- //if (self.tur_impactent != self.enemy)
-
// Volly status
if (self.shot_volly > 1)
if (self.volly_counter == self.shot_volly)
** Evaluate a entity for target valitity based on validate_flags
** NOTE: the caller must check takedamage before calling this, to inline this check.
**/
-float turret_validate_target(entity e_turret,entity e_target,float validate_flags)
+float turret_validate_target(entity e_turret, entity e_target, float validate_flags)
{
vector v_tmp;
}
// Can we even aim this thing?
- tvt_thadv = angleofs3(e_turret.tur_head.origin,e_turret.angles + e_turret.tur_head.angles ,e_target);
- //tvt_thadv = angleofs(e_turret.angles,e_target);
-
-
-
- tvt_tadv = shortangle_vxy(angleofs(e_turret,e_target),e_turret.angles);
+ tvt_thadv = angleofs3(e_turret.tur_head.origin, e_turret.angles + e_turret.tur_head.angles, e_target);
+ tvt_tadv = shortangle_vxy(angleofs(e_turret, e_target), e_turret.angles);
tvt_thadf = vlen(tvt_thadv);
tvt_tadf = vlen(tvt_tadv);
float score; // target looper entity score
entity e_enemy; // currently best scoreing target
float m_score; // currently best scoreing target's score
- float f;
m_score = 0;
if(self.enemy)
else
self.enemy = world;
- e = findradius(self.origin,self.target_range);
+ e = findradius(self.origin, self.target_range);
// Nothing to aim at?
- if (!e) return world;
+ if (!e)
+ return world;
while (e)
{
if(e.takedamage)
{
- f = turret_validate_target(self,e,self.target_select_flags);
- if (f > 0)
+ if (turret_validate_target(self, e, self.target_select_flags) > 0)
{
score = self.turret_score_target(self,e);
if ((score > m_score) && (score > 0))
if not (g_onslaught)
if (self.target)
{
- e = find(world,targetname,self.target);
+ e = find(world, targetname,self.target);
if (e != world)
self.team = e.team;
}
// Handle ammo
if not (self.spawnflags & TSF_NO_AMMO_REGEN)
if (self.ammo < self.ammo_max)
- self.ammo = min(self.ammo + self.ammo_recharge,self.ammo_max);
-
+ self.ammo = min(self.ammo + self.ammo_recharge, self.ammo_max);
// Inactive turrets needs to run the think loop,
// So they can handle animation and wake up if need be.
return;
}
- //This is just wrong :| and unlikely to ever happen.
- /*
- if(self.deadflag != DEAD_NO)
- {
- dprint("WARNING: dead turret running the think function!\n");
- return;
- }
- */
-
// This is typicaly used for zaping every target in range
// turret_fusionreactor uses this to recharge friendlys.
if (self.shoot_flags & TFL_SHOOT_HITALLVALID)
// Check if we have a vailid enemy, and try to find one if we dont.
- // g_turrets_targetscan_maxdelay forces a target re-scan this often
+ // g_turrets_targetscan_maxdelay forces a target re-scan at least this often
float do_target_scan;
if((self.target_select_time + cvar("g_turrets_targetscan_maxdelay")) < time)
do_target_scan = 1;
// Old target (if any) invalid?
- if (turret_validate_target(self,self.enemy,self.target_validate_flags) <= 0)
- do_target_scan = 1;
+ if (turret_validate_target(self, self.enemy, self.target_validate_flags) <= 0)
+ {
+ self.enemy = world;
+ do_target_scan = 1;
+ }
// But never more often then g_turrets_targetscan_mindelay!
if (self.target_select_time + cvar("g_turrets_targetscan_mindelay") > time)
turret_fire();
}
- // do any per-turret stuff
+ // do any custom per-turret stuff
if(self.turret_postthink)
self.turret_postthink();
}
if (cvar("g_turrets_nofire") != 0)
return;
- /*
- // unlikely to ever happen.
- if (self.deadflag != DEAD_NO)
- return;
-
- if not (self.tur_active)
- return;
- */
-
self.turret_firefunc();
self.attack_finished_single = time + self.shot_refire;
/*
When .used a turret switch team to activator.team.
- If activator is world, the turrets goes inactive.
+ If activator is world, the turret go inactive.
*/
void turret_stdproc_use()
{
- dprint("Turret ",self.netname, " used by ",activator.classname,"\n");
+ dprint("Turret ",self.netname, " used by ", activator.classname, "\n");
self.team = activator.team;
{
entity e, ee;
- // Are turrets allowed atm?
+ // Are turrets allowed?
if (cvar("g_turrets") == 0)
return 0;
self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize
}
else if not (teamplay)
- self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
+ self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
else if(g_onslaught && self.targetname)
{
e = find(world,target,self.targetname);
}
}
else if(!self.team)
- self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
+ self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
/*
* Try to guess some reasonaly defaults
* as possible beforehand.
*/
if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
- if not (self.ticrate) self.ticrate = 0.2; // Support units generaly dont need to have a high speed ai-loop
+ self.ticrate = 0.2; // Support units generaly dont need to have a high speed ai-loop
else
- if not (self.ticrate) self.ticrate = 0.1; // 10 fps for normal turrets
+ self.ticrate = 0.1; // 10 fps for normal turrets
- self.ticrate = bound(sys_frametime,self.ticrate,60); // keep it sane
+ self.ticrate = bound(sys_frametime, self.ticrate, 60); // keep it sane
// General stuff
if (self.netname == "")
if not (self.respawntime)
self.respawntime = 60;
- self.respawntime = max(-1,self.respawntime);
+ self.respawntime = max(-1, self.respawntime);
if not (self.health)
self.health = 1000;
- self.tur_health = max(1,self.health);
+ self.tur_health = max(1, self.health);
if not (self.turrcaps_flags)
self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
- if (!self.damage_flags)
+ if not (self.damage_flags)
self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
// Shot stuff.
if not (self.shot_refire)
self.shot_refire = 1;
- self.shot_refire = bound(0.01,self.shot_refire,9999);
+ self.shot_refire = bound(0.01, self.shot_refire, 9999);
if not (self.shot_dmg)
self.shot_dmg = self.shot_refire * 50;
- self.shot_dmg = max(1,self.shot_dmg);
+ self.shot_dmg = max(1, self.shot_dmg);
if not (self.shot_radius)
self.shot_radius = self.shot_dmg * 0.5;
- self.shot_radius = max(1,self.shot_radius);
+ self.shot_radius = max(1, self.shot_radius);
if not (self.shot_speed)
self.shot_speed = 2500;
- self.shot_speed = max(1,self.shot_speed);
+ self.shot_speed = max(1, self.shot_speed);
if not (self.shot_spread)
self.shot_spread = 0.0125;
- self.shot_spread = bound(0.0001,self.shot_spread,500);
+ self.shot_spread = bound(0.0001, self.shot_spread, 500);
if not (self.shot_force)
self.shot_force = self.shot_dmg * 0.5 + self.shot_radius * 0.5;
- self.shot_force = bound(0.001,self.shot_force,MAX_SHOT_DISTANCE * 0.5);
+ self.shot_force = bound(0.001, self.shot_force, 5000);
if not (self.shot_volly)
self.shot_volly = 1;
- self.shot_volly = bound(1,self.shot_volly,floor(self.ammo_max / self.shot_dmg));
+ self.shot_volly = bound(1, self.shot_volly, floor(self.ammo_max / self.shot_dmg));
if not (self.shot_volly_refire)
self.shot_volly_refire = self.shot_refire * self.shot_volly;
- self.shot_volly_refire = bound(self.shot_refire,self.shot_volly_refire,60);
+ self.shot_volly_refire = bound(self.shot_refire, self.shot_volly_refire, 60);
if not (self.firecheck_flags)
self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |
// Range stuff.
if not (self.target_range)
self.target_range = self.shot_speed * 0.5;
- self.target_range = bound(0,self.target_range,MAX_SHOT_DISTANCE);
+ self.target_range = bound(0, self.target_range, MAX_SHOT_DISTANCE);
if not (self.target_range_min)
self.target_range_min = self.shot_radius * 2;
- self.target_range_min = bound(0,self.target_range_min,MAX_SHOT_DISTANCE);
-
- //if (!self.target_range_fire)
- // self.target_range_fire = self.target_range * 0.8;
- //self.target_range_fire = bound(0,self.target_range_fire,MAX_SHOT_DISTANCE);
+ self.target_range_min = bound(0, self.target_range_min, MAX_SHOT_DISTANCE);
if not (self.target_range_optimal)
self.target_range_optimal = self.target_range * 0.5;
- self.target_range_optimal = bound(0,self.target_range_optimal,MAX_SHOT_DISTANCE);
+ self.target_range_optimal = bound(0, self.target_range_optimal, MAX_SHOT_DISTANCE);
// Aim stuff.
if not (self.aim_maxrot)
self.aim_maxrot = 90;
- self.aim_maxrot = bound(0,self.aim_maxrot,360);
+ self.aim_maxrot = bound(0, self.aim_maxrot, 360);
if not (self.aim_maxpitch)
self.aim_maxpitch = 20;
- self.aim_maxpitch = bound(0,self.aim_maxpitch,90);
+ self.aim_maxpitch = bound(0, self.aim_maxpitch, 90);
if not (self.aim_speed)
self.aim_speed = 36;
- self.aim_speed = bound(0.1,self.aim_speed, 1000);
+ self.aim_speed = bound(0.1, self.aim_speed, 1000);
if not (self.aim_firetolerance_dist)
self.aim_firetolerance_dist = 5 + (self.shot_radius * 2);
- self.aim_firetolerance_dist = bound(0.1,self.aim_firetolerance_dist,MAX_SHOT_DISTANCE);
+ self.aim_firetolerance_dist = bound(0.1, self.aim_firetolerance_dist, MAX_SHOT_DISTANCE);
if not (self.aim_flags)
{
self.aim_flags |= TFL_AIM_GROUND2;
}
- // Sill the most tested (and aim-effective)
if not (self.track_type)
self.track_type = TFL_TRACKTYPE_STEPMOTOR;
if (self.track_type != TFL_TRACKTYPE_STEPMOTOR)
{
- // Fluid / Ineria mode. Looks mutch nicer, bit experimental &
- // Can inmapt aim preformance alot.
- // needs a bit diffrent aimspeed
+ // Fluid / Ineria mode. Looks mutch nicer.
+ // Can reduce aim preformance alot, needs a bit diffrent aimspeed
if not (self.aim_speed)
self.aim_speed = 180;
- self.aim_speed = bound(0.1,self.aim_speed, 1000);
+ self.aim_speed = bound(0.1, self.aim_speed, 1000);
if not (self.track_accel_pitch)
self.track_accel_pitch = 0.5;
// Target selection stuff.
if not (self.target_select_rangebias)
self.target_select_rangebias = 1;
- self.target_select_rangebias = bound(-10,self.target_select_rangebias,10);
+ self.target_select_rangebias = bound(-10, self.target_select_rangebias, 10);
if not (self.target_select_samebias)
self.target_select_samebias = 1;
- self.target_select_samebias = bound(-10,self.target_select_samebias,10);
+ self.target_select_samebias = bound(-10, self.target_select_samebias, 10);
if not (self.target_select_anglebias)
self.target_select_anglebias = 1;
- self.target_select_anglebias = bound(-10,self.target_select_anglebias,10);
+ self.target_select_anglebias = bound(-10, self.target_select_anglebias, 10);
if not (self.target_select_missilebias)
self.target_select_missilebias = -10;
- self.target_select_missilebias = bound(-10,self.target_select_missilebias,10);
- self.target_select_playerbias = bound(-10,self.target_select_playerbias,10);
+ self.target_select_missilebias = bound(-10, self.target_select_missilebias, 10);
+ self.target_select_playerbias = bound(-10, self.target_select_playerbias, 10);
if not (self.target_select_flags)
{
// Ammo stuff
if not (self.ammo_max)
self.ammo_max = self.shot_dmg * 10;
- self.ammo_max = max(self.shot_dmg,self.ammo_max);
+ self.ammo_max = max(self.shot_dmg, self.ammo_max);
if not (self.ammo)
self.ammo = self.shot_dmg * 5;
- self.ammo = bound(0,self.ammo,self.ammo_max);
+ self.ammo = bound(0,self.ammo, self.ammo_max);
if not (self.ammo_recharge)
self.ammo_recharge = self.shot_dmg * 0.5;
- self.ammo_recharge = max(0,self.ammo_recharge);
+ self.ammo_recharge = max(0 ,self.ammo_recharge);
// Convert the recharge from X per sec to X per ticrate
self.ammo_recharge = self.ammo_recharge * self.ticrate;
self.tur_head.team = self.team;
self.tur_head.owner = self;
- setmodel(self,base);
- setmodel(self.tur_head,head);
+ setmodel(self, base);
+ setmodel(self.tur_head, head);
- setsize(self,'-32 -32 0','32 32 64');
- setsize(self.tur_head,'0 0 0','0 0 0');
+ setsize(self, '-32 -32 0', '32 32 64');
+ setsize(self.tur_head, '0 0 0', '0 0 0');
- setorigin(self.tur_head,'0 0 0');
+ setorigin(self.tur_head, '0 0 0');
setattachment(self.tur_head, self, "tag_head");
if (!self.health)
// In target defend mode, aim on the spot to defend when idle.
if (self.tur_defend)
- self.idle_aim = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend);
+ self.idle_aim = self.tur_head.angles + angleofs(self.tur_head, self.tur_defend);
else
self.idle_aim = '0 0 0';
self.use();
}
+ turret_stdproc_respawn();
return 1;
}
-//--// Some support routines //--//
-
-#define anglemodss(a) (a - floor(a / 360) * 360)
-
-float(float v) anglemods =
+/*
+* Return a angle within +/- 360.
+*/
+float anglemods(float v)
{
v = v - 360 * floor(v / 360);
- return v;
-}
-
-float safeangle(float a)
-{
- if((a >= -360) && (a <= 360))
- return a;
-
-
- a -= (360 * floor(a / 360));
-
- return a;
+
+ if(v >= 180)
+ return v - 360;
+ else if(v <= -180)
+ return v + 360;
+ else
+ return v;
}
-float shortangle_f(float ang1,float ang2)
+/*
+* Return the short angle
+*/
+float shortangle_f(float ang1, float ang2)
{
if(ang1 > ang2)
{
return ang1;
}
-vector shortangle_v(vector ang1,vector ang2)
+vector shortangle_v(vector ang1, vector ang2)
{
vector vtmp;
return vtmp;
}
-vector shortangle_vxy(vector ang1,vector ang2)
+vector shortangle_vxy(vector ang1, vector ang2)
{
vector vtmp;
return vtmp;
}
-// Get real origin
+
+/*
+* Get "real" origin, in worldspace, even if ent is attached to something else.
+*/
vector real_origin(entity ent)
{
entity e;
e = ent.tag_entity;
while(e)
{
- // v = v + e.origin;
v = v + ((e.absmin + e.absmax) * 0.5);
e = e.tag_entity;
}
- //v = v + ent.origin;
v = v + ((ent.absmin + ent.absmax) * 0.5);
return v;
}
-// Plug this into wherever precache is done.
-void g_turrets_common_precash()
-{
- precache_model ("models/turrets/c512.md3");
- precache_model ("models/marker.md3");
-}
-
-void SUB_Remove();
-void marker_think()
-{
- if(self.cnt)
- if(self.cnt < time)
- {
- self.think = SUB_Remove;
- self.nextthink = time;
- return;
- }
-
- self.frame += 1;
- if(self.frame > 29)
- self.frame = 0;
-
- self.nextthink = time;
-}
-
-void mark_error(vector where,float lifetime)
-{
- entity err;
-
- err = spawn();
- err.classname = "error_marker";
- setmodel(err,"models/marker.md3");
- setorigin(err,where);
- err.movetype = MOVETYPE_NONE;
- err.think = marker_think;
- err.nextthink = time;
- err.skin = 0;
- if(lifetime)
- err.cnt = lifetime + time;
-}
-
-void mark_info(vector where,float lifetime)
-{
- entity err;
-
- err = spawn();
- err.classname = "info_marker";
- setmodel(err,"models/marker.md3");
- setorigin(err,where);
- err.movetype = MOVETYPE_NONE;
- err.think = marker_think;
- err.nextthink = time;
- err.skin = 1;
- if(lifetime)
- err.cnt = lifetime + time;
-}
-
-entity mark_misc(vector where,float lifetime)
-{
- entity err;
-
- err = spawn();
- err.classname = "mark_misc";
- setmodel(err,"models/marker.md3");
- setorigin(err,where);
- err.movetype = MOVETYPE_NONE;
- err.think = marker_think;
- err.nextthink = time;
- err.skin = 3;
- if(lifetime)
- err.cnt = lifetime + time;
- return err;
-}
-
-/*
-* Paint a v_color colord circle on target onwho
-* that fades away over f_time
-*/
-void paint_target(entity onwho, float f_size, vector v_color, float f_time)
-{
- entity e;
-
- e = spawn();
- setmodel(e, "models/turrets/c512.md3"); // precision set above
- e.scale = (f_size/512);
- //setsize(e, '0 0 0', '0 0 0');
- //setattachment(e,onwho,"");
- setorigin(e,onwho.origin + '0 0 1');
- e.alpha = 0.15;
- e.movetype = MOVETYPE_FLY;
-
- e.velocity = (v_color * 32); // + '0 0 1' * 64;
-
- e.colormod = v_color;
- SUB_SetFade(e,time,f_time);
-}
-
-void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
-{
- entity e;
-
- e = spawn();
- setmodel(e, "models/turrets/c512.md3"); // precision set above
- e.scale = (f_size/512);
- setsize(e, '0 0 0', '0 0 0');
-
- setorigin(e,onwho.origin + '0 0 1');
- e.alpha = 0.15;
- e.movetype = MOVETYPE_FLY;
-
- e.velocity = (v_color * 32); // + '0 0 1' * 64;
- e.avelocity_x = -128;
-
- e.colormod = v_color;
- SUB_SetFade(e,time,f_time);
-}
-
-void paint_target3(vector where, float f_size, vector v_color, float f_time)
-{
- entity e;
- e = spawn();
- setmodel(e, "models/turrets/c512.md3"); // precision set above
- e.scale = (f_size/512);
- setsize(e, '0 0 0', '0 0 0');
- setorigin(e,where+ '0 0 1');
- e.movetype = MOVETYPE_NONE;
- e.velocity = '0 0 0';
- e.colormod = v_color;
- SUB_SetFade(e,time,f_time);
-}
-
/*
* Return the angle between two enteties
*/
vector angleofs(entity from, entity to)
{
vector v_res;
-
- // makevectors(from.angles);
+
v_res = normalize(to.origin - from.origin);
v_res = vectoangles(v_res);
v_res = v_res - from.angles;
- if (v_res_x < 0) v_res_x += 360;
- if (v_res_x > 180) v_res_x -= 360;
-
- if (v_res_y < 0) v_res_y += 360;
- if (v_res_y > 180) v_res_y -= 360;
-
- return v_res;
-}
-
-vector angleofs2(entity from, vector to)
-{
- vector v_res;
-
- // makevectors(from.angles);
- v_res = normalize(to - from.origin);
- v_res = vectoangles(v_res);
- v_res = v_res - from.angles;
-
- if (v_res_x < 0) v_res_x += 360;
- if (v_res_x > 180) v_res_x -= 360;
+ if (v_res_x < 0) v_res_x += 360;
+ if (v_res_x > 180) v_res_x -= 360;
- if (v_res_y < 0) v_res_y += 360;
- if (v_res_y > 180) v_res_y -= 360;
+ if (v_res_y < 0) v_res_y += 360;
+ if (v_res_y > 180) v_res_y -= 360;
return v_res;
}
-vector angleofs3(vector from,vector from_a, entity to)
+vector angleofs3(vector from, vector from_a, entity to)
{
vector v_res;
-
- // makevectors(from.angles);
+
v_res = normalize(to.origin - from);
v_res = vectoangles(v_res);
v_res = v_res - from_a;
- if (v_res_x < 0) v_res_x += 360;
- if (v_res_x > 180) v_res_x -= 360;
+ if (v_res_x < 0) v_res_x += 360;
+ if (v_res_x > 180) v_res_x -= 360;
- if (v_res_y < 0) v_res_y += 360;
- if (v_res_y > 180) v_res_y -= 360;
+ if (v_res_y < 0) v_res_y += 360;
+ if (v_res_y > 180) v_res_y -= 360;
return v_res;
}
-float turret_tag_setup()
-{
- if(!self.tur_head)
- {
- dprint("Call to turret_tag_setup with self.tur_head missing!\n");
- self.tur_shotorg = '0 0 0';
- return 0;
- }
-
- //if not(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
- // setorigin(self.tur_head,gettaginfo(self,gettagindex(self,"tag_head")));
-
- self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
-
- v_forward = normalize(v_forward);
-
- return 1;
-}
-
+/*
+* Update self.tur_shotorg by getting up2date bone info
+* NOTICE this func overwrites the global v_forward, v_right and v_up vectors.
+*/
float turret_tag_fire_update()
{
if(!self.tur_head)
{
- dprint("Call to turret_tag_fire_update with self.tur_head missing!\n");
+ error("Call to turret_tag_fire_update with self.tur_head missing!\n");
self.tur_shotorg = '0 0 0';
- return 0;
+ return FALSE;
}
- self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
+ self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
v_forward = normalize(v_forward);
- //dprint("update: tur_shotorg: ",vtos(self.tur_shotorg)," origin:", vtos(self.tur_head.origin), " angels: ", vtos(self.tur_head.angles),"\n");
-
- return 1;
+ return TRUE;
}
-void FireImoBeam (vector start,vector end,vector smin,vector smax,
- float bforce,float f_dmg,float f_velfactor, float deathtype)
+/*
+* Railgun-like beam, but has thickness and suppots slowing of target
+*/
+void FireImoBeam (vector start, vector end, vector smin, vector smax,
+ float bforce, float f_dmg, float f_velfactor, float deathtype)
{
local vector hitloc, force, endpoint, dir;
trace_endpos = endpoint;
}
+// Plug this into wherever precache is done.
+void g_turrets_common_precash()
+{
+ precache_model ("models/turrets/c512.md3");
+ precache_model ("models/marker.md3");
+}
+
void turrets_precache_debug_models()
{
precache_model ("models/turrets/c512.md3");
//precache_model ("models/turrets/plasma.md3");
//precache_model ("models/turrets/tesla_head.md3");
//precache_model ("models/turrets/tesla_base.md3");
- //turrets_precache_debug_models();
+ #ifdef TURRET_DEBUG
+ turrets_precache_debug_models();
+ #endif
+}
+
+
+#ifdef TURRET_DEBUG
+void SUB_Remove();
+void marker_think()
+{
+ if(self.cnt)
+ if(self.cnt < time)
+ {
+ self.think = SUB_Remove;
+ self.nextthink = time;
+ return;
+ }
+
+ self.frame += 1;
+ if(self.frame > 29)
+ self.frame = 0;
+
+ self.nextthink = time;
+}
+
+void mark_error(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "error_marker";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 0;
+ if(lifetime)
+ err.cnt = lifetime + time;
+}
+
+void mark_info(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "info_marker";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 1;
+ if(lifetime)
+ err.cnt = lifetime + time;
+}
+
+entity mark_misc(vector where,float lifetime)
+{
+ entity err;
+
+ err = spawn();
+ err.classname = "mark_misc";
+ setmodel(err,"models/marker.md3");
+ setorigin(err,where);
+ err.movetype = MOVETYPE_NONE;
+ err.think = marker_think;
+ err.nextthink = time;
+ err.skin = 3;
+ if(lifetime)
+ err.cnt = lifetime + time;
+ return err;
+}
+
+/*
+* Paint a v_color colord circle on target onwho
+* that fades away over f_time
+*/
+void paint_target(entity onwho, float f_size, vector v_color, float f_time)
+{
+ entity e;
+
+ e = spawn();
+ setmodel(e, "models/turrets/c512.md3"); // precision set above
+ e.scale = (f_size/512);
+ //setsize(e, '0 0 0', '0 0 0');
+ //setattachment(e,onwho,"");
+ setorigin(e,onwho.origin + '0 0 1');
+ e.alpha = 0.15;
+ e.movetype = MOVETYPE_FLY;
+
+ e.velocity = (v_color * 32); // + '0 0 1' * 64;
+
+ e.colormod = v_color;
+ SUB_SetFade(e,time,f_time);
+}
+
+void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
+{
+ entity e;
+
+ e = spawn();
+ setmodel(e, "models/turrets/c512.md3"); // precision set above
+ e.scale = (f_size/512);
+ setsize(e, '0 0 0', '0 0 0');
+
+ setorigin(e,onwho.origin + '0 0 1');
+ e.alpha = 0.15;
+ e.movetype = MOVETYPE_FLY;
+
+ e.velocity = (v_color * 32); // + '0 0 1' * 64;
+ e.avelocity_x = -128;
+
+ e.colormod = v_color;
+ SUB_SetFade(e,time,f_time);
+}
+
+void paint_target3(vector where, float f_size, vector v_color, float f_time)
+{
+ entity e;
+ e = spawn();
+ setmodel(e, "models/turrets/c512.md3"); // precision set above
+ e.scale = (f_size/512);
+ setsize(e, '0 0 0', '0 0 0');
+ setorigin(e,where+ '0 0 1');
+ e.movetype = MOVETYPE_NONE;
+ e.velocity = '0 0 0';
+ e.colormod = v_color;
+ SUB_SetFade(e,time,f_time);
}
+#endif
/*
* Generic bias aware score system.
*/
-float turret_stdproc_targetscore_generic(entity e_turret,entity e_target)
+float turret_stdproc_targetscore_generic(entity e_turret, entity e_target)
{
//vector v_tmp;
float d_dist; // Defendmode Distance
float ikr; // ideal kill range
- if(!e_target) return 0;
-
- //if (e_target == e_turret.enemy) s_score = 1;
+ /*
+ if(!e_target)
+ return 0;
+ */
if (e_turret.tur_defend)
{
if ((e_turret.target_select_playerbias > 0) && (e_target.flags & FL_CLIENT))
p_score = 1;
- d_score = max(d_score,0);
- a_score = max(a_score,0);
- m_score = max(m_score,0);
- p_score = max(p_score,0);
+ d_score = max(d_score, 0);
+ a_score = max(a_score, 0);
+ m_score = max(m_score, 0);
+ p_score = max(p_score, 0);
score = (d_score * e_turret.target_select_rangebias) +
(a_score * e_turret.target_select_anglebias) +
proj.bot_dodgerating = self.shot_dmg;
proj.think = turret_ewheel_projectile_explode;
proj.nextthink = time + 9;
- proj.solid = SOLID_BBOX;
+ //proj.solid = SOLID_TRIGGER;
proj.movetype = MOVETYPE_FLYMISSILE;
proj.velocity = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
proj.touch = turret_ewheel_projectile_explode;
proj.enemy = self.enemy;
proj.flags = FL_PROJECTILE | FL_NOTARGET;
+ PROJECTILE_MAKETRIGGER(proj);
CSQCProjectile(proj, TRUE, PROJECTILE_LASER, TRUE);
}
self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
+ self.target_select_flags = TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;// | TFL_TARGETSELECT_LOS;
+ self.target_validate_flags = TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;// | TFL_TARGETSELECT_LOS;
self.damage_flags |= TFL_DMG_DEATH_NOGIBS;
self.iscreature = TRUE;
self.tur_head.aim_speed = cvar("g_turrets_unit_ewheel_turnrate");
self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
//setorigin(self,self.origin + '0 0 128');
self.damage_flags |= TFL_DMG_HEADSHAKE;
self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fire routine
}
if (self.tur_head.frame != 0)
- self.tur_head.frame = self.tur_head.frame + 1;
+ self.tur_head.frame += 1;
- if (self.tur_head.frame > 7)
+ if (self.tur_head.frame >= 7)
self.tur_head.frame = 0;
}
void turret_hellion_attack()
{
- local entity missile;
-
+ entity missile;
+
+ if(self.tur_head.frame != 0)
+ self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire"));
+ else
+ self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire2"));
+
sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
- // switch tubes
- //self.tur_shotorg_y = self.tur_shotorg_y * -1;
-
missile = spawn ();
setorigin(missile, self.tur_shotorg);
setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
missile.tur_health = time + 9;
missile.tur_aimpos = randomvec() * 128;
te_explosion (missile.origin);
-
CSQCProjectile(missile, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
- if (self.tur_head.frame == 0)
- self.tur_head.frame = self.tur_head.frame + 1;
-
+ self.tur_head.frame += 1;
}
void turret_hellion_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
return;
}
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
self.turret_firefunc = turret_hellion_attack;
self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fire routine
self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL;
- self.aim_flags = TFL_AIM_LEAD;
-
- if(cvar("g_antilag_bullets"))
- self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
- else
- self.aim_flags |= TFL_AIM_SHOTTIMECOMPENSATE;
+ self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+
+ if not (cvar("g_antilag_bullets"))
+ self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
if (turret_stdproc_init("machinegun_std",0,"models/turrets/base.md3","models/turrets/machinegun.md3") == 0)
{
self.damage_flags |= TFL_DMG_HEADSHAKE;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fire routine
void turret_mlrs_postthink()
{
-
// 0 = full, 6 = empty
- self.tur_head.frame = rint(6 - (self.ammo / self.shot_dmg));
+ self.tur_head.frame = bound(0, 6 - floor(0.1 + self.ammo / self.shot_dmg), 6);
+ if(self.tur_head.frame < 0)
+ {
+ dprint("ammo:",ftos(self.ammo),"\n");
+ dprint("shot_dmg:",ftos(self.shot_dmg),"\n");
+ }
+
}
void turret_mlrs_attack()
self.shoot_flags |= TFL_SHOOT_VOLLYALWAYS;
self.volly_counter = self.shot_volly;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fire routine
self.turrcaps_flags = TFL_TURRCAPS_SNIPER|TFL_TURRCAPS_HITSCAN|TFL_TURRCAPS_PLAYERKILL;
self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
- self.aim_flags = TFL_AIM_ZEASE | TFL_AIM_LEAD;
+ self.aim_flags = TFL_AIM_LEAD;
if (turret_stdproc_init("phaser_std",0,"models/turrets/base.md3","models/turrets/phaser.md3") == 0)
{
return;
}
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
self.turret_firecheckfunc = turret_phaser_firecheck;
self.damage_flags |= TFL_DMG_HEADSHAKE;
self.firecheck_flags |= TFL_FIRECHECK_AFF;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fireing routine
self.damage_flags |= TFL_DMG_HEADSHAKE;
self.firecheck_flags |= TFL_FIRECHECK_AFF;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
// Our fireing routine
self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
self.turret_firefunc = turret_tesla_fire;
return;
}
- if (!turret_tag_setup())
+ if (!turret_tag_fire_update())
dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
self.damage_flags |= TFL_DMG_DEATH_NOGIBS;
ftmp2 = ftmp * -1;
ftmp = bound(ftmp2, shortangle_f(player.v_angle_y - racer.angles_y, racer.angles_y), ftmp);
- ftmp2 = safeangle(racer.angles_y + ftmp);
+ ftmp2 = anglemods(racer.angles_y + ftmp);
// Roll
ftmp = bound(-45, shortangle_f(player.v_angle_z + ((racer.angles_y - ftmp2) * racer_turnroll), racer.angles_z), 45);
- ftmp = safeangle(racer.angles_z + ftmp);
+ ftmp = anglemods(racer.angles_z + ftmp);
racer.angles_z = bound(-85, ftmp, 85);
// Turn
ftmp2 = ftmp * -1;
ftmp = bound(ftmp2,shortangle_f(player.v_angle_x - racer.angles_x,racer.angles_x),ftmp);
- racer.angles_x = safeangle(racer.angles_x + ftmp);
+ racer.angles_x = anglemods(racer.angles_x + ftmp);
racer.angles_x *= -1;
df = racer.velocity * -0.5;
//vhic.angles_z = ftmp;
// Turn
- vhic.angles_y = safeangle(vhic.angles_y + ftmp);
+ vhic.angles_y = anglemods(vhic.angles_y + ftmp);
// Pitch Body
ftmp = raptor_pitchspeed * sys_frametime;
ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - vhic.angles_x,vhic.angles_x), ftmp);
- vhic.angles_x = bound(-60,safeangle(vhic.angles_x + ftmp),60);
+ vhic.angles_x = bound(-60,anglemods(vhic.angles_x + ftmp),60);
vhic.angles_x *= -1;
if(raptor_movestyle == 1)
}
else
{
- spider.angles_y = safeangle(spider.angles_y + ftmp);
+ spider.angles_y = anglemods(spider.angles_y + ftmp);
spider.tur_head.angles_y -= ftmp;
if(player.movement_x != 0)
#include "w_shotgun.qc"
#include "w_uzi.qc"
#include "w_grenadelauncher.qc"
+#include "w_minelayer.qc"
#include "w_electro.qc"
#include "w_crylink.qc"
#include "w_nex.qc"
w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward;
}
- fireBallisticBullet(w_shotorg, w_shotdir, pSpread, pSpeed, pLifetime, pDamage, pHeadshotAddedDamage / pDamage, pForce, deathtype, (cvar("g_balance_campingrifle_tracer") ? EF_RED : EF_BLUE), 1, pBulletConstant);
+ if(deathtype & HITTYPE_SECONDARY)
+ fireBallisticBullet(w_shotorg, w_shotdir, pSpread, pSpeed, pLifetime, pDamage, pHeadshotAddedDamage / pDamage, pForce, deathtype, (cvar("g_balance_campingrifle_secondary_tracer") ? EF_RED : EF_BLUE), 1, pBulletConstant);
+ else
+ fireBallisticBullet(w_shotorg, w_shotdir, pSpread, pSpeed, pLifetime, pDamage, pHeadshotAddedDamage / pDamage, pForce, deathtype, (cvar("g_balance_campingrifle_primary_tracer") ? EF_RED : EF_BLUE), 1, pBulletConstant);
endFireBallisticBullet();
if (cvar("g_casings") >= 2)
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
#ifdef SVQC
.float gravity;
-.entity realowner;
-
.entity queuenext;
.entity queueprev;
void lgbeam_think()
{
self.owner.prevlgfire = time;
- if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self != self.owner.lgbeam || self.owner.deadflag != DEAD_NO || !self.owner.BUTTON_ATCK)
+ if (self != self.owner.lgbeam)
{
remove(self);
return;
}
+ if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self.owner.deadflag != DEAD_NO || !self.owner.BUTTON_ATCK)
+ {
+ if(self == self.owner.lgbeam)
+ self.owner.lgbeam = world;
+ remove(self);
+ return;
+ }
self.nextthink = time;
makevectors(self.owner.v_angle);
- float dt;
+ float dt, f;
dt = frametime;
if not(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)
{
if(cvar("g_balance_electro_primary_ammo"))
- dt = min(frametime, self.owner.ammo_cells / cvar("g_balance_electro_primary_ammo"));
- self.owner.ammo_cells = max(0, self.owner.ammo_cells - cvar("g_balance_electro_primary_ammo") * frametime);
+ {
+ dt = min(dt, self.owner.ammo_cells / cvar("g_balance_electro_primary_ammo"));
+ self.owner.ammo_cells = max(0, self.owner.ammo_cells - cvar("g_balance_electro_primary_ammo") * frametime);
+ }
}
W_SetupShot_Range(self.owner, TRUE, 0, "", cvar("g_balance_electro_primary_damage") * dt, cvar("g_balance_electro_primary_range"));
{
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);
{
if(cvar("g_balance_electro_lightning"))
{
- if (self.BUTTON_ATCK_prev == 0)
+ if ((!self.lgbeam) || wasfreed(self.lgbeam))
{
W_Electro_Attack3();
}
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)
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");
}
{
if (self.BUTTON_ATCK)
if (time >= self.fireball_primarytime)
- if (weapon_prepareattack(1, cvar("g_balance_fireball_primary_refire")))
+ if (weapon_prepareattack(0, cvar("g_balance_fireball_primary_refire")))
{
W_Fireball_Attack1_Frame0();
self.fireball_primarytime = time + cvar("g_balance_fireball_primary_refire2");
}
if (self.BUTTON_ATCK2)
- if (weapon_prepareattack(0, cvar("g_balance_fireball_secondary_refire")))
+ if (weapon_prepareattack(1, cvar("g_balance_fireball_secondary_refire")))
{
W_Fireball_Attack2();
weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_fireball_secondary_animtime"), w_ready);
}
else if(req == WR_PRECACHE)
{
- precache_sound("weapons/fireball_impact.wav");
precache_sound("weapons/fireball_impact2.wav");
}
else if (req == WR_SUICIDEMESSAGE)
REGISTER_WEAPON(GRENADE_LAUNCHER, w_glauncher, IT_ROCKETS, 4, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "gl", "grenadelauncher", "Mortar");
#else
#ifdef SVQC
+.float gl_detonate_later;
+.float gl_bouncecnt;
+
void W_Grenade_Explode (void)
{
if(other.takedamage == DAMAGE_AIM)
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);
}
}
+void W_Grenade_Think1 (void)
+{
+ self.nextthink = time;
+ if (time > self.cnt)
+ {
+ other = world;
+ self.projectiledeathtype |= HITTYPE_BOUNCE;
+ W_Grenade_Explode ();
+ return;
+ }
+ if(self.gl_detonate_later && self.gl_bouncecnt >= cvar("g_balance_grenadelauncher_primary_remote_minbouncecnt"))
+ W_Grenade_Explode();
+}
+
void W_Grenade_Touch1 (void)
{
PROJECTILE_TOUCH;
- if(cvar("g_balance_grenadelauncher_primary_sticky") && other.takedamage != DAMAGE_AIM)
+ if (other.takedamage == DAMAGE_AIM || cvar("g_balance_grenadelauncher_primary_type") == 0) // always explode when hitting a player, or if normal mortar projectile
+ {
+ self.use ();
+ }
+ else if (cvar("g_balance_grenadelauncher_primary_type") == 1) // bounce
+ {
+ float r;
+ r = random() * 6;
+ if(r < 1)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce1.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 2)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce2.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 3)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce3.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 4)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce4.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 5)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce5.wav", VOL_BASE, ATTN_NORM);
+ else
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce6.wav", VOL_BASE, ATTN_NORM);
+ self.projectiledeathtype |= HITTYPE_BOUNCE;
+ self.gl_bouncecnt += 1;
+ }
+ else if(cvar("g_balance_grenadelauncher_primary_type") == 2 && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))) // stick
{
spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM);
self.nextthink = min(self.nextthink, time + cvar("g_balance_grenadelauncher_primary_lifetime2"));
}
- else
- W_Grenade_Explode ();
}
void W_Grenade_Touch2 (void)
{
PROJECTILE_TOUCH;
- if(cvar("g_balance_grenadelauncher_secondary_sticky") && other.takedamage != DAMAGE_AIM)
+ if (other.takedamage == DAMAGE_AIM || cvar("g_balance_grenadelauncher_secondary_type") == 0) // always explode when hitting a player, or if normal mortar projectile
+ {
+ self.use ();
+ }
+ else if (cvar("g_balance_grenadelauncher_secondary_type") == 1) // bounce
+ {
+ float r;
+ r = random() * 6;
+ if(r < 1)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce1.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 2)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce2.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 3)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce3.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 4)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce4.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 5)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce5.wav", VOL_BASE, ATTN_NORM);
+ else
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce6.wav", VOL_BASE, ATTN_NORM);
+ self.projectiledeathtype |= HITTYPE_BOUNCE;
+ self.gl_bouncecnt += 1;
+ }
+ else if(cvar("g_balance_grenadelauncher_secondary_type") == 2 && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))) // stick
{
spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM);
self.nextthink = min(self.nextthink, time + cvar("g_balance_grenadelauncher_secondary_lifetime2"));
}
- else
- {
- if (other.takedamage == DAMAGE_AIM)
- {
- self.use ();
- }
- else
- {
- float r;
- r = random() * 6;
- if(r < 1)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce1.wav", VOL_BASE, ATTN_NORM);
- else if(r < 2)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce2.wav", VOL_BASE, ATTN_NORM);
- else if(r < 3)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce3.wav", VOL_BASE, ATTN_NORM);
- else if(r < 4)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce4.wav", VOL_BASE, ATTN_NORM);
- else if(r < 5)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce5.wav", VOL_BASE, ATTN_NORM);
- else
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce6.wav", VOL_BASE, ATTN_NORM);
- self.projectiledeathtype |= HITTYPE_BOUNCE;
- }
- }
}
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);
gren.bot_dodge = TRUE;
gren.bot_dodgerating = cvar("g_balance_grenadelauncher_primary_damage");
gren.movetype = MOVETYPE_BOUNCE;
+ gren.bouncefactor = cvar("g_balance_grenadelauncher_primary_bouncefactor");
+ gren.bouncestop = cvar("g_balance_grenadelauncher_primary_bouncestop");
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;
+ gren.cnt = time + cvar("g_balance_grenadelauncher_primary_lifetime");
+ gren.nextthink = time;
+ gren.think = W_Grenade_Think1;
gren.use = W_Grenade_Explode;
gren.touch = W_Grenade_Touch1;
gren.takedamage = DAMAGE_YES;
gren.health = cvar("g_balance_grenadelauncher_primary_health");
+ gren.damageforcescale = cvar("g_balance_grenadelauncher_primary_damageforcescale");
gren.event_damage = W_Grenade_Damage;
W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_primary);
gren.angles = vectoangles (gren.velocity);
gren.flags = FL_PROJECTILE;
- CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);
+ if(cvar("g_balance_grenadelauncher_primary_type") == 0 || cvar("g_balance_grenadelauncher_primary_type") == 2)
+ CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);
+ else
+ CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE_BOUNCING, TRUE);
}
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);
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;
gren.angles = vectoangles (gren.velocity);
gren.flags = FL_PROJECTILE;
- if(cvar("g_balance_grenadelauncher_secondary_sticky"))
+ if(cvar("g_balance_grenadelauncher_secondary_type") == 0 || cvar("g_balance_grenadelauncher_secondary_type") == 2)
CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);
else
CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE_BOUNCING, TRUE);
.float bot_secondary_grenademooth;
float w_glauncher(float req)
{
+ entity nade;
+ float nadefound;
+
if (req == WR_AIM)
{
self.BUTTON_ATCK = FALSE;
if (self.BUTTON_ATCK)
if (weapon_prepareattack(0, cvar("g_balance_grenadelauncher_primary_refire")))
{
- if(cvar("g_balance_grenadelauncher_primary2secondary"))
- W_Grenade_Attack2();
- else
- W_Grenade_Attack();
+ W_Grenade_Attack();
weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_grenadelauncher_primary_animtime"), w_ready);
}
- if (self.BUTTON_ATCK2 && !cvar("g_balance_grenadelauncher_primary2secondary"))
- if (weapon_prepareattack(1, cvar("g_balance_grenadelauncher_secondary_refire")))
+ if (self.BUTTON_ATCK2)
{
- W_Grenade_Attack2();
- weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_grenadelauncher_secondary_animtime"), w_ready);
+ if (cvar("g_balance_grenadelauncher_secondary_remote_detonateprimary"))
+ {
+ nadefound = 0;
+ for(nade = world; (nade = find(nade, classname, "grenade")); ) if(nade.owner == self)
+ {
+ if(!nade.gl_detonate_later)
+ {
+ nade.gl_detonate_later = TRUE;
+ nadefound = 1;
+ }
+ }
+ if(nadefound)
+ sound (self, CHAN_WEAPON2, "weapons/rocket_det.wav", VOL_BASE, ATTN_NORM);
+ }
+ else if (weapon_prepareattack(1, cvar("g_balance_grenadelauncher_secondary_refire")))
+ {
+ W_Grenade_Attack2();
+ weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_grenadelauncher_secondary_animtime"), w_ready);
+ }
}
}
else if (req == WR_PRECACHE)
--- /dev/null
+#ifdef REGISTER_WEAPON
+REGISTER_WEAPON(MINE_LAYER, w_minelayer, IT_ROCKETS, 4, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "minelayer", "minelayer", "Mine Layer");
+#else
+#ifdef SVQC
+void W_Mine_Think (void);
+.float minelayer_detonate, minelayer_mines;
+.float mine_time;
+
+void spawnfunc_weapon_minelayer (void)
+{
+ weapon_defaultspawnfunc(WEP_MINE_LAYER);
+}
+
+void W_Mine_Stick ()
+{
+ spamsound (self, CHAN_PROJECTILE, "weapons/mine_stick.wav", VOL_BASE, ATTN_NORM);
+
+ // in order for mines to face properly when sticking to the ground, they must be a server side entity rather than a csqc projectile
+
+ entity newmine;
+ newmine = spawn();
+ newmine.classname = self.classname;
+
+ newmine.bot_dodge = self.bot_dodge;
+ newmine.bot_dodgerating = self.bot_dodgerating;
+
+ newmine.owner = self.owner;
+ setsize(newmine, '-4 -4 -4', '4 4 4');
+ setorigin(newmine, self.origin);
+ setmodel(newmine, "models/mine.md3");
+ newmine.angles = vectoangles(-trace_plane_normal); // face against the surface
+
+ newmine.takedamage = self.takedamage;
+ newmine.damageforcescale = self.damageforcescale;
+ newmine.health = self.health;
+ newmine.event_damage = self.event_damage;
+
+ newmine.movetype = MOVETYPE_NONE; // lock the mine in place
+ newmine.projectiledeathtype = self.projectiledeathtype;
+
+ newmine.mine_time = self.mine_time;
+
+ newmine.touch = SUB_Null;
+ newmine.think = W_Mine_Think;
+ newmine.nextthink = time;
+ newmine.cnt = self.cnt;
+ newmine.flags = self.flags;
+
+ remove(self);
+ self = newmine;
+}
+
+void W_Mine_Explode ()
+{
+ if(other.takedamage == DAMAGE_AIM)
+ if(other.classname == "player")
+ if(IsDifferentTeam(self.owner, other))
+ if(IsFlying(other))
+ AnnounceTo(self.owner, "airshot");
+
+ self.event_damage = SUB_Null;
+ self.takedamage = DAMAGE_NO;
+
+ RadiusDamage (self, self.owner, cvar("g_balance_minelayer_damage"), cvar("g_balance_minelayer_edgedamage"), cvar("g_balance_minelayer_radius"), world, cvar("g_balance_minelayer_force"), self.projectiledeathtype, other);
+
+ if (self.owner.weapon == WEP_MINE_LAYER)
+ {
+ if(self.owner.ammo_rockets < cvar("g_balance_minelayer_ammo"))
+ {
+ self.owner.cnt = WEP_MINE_LAYER;
+ ATTACK_FINISHED(self.owner) = time;
+ self.owner.switchweapon = w_getbestweapon(self.owner);
+ }
+ }
+ remove (self);
+}
+
+void W_Mine_DoRemoteExplode ()
+{
+ self.event_damage = SUB_Null;
+ self.takedamage = DAMAGE_NO;
+
+ RadiusDamage (self, self.owner, cvar("g_balance_minelayer_remote_damage"), cvar("g_balance_minelayer_remote_edgedamage"), cvar("g_balance_minelayer_remote_radius"), world, cvar("g_balance_minelayer_remote_force"), self.projectiledeathtype | HITTYPE_BOUNCE, world);
+
+ if (self.owner.weapon == WEP_MINE_LAYER)
+ {
+ if(self.owner.ammo_rockets < cvar("g_balance_minelayer_ammo"))
+ {
+ self.owner.cnt = WEP_MINE_LAYER;
+ ATTACK_FINISHED(self.owner) = time;
+ self.owner.switchweapon = w_getbestweapon(self.owner);
+ }
+ }
+ remove (self);
+}
+
+void W_Mine_RemoteExplode ()
+{
+ if(self.owner.deadflag == DEAD_NO)
+ if((self.spawnshieldtime >= 0)
+ ? (time >= self.spawnshieldtime) // timer
+ : (vlen(NearestPointOnBox(self.owner, self.origin) - self.origin) > cvar("g_balance_minelayer_radius")) // safety device
+ )
+ {
+ W_Mine_DoRemoteExplode();
+ }
+}
+
+void W_Mine_ProximityExplode ()
+{
+ // make sure no friend is in the mine's radius. If there is any, explosion is delayed until he's at a safe distance
+ if(cvar("g_balance_minelayer_protection"))
+ {
+ entity head;
+ head = findradius(self.origin, cvar("g_balance_minelayer_radius"));
+ while(head)
+ {
+ if(head == self.owner || !IsDifferentTeam(head, self.owner))
+ return;
+ head = head.chain;
+ }
+ }
+
+ self.mine_time = 0;
+ W_Mine_Explode();
+}
+
+void W_Mine_Think (void)
+{
+ entity head;
+
+ self.nextthink = time;
+ if (time > self.cnt)
+ {
+ other = world;
+ self.projectiledeathtype |= HITTYPE_BOUNCE;
+ W_Mine_Explode();
+ return;
+ }
+
+ // a player's mines shall explode if he disconnects or dies
+ // TODO: Do this on team change too
+ if(self.owner.classname != "player" || self.owner.deadflag != DEAD_NO)
+ {
+ other = world;
+ self.projectiledeathtype |= HITTYPE_BOUNCE;
+ W_Mine_Explode();
+ return;
+ }
+
+ // set the mine for detonation when a foe gets close enough
+ head = findradius(self.origin, cvar("g_balance_minelayer_proximityradius"));
+ while(head)
+ {
+ if(head.classname == "player" && head.deadflag == DEAD_NO)
+ if(head != self.owner && IsDifferentTeam(head, self.owner)) // don't trigger for team mates
+ if(!self.mine_time)
+ {
+ spamsound (self, CHAN_PROJECTILE, "weapons/mine_trigger.wav", VOL_BASE, ATTN_NORM);
+ self.mine_time = time + cvar("g_balance_minelayer_time");
+ }
+ head = head.chain;
+ }
+
+ // explode if it's time to
+ if(self.mine_time && time >= self.mine_time)
+ W_Mine_ProximityExplode();
+
+ // remote detonation
+ if (self.owner.weapon == WEP_MINE_LAYER)
+ if (self.owner.deadflag == DEAD_NO)
+ if (self.minelayer_detonate)
+ W_Mine_RemoteExplode();
+
+ if(self.csqcprojectile_clientanimate == 0)
+ UpdateCSQCProjectile(self);
+}
+
+void W_Mine_Touch (void)
+{
+ PROJECTILE_TOUCH;
+ if(!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))
+ W_Mine_Stick();
+ else if(self.movetype != MOVETYPE_NONE) // don't unstick a locked mine when someone touches it
+ self.velocity = '0 0 0';
+}
+
+void W_Mine_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+ if (self.health <= 0)
+ return;
+ self.health = self.health - damage;
+ self.angles = vectoangles(self.velocity);
+ if (self.health <= 0)
+ W_PrepareExplosionByDamage(attacker, W_Mine_Explode);
+}
+
+void W_Mine_Attack (void)
+{
+ entity mine;
+ entity flash;
+
+ // scan how many mines we placed, and return if we reached our limit
+ if(cvar("g_balance_minelayer_limit"))
+ {
+ self.minelayer_mines = 0;
+ for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
+ self.minelayer_mines += 1;
+
+ if(self.minelayer_mines >= cvar("g_balance_minelayer_limit"))
+ {
+ // the refire delay keeps this message from being spammed
+ sprint(self, strcat("You cannot place more than ^2", cvar_string("g_balance_minelayer_limit"), " ^7mines at a time\n") );
+ play2(self, "weapons/unavailable.wav");
+ return;
+ }
+ }
+
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ self.ammo_rockets = self.ammo_rockets - cvar("g_balance_minelayer_ammo");
+
+ W_SetupShot_ProjectileSize (self, '-4 -4 -4', '4 4 4', FALSE, 5, "weapons/mine_fire.wav", cvar("g_balance_minelayer_damage"));
+ pointparticles(particleeffectnum("rocketlauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
+
+ mine = WarpZone_RefSys_SpawnSameRefSys(self);
+ mine.owner = self;
+ if(cvar("g_balance_minelayer_detonatedelay") >= 0)
+ mine.spawnshieldtime = time + cvar("g_balance_minelayer_detonatedelay");
+ else
+ mine.spawnshieldtime = -1;
+ mine.classname = "mine";
+ mine.bot_dodge = TRUE;
+ mine.bot_dodgerating = cvar("g_balance_minelayer_damage") * 2; // * 2 because it can detonate inflight which makes it even more dangerous
+
+ mine.takedamage = DAMAGE_YES;
+ mine.damageforcescale = cvar("g_balance_minelayer_damageforcescale");
+ mine.health = cvar("g_balance_minelayer_health");
+ mine.event_damage = W_Mine_Damage;
+
+ mine.movetype = MOVETYPE_TOSS;
+ PROJECTILE_MAKETRIGGER(mine);
+ mine.projectiledeathtype = WEP_MINE_LAYER;
+ setsize (mine, '-4 -4 -4', '4 4 4'); // give it some size so it can be shot
+
+ setorigin (mine, w_shotorg - v_forward * 4); // move it back so it hits the wall at the right point
+ W_SetupProjectileVelocity(mine, cvar("g_balance_minelayer_speed"), 0);
+ mine.angles = vectoangles (mine.velocity);
+
+ mine.touch = W_Mine_Touch;
+ mine.think = W_Mine_Think;
+ mine.nextthink = time;
+ mine.cnt = time + cvar("g_balance_minelayer_lifetime");
+ mine.flags = FL_PROJECTILE;
+
+ CSQCProjectile(mine, FALSE, PROJECTILE_MINE, TRUE);
+
+ // muzzle flash for 1st person view
+ flash = spawn ();
+ setmodel (flash, "models/flash.md3"); // precision set below
+ SUB_SetFade (flash, time, 0.1);
+ flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
+ W_AttachToShotorg(flash, '5 0 0');
+
+ // common properties
+}
+
+void spawnfunc_weapon_minelayer (void); // defined in t_items.qc
+
+float w_minelayer(float req)
+{
+ entity mine;
+ float minfound;
+ if (req == WR_AIM)
+ {
+ // aim and decide to fire if appropriate
+ self.BUTTON_ATCK = bot_aim(cvar("g_balance_minelayer_speed"), 0, cvar("g_balance_minelayer_lifetime"), FALSE);
+ if(skill >= 2) // skill 0 and 1 bots won't detonate mines!
+ {
+ // decide whether to detonate mines
+ entity targetlist, targ;
+ float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
+ float selfdamage, teamdamage, enemydamage;
+ edgedamage = cvar("g_balance_minelayer_edgedamage");
+ coredamage = cvar("g_balance_minelayer_damage");
+ edgeradius = cvar("g_balance_minelayer_radius");
+ recipricoledgeradius = 1 / edgeradius;
+ selfdamage = 0;
+ teamdamage = 0;
+ enemydamage = 0;
+ targetlist = findchainfloat(bot_attack, TRUE);
+ mine = find(world, classname, "mine");
+ while (mine)
+ {
+ if (mine.owner != self)
+ {
+ mine = find(mine, classname, "mine");
+ continue;
+ }
+ targ = targetlist;
+ while (targ)
+ {
+ d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - mine.origin);
+ d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
+ // count potential damage according to type of target
+ if (targ == self)
+ selfdamage = selfdamage + d;
+ else if (targ.team == self.team && teams_matter)
+ teamdamage = teamdamage + d;
+ else if (bot_shouldattack(targ))
+ enemydamage = enemydamage + d;
+ targ = targ.chain;
+ }
+ mine = find(mine, classname, "mine");
+ }
+ float desirabledamage;
+ desirabledamage = enemydamage;
+ if (teamplay != 1 && time > self.invincible_finished && time > self.spawnshieldtime)
+ desirabledamage = desirabledamage - selfdamage * cvar("g_balance_selfdamagepercent");
+ if (self.team && teamplay != 1)
+ desirabledamage = desirabledamage - teamdamage;
+
+ mine = find(world, classname, "mine");
+ while (mine)
+ {
+ if (mine.owner != self)
+ {
+ mine = find(mine, classname, "mine");
+ continue;
+ }
+ makevectors(mine.v_angle);
+ targ = targetlist;
+ if (skill > 9) // normal players only do this for the target they are tracking
+ {
+ targ = targetlist;
+ while (targ)
+ {
+ if (
+ (v_forward * normalize(mine.origin - targ.origin)< 0.1)
+ && desirabledamage > 0.1*coredamage
+ )self.BUTTON_ATCK2 = TRUE;
+ targ = targ.chain;
+ }
+ }else{
+ float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000);
+ //As the distance gets larger, a correct detonation gets near imposible
+ //Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player
+ if(v_forward * normalize(mine.origin - self.enemy.origin)< 0.1)
+ if(self.enemy.classname == "player")
+ if(desirabledamage >= 0.1*coredamage)
+ if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
+ self.BUTTON_ATCK2 = TRUE;
+ // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
+ }
+
+ mine = find(mine, classname, "mine");
+ }
+ // if we would be doing at X percent of the core damage, detonate it
+ // but don't fire a new shot at the same time!
+ if (desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events
+ self.BUTTON_ATCK2 = TRUE;
+ if ((skill > 6.5) && (selfdamage > self.health))
+ self.BUTTON_ATCK2 = FALSE;
+ //if(self.BUTTON_ATCK2 == TRUE)
+ // dprint(ftos(desirabledamage),"\n");
+ if (self.BUTTON_ATCK2 == TRUE) self.BUTTON_ATCK = FALSE;
+ }
+ }
+ else if (req == WR_THINK)
+ {
+ if (self.BUTTON_ATCK)
+ {
+ if(weapon_prepareattack(0, cvar("g_balance_minelayer_refire")))
+ {
+ W_Mine_Attack();
+ weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_minelayer_animtime"), w_ready);
+ }
+ }
+
+ if (self.BUTTON_ATCK2)
+ {
+ minfound = 0;
+ for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
+ {
+ if(!mine.minelayer_detonate)
+ {
+ mine.minelayer_detonate = TRUE;
+ minfound = 1;
+ }
+ }
+ if(minfound)
+ sound (self, CHAN_WEAPON2, "weapons/mine_det.wav", VOL_BASE, ATTN_NORM);
+ }
+ }
+ else if (req == WR_PRECACHE)
+ {
+ precache_model ("models/flash.md3");
+ precache_model ("models/mine.md3");
+ precache_model ("models/weapons/g_minelayer.md3");
+ precache_model ("models/weapons/v_minelayer.md3");
+ precache_model ("models/weapons/h_minelayer.iqm");
+ precache_sound ("weapons/mine_det.wav");
+ precache_sound ("weapons/mine_fire.wav");
+ precache_sound ("weapons/mine_stick.wav");
+ precache_sound ("weapons/mine_trigger.wav");
+ }
+ else if (req == WR_SETUP)
+ {
+ weapon_setup(WEP_MINE_LAYER);
+ }
+ else if (req == WR_CHECKAMMO1)
+ {
+ // don't switch while placing a mine
+ if ((ATTACK_FINISHED(self) <= time || self.weapon != WEP_MINE_LAYER)
+ && self.ammo_rockets < cvar("g_balance_minelayer_ammo"))
+ return FALSE;
+ }
+ else if (req == WR_CHECKAMMO2)
+ return FALSE;
+ return TRUE;
+};
+#endif
+#ifdef CSQC
+float w_minelayer(float req)
+{
+ if(req == WR_IMPACTEFFECT)
+ {
+ vector org2;
+ org2 = w_org + w_backoff * 12;
+ pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
+ if(!w_issilent)
+ sound(self, CHAN_PROJECTILE, "weapons/mine_exp.wav", VOL_BASE, ATTN_NORM);
+ }
+ else if(req == WR_PRECACHE)
+ {
+ precache_sound("weapons/mine_exp.wav");
+ }
+ else if (req == WR_SUICIDEMESSAGE)
+ w_deathtypestring = "%s exploded";
+ else if (req == WR_KILLMESSAGE)
+ {
+ if(w_deathtype & HITTYPE_BOUNCE) // (remote detonation)
+ w_deathtypestring = "%s got too close to %s's mine";
+ else if(w_deathtype & HITTYPE_SPLASH)
+ w_deathtypestring = "%s almost dodged %s's mine";
+ else
+ w_deathtypestring = "%s stepped on %s's mine";
+ }
+ return TRUE;
+}
+#endif
+#endif
REGISTER_WEAPON(NEX, w_nex, IT_CELLS, 7, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "nex", "nex", "Nex");
#else
#ifdef SVQC
-void SendCSQCNexBeamParticle() {
+void SendCSQCNexBeamParticle(float charge) {
vector v;
v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte(MSG_BROADCAST, TE_CSQC_NEXGUNBEAMPARTICLE);
-
WriteCoord(MSG_BROADCAST, w_shotorg_x);
WriteCoord(MSG_BROADCAST, w_shotorg_y);
WriteCoord(MSG_BROADCAST, w_shotorg_z);
WriteCoord(MSG_BROADCAST, v_x);
WriteCoord(MSG_BROADCAST, v_y);
WriteCoord(MSG_BROADCAST, v_z);
+ WriteByte(MSG_BROADCAST, bound(0, 255 * charge, 255));
}
void W_Nex_Attack (float issecondary)
{
- float mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, myammo;
+ float mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, myammo, charge;
if(issecondary)
{
mydmg = cvar("g_balance_nex_secondary_damage");
float flying;
flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
+ if(cvar("g_balance_nex_charge"))
+ {
+ charge = self.nex_charge;
+ self.nex_charge *= cvar("g_balance_nex_charge_shot_multiplier"); // do this AFTER setting mydmg/myforce
+ }
+ else
+ charge = 1;
+ mydmg *= charge;
+ myforce *= charge;
+
W_SetupShot (self, TRUE, 5, "weapons/nexfire.wav", mydmg);
yoda = 0;
AnnounceTo(self, "yoda");
//beam and muzzle flash done on client
- SendCSQCNexBeamParticle();
+ SendCSQCNexBeamParticle(charge);
// flash and burn the wall
if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
float w_nex(float req)
{
+ float dt;
if (req == WR_AIM)
{
self.BUTTON_ATCK = bot_aim(1000000, 0, 1, FALSE);
}
else if (req == WR_THINK)
{
+ if(cvar("g_balance_nex_charge") && self.nex_charge < cvar("g_balance_nex_charge_limit"))
+ self.nex_charge = min(1, self.nex_charge + cvar("g_balance_nex_charge_rate") * frametime / W_TICSPERFRAME);
if (self.BUTTON_ATCK)
{
if (weapon_prepareattack(0, cvar("g_balance_nex_primary_refire")))
}
if (self.BUTTON_ATCK2)
{
- if(cvar("g_balance_nex_secondary"))
+ if(cvar("g_balance_nex_secondary_charge"))
+ {
+ dt = frametime / W_TICSPERFRAME;
+ if(self.nex_charge < 1)
+ {
+ dt = min(dt, (1 - self.nex_charge) / cvar("g_balance_nex_secondary_charge_rate"));
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(cvar("g_balance_nex_secondary_ammo"))
+ {
+ dt = min(dt, (self.ammo_cells - cvar("g_balance_nex_primary_ammo")) / cvar("g_balance_nex_secondary_ammo"));
+ dt = max(0, dt);
+ if(dt > 0)
+ {
+ self.ammo_cells = max(cvar("g_balance_nex_secondary_ammo"), self.ammo_cells - cvar("g_balance_nex_secondary_ammo") * dt);
+ }
+ }
+ }
+ self.nex_charge += dt * cvar("g_balance_nex_secondary_charge_rate");
+ }
+ }
+ else if(cvar("g_balance_nex_secondary"))
{
if (weapon_prepareattack(0, cvar("g_balance_nex_secondary_refire")))
{
else if (req == WR_CHECKAMMO1)
return self.ammo_cells >= cvar("g_balance_nex_primary_ammo");
else if (req == WR_CHECKAMMO2)
+ {
+ if(cvar("g_balance_nex_secondary_charge"))
+ return self.ammo_cells >= cvar("g_balance_nex_primary_ammo");
return self.ammo_cells >= cvar("g_balance_nex_secondary_ammo");
+ }
return TRUE;
};
#endif
void W_Rocket_Touch (void)
{
+ if(WarpZone_Projectile_Touch())
+ {
+ if(wasfreed(self))
+ W_Rocket_Unregister();
+ return;
+ }
W_Rocket_Unregister();
-
- PROJECTILE_TOUCH;
W_Rocket_Explode ();
}
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
void spawnfunc_weapon_shotgun(); // defined in t_items.qc
+.float shotgun_primarytime;
+
float w_shotgun(float req)
{
if (req == WR_AIM)
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")))
+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)
{
}
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();
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();
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);
//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;
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;
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;
{
// 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;
void WarpZone_MakeAllSolid()
{
entity e;
+ if(!warpzone_warpzones_exist)
+ return;
for(e = world; (e = find(e, classname, "trigger_warpzone")); )
e.solid = SOLID_BSP;
}
void WarpZone_MakeAllOther()
{
entity e;
+ if(!warpzone_warpzones_exist)
+ return;
for(e = world; (e = find(e, classname, "trigger_warpzone")); )
e.solid = SOLID_TRIGGER;
}
goto fail;
}
WarpZone_Trace_AddTransform(wz);
- org = WarpZone_TransformOrigin(wz, trace_endpos);
+ org = WarpZone_TransformOrigin(wz, org);
end = WarpZone_TransformOrigin(wz, end);
}
WarpZone_MakeAllSolid();
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)
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);
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")
entity WarpZone_TrailParticles_trace_callback_own;
float WarpZone_TrailParticles_trace_callback_eff;
+float WarpZone_TrailParticles_trace_callback_f;
+float WarpZone_TrailParticles_trace_callback_flags;
void WarpZone_TrailParticles_trace_callback(vector from, vector endpos, vector to)
{
trailparticles(WarpZone_TrailParticles_trace_callback_own, WarpZone_TrailParticles_trace_callback_eff, from, endpos);
WarpZone_TraceBox_ThroughZone(org, '0 0 0', '0 0 0', end, MOVE_NOMONSTERS, world, world, WarpZone_TrailParticles_trace_callback);
}
+#ifdef CSQC
+void WarpZone_TrailParticles_WithMultiplier_trace_callback(vector from, vector endpos, vector to)
+{
+ boxparticles(WarpZone_TrailParticles_trace_callback_eff, WarpZone_TrailParticles_trace_callback_own, from, endpos, WarpZone_TrailParticles_trace_callback_own.velocity, WarpZone_TrailParticles_trace_callback_own.velocity, WarpZone_TrailParticles_trace_callback_f, WarpZone_TrailParticles_trace_callback_flags);
+}
+
+void WarpZone_TrailParticles_WithMultiplier(entity own, float eff, vector org, vector end, float f, float boxflags)
+{
+ WarpZone_TrailParticles_trace_callback_own = own;
+ WarpZone_TrailParticles_trace_callback_eff = eff;
+ WarpZone_TrailParticles_trace_callback_f = f;
+ WarpZone_TrailParticles_trace_callback_flags = boxflags;
+ WarpZone_TraceBox_ThroughZone(org, '0 0 0', '0 0 0', end, MOVE_NOMONSTERS, world, world, WarpZone_TrailParticles_WithMultiplier_trace_callback);
+}
+#endif
+
float WarpZone_PlaneDist(entity wz, vector v)
{
return (v - wz.warpzone_origin) * wz.warpzone_forward;
.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);
void WarpZone_TraceToss(entity e, entity forent);
void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZone_trace_callback_t cb);
void WarpZone_TrailParticles(entity own, float eff, vector org, vector end);
+#ifdef CSQC
+void WarpZone_TrailParticles_WithMultiplier(entity own, float eff, vector org, vector end, float f, float boxflags);
+#endif
.vector WarpZone_findradius_dist;
.vector WarpZone_findradius_nearest;
o1 = WarpZone_TransformOrigin(self, o0);
v1 = WarpZone_TransformVelocity(self, v0);
- if(player.classname == "player")
+ if(clienttype(player) != CLIENTTYPE_NOTACLIENT)
a1 = WarpZone_TransformVAngles(self, player.v_angle);
else
a1 = WarpZone_TransformAngles(self, a0);
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
{
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);
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);
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;
}
entity wz;
wz = WarpZone_Find(self.origin + self.mins, self.origin + self.maxs);
if(!wz)
- return FALSE;
+ return 0;
+ if(self.warpzone_teleport_time == time)
+ {
+ // just ignore if we got teleported this frame already and now hit a wall and are in a warpzone again (this will cause a detonation)
+ // print("2 warps 1 frame\n");
+ return -1;
+ }
o0 = self.origin;
v0 = self.velocity;
a0 = self.angles;
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));
pd = WarpZone_TargetPlaneDist(wz, self.origin);
if(pd < mpd)
{
- dpd = normalize(self.velocity) * self.warpzone_targetforward;
+ dpd = normalize(self.velocity) * wz.warpzone_targetforward;
setorigin(self, self.origin + normalize(self.velocity) * ((mpd - pd) / dpd));
if(!WarpZoneLib_MoveOutOfSolid(self))
{
setorigin(self, o0);
self.angles = a0;
self.velocity = v0;
- return FALSE;
+ return 0;
}
}
WarpZone_RefSys_Add(self, wz);
WarpZone_StoreProjectileData(self);
self.warpzone_teleport_time = time;
- return TRUE;
+ return +1;
}
float WarpZone_Projectile_Touch()
{
+ float f;
if(other.classname == "trigger_warpzone")
return TRUE;
if(WarpZone_Projectile_Touch_ImpactFilter_Callback())
return TRUE;
- if(WarpZone_CheckProjectileImpact())
- return TRUE;
- if(self.warpzone_teleport_time == time) // already got teleported this frame? no collision then please
+ if((f = WarpZone_CheckProjectileImpact()) != 0)
+ return (f > 0);
+ if(self.warpzone_teleport_time == time)
{
+ // sequence: hit warpzone, get teleported, hit wall
+ // print("2 hits 1 frame\n");
setorigin(self, self.warpzone_oldorigin);
self.velocity = self.warpzone_oldvelocity;
self.angles = self.warpzone_oldangles;
return TRUE;
}
-
return FALSE;
}
error("Warp zone with nonexisting killtarget");
return;
}
+ self.killtarget = string_null;
}
}
void WarpZoneCamera_InitStep_FindTarget()
{
+ entity e;
+ float i;
if(self.target == "")
{
error("Camera with no target");
return;
}
- self.enemy = find(world, targetname, self.target);
+ self.enemy = world;
+ for(e = world, i = 0; (e = find(e, targetname, self.target)); )
+ if(random() * ++i < 1)
+ self.enemy = e;
if(self.enemy == world)
{
error("Camera with nonexisting target");
}
++warpzone_cameras_exist;
WarpZone_Camera_SetUp(self, self.enemy.origin, self.enemy.angles);
+ self.SendFlags = 0xFFFFFF;
}
void WarpZone_InitStep_UpdateTransform()
WarpZone_InitStep_ClearTarget();
for(self = warpzone_first; self; self = self.warpzone_next)
WarpZone_InitStep_FindTarget();
+ for(self = warpzone_camera_first; self; self = self.warpzone_next)
+ WarpZoneCamera_InitStep_FindTarget();
for(self = warpzone_first; self; self = self.warpzone_next)
WarpZone_InitStep_FinalizeTransform();
self = e;
WarpZone_InitStep_FindOriginTarget();
for(self = warpzone_position_first; self; self = self.warpzone_next)
WarpZonePosition_InitStep_FindTarget();
- for(self = warpzone_camera_first; self; self = self.warpzone_next)
- WarpZoneCamera_InitStep_FindTarget();
for(self = warpzone_first; self; self = self.warpzone_next)
WarpZone_InitStep_UpdateTransform();
self = e;
WarpZone_StoreProjectileData(e);
}
+.float warpzone_reconnecting;
+float visible_to_some_client(entity ent)
+{
+ entity e;
+ for(e = nextent(world); clienttype(e) != CLIENTTYPE_NOTACLIENT; e = nextent(e))
+ if(e.classname == "player" && clienttype(e) == CLIENTTYPE_REAL)
+ if(checkpvs(e.origin + e.view_ofs, ent))
+ return 1;
+ return 0;
+}
void trigger_warpzone_reconnect_use()
{
entity e;
// NOTE: this matches for target, not targetname, but of course
// targetname must be set too on the other entities
for(self = warpzone_first; self; self = self.warpzone_next)
- if(e.target == "" || self.target == e.target)
+ self.warpzone_reconnecting = ((e.target == "" || self.target == e.target) && !((e.spawnflags & 1) && (visible_to_some_client(self) || visible_to_some_client(self.enemy))));
+ for(self = warpzone_camera_first; self; self = self.warpzone_next)
+ self.warpzone_reconnecting = ((e.target == "" || self.target == e.target) && !((e.spawnflags & 1) && visible_to_some_client(self)));
+ for(self = warpzone_first; self; self = self.warpzone_next)
+ if(self.warpzone_reconnecting)
WarpZone_InitStep_ClearTarget();
for(self = warpzone_first; self; self = self.warpzone_next)
- if(e.target == "" || self.target == e.target)
+ if(self.warpzone_reconnecting)
WarpZone_InitStep_FindTarget();
+ for(self = warpzone_camera_first; self; self = self.warpzone_next)
+ if(self.warpzone_reconnecting)
+ WarpZoneCamera_InitStep_FindTarget();
for(self = warpzone_first; self; self = self.warpzone_next)
- if(e.target == "" || self.target == e.target || self.enemy.target == e.target)
+ if(self.warpzone_reconnecting || self.enemy.warpzone_reconnecting)
WarpZone_InitStep_FinalizeTransform();
self = e;
}
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
+crypto_keygen 0 http://rm.endoftheinternet.org/~xonotic/keygen/?ca=0&key=
--- /dev/null
+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
+ }
+}
+
--- /dev/null
+nutsandboltssteel
+{
+ {
+ map textures/nutsandbolts3
+ tcgen environment
+ }
+ {
+ map $lightmap
+ }
+}
--- /dev/null
+rocketThrust
+{
+ surfaceparm trans
+ cull disable
+ {
+ clampmap textures/thrustc1.tga
+ blendfunc add
+ tcMod rotate 720
+ }
+}
-//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
--- /dev/null
+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
set g_turrets_unit_flac_std_shot_speed 9000
set g_turrets_unit_flac_std_shot_spread 0.02
set g_turrets_unit_flac_std_shot_force 25
+set g_turrets_unit_flac_std_shot_volly 0
+set g_turrets_unit_flac_std_shot_volly_refire 0
set g_turrets_unit_flac_std_target_range 4000
set g_turrets_unit_flac_std_target_range_min 500
set g_turrets_unit_flac_std_ammo_recharge 100
set g_turrets_unit_flac_std_aim_firetolerance_dist 150
-set g_turrets_unit_flac_std_aim_speed 360
+set g_turrets_unit_flac_std_aim_speed 200
set g_turrets_unit_flac_std_aim_maxrot 360
set g_turrets_unit_flac_std_aim_maxpitch 35
set g_turrets_unit_flac_std_track_type 3
-set g_turrets_unit_flac_std_track_accel_pitch 0.25
-set g_turrets_unit_flac_std_track_accel_rot 0.8
-set g_turrets_unit_flac_std_track_blendrate 0.6
+set g_turrets_unit_flac_std_track_accel_pitch 0.5
+set g_turrets_unit_flac_std_track_accel_rot 0.7
+set g_turrets_unit_flac_std_track_blendrate 0.2
set g_turrets_unit_hellion_std_respawntime 90
set g_turrets_unit_hellion_std_shot_dmg 50
-set g_turrets_unit_hellion_std_shot_refire 0.25
+set g_turrets_unit_hellion_std_shot_refire 0.2
set g_turrets_unit_hellion_std_shot_radius 80
set g_turrets_unit_hellion_std_shot_speed 650
set g_turrets_unit_hellion_std_track_type 3
set g_turrets_unit_hellion_std_track_accel_pitch 0.25
-set g_turrets_unit_hellion_std_track_accel_rot 0.5
-set g_turrets_unit_hellion_std_track_blendrate 0.75
+set g_turrets_unit_hellion_std_track_accel_rot 0.6
+set g_turrets_unit_hellion_std_track_blendrate 0.25
set g_turrets_unit_hk_std_track_type 3
set g_turrets_unit_hk_std_track_accel_pitch 0.25
-set g_turrets_unit_hk_std_track_accel_rot 0.5
-set g_turrets_unit_hk_std_track_blendrate 0.25
+set g_turrets_unit_hk_std_track_accel_rot 0.6
+set g_turrets_unit_hk_std_track_blendrate 0.2
set g_turrets_unit_machinegun_std_ammo_recharge 75
set g_turrets_unit_machinegun_std_aim_firetolerance_dist 25
-set g_turrets_unit_machinegun_std_aim_speed 720
+set g_turrets_unit_machinegun_std_aim_speed 120
set g_turrets_unit_machinegun_std_aim_maxrot 360
set g_turrets_unit_machinegun_std_aim_maxpitch 25
set g_turrets_unit_machinegun_std_track_type 3
-set g_turrets_unit_machinegun_std_track_accel_pitch 0.5
-set g_turrets_unit_machinegun_std_track_accel_rot 0.75
-set g_turrets_unit_machinegun_std_track_blendrate 0.5
+set g_turrets_unit_machinegun_std_track_accel_pitch 0.4
+set g_turrets_unit_machinegun_std_track_accel_rot 0.9
+set g_turrets_unit_machinegun_std_track_blendrate 0.2
set g_turrets_unit_mlrs_std_shot_force 25
set g_turrets_unit_mlrs_std_shot_volly 6
-set g_turrets_unit_mlrs_std_shot_volly_refire 1
+
+// !must be correctly matched with ammo_recharge as this unit use
+// volly_always. (means ammo_recharge * ammo_max must be eaqual to volly_refire)
+set g_turrets_unit_mlrs_std_shot_volly_refire 4
set g_turrets_unit_mlrs_std_target_range 3000
set g_turrets_unit_mlrs_std_target_range_min 500
set g_turrets_unit_mlrs_std_target_select_playerbias 1
set g_turrets_unit_mlrs_std_target_select_missilebias 0
-set g_turrets_unit_mlrs_std_ammo_max 420
-set g_turrets_unit_mlrs_std_ammo 420
-set g_turrets_unit_mlrs_std_ammo_recharge 70
+// !must be shot_dmg * 6 as this unit uses ammo to control the animation
+set g_turrets_unit_mlrs_std_ammo_max 300
+set g_turrets_unit_mlrs_std_ammo 300
+set g_turrets_unit_mlrs_std_ammo_recharge 75
set g_turrets_unit_mlrs_std_aim_firetolerance_dist 120
-set g_turrets_unit_mlrs_std_aim_speed 270
+set g_turrets_unit_mlrs_std_aim_speed 100
set g_turrets_unit_mlrs_std_aim_maxrot 360
set g_turrets_unit_mlrs_std_aim_maxpitch 20
set g_turrets_unit_mlrs_std_track_type 3
set g_turrets_unit_mlrs_std_track_accel_pitch 0.5
-set g_turrets_unit_mlrs_std_track_accel_rot 0.8
+set g_turrets_unit_mlrs_std_track_accel_rot 0.7
set g_turrets_unit_mlrs_std_track_blendrate 0.2
set g_turrets_unit_phaser_std_aim_firetolerance_dist 100
-set g_turrets_unit_phaser_std_aim_speed 540
+set g_turrets_unit_phaser_std_aim_speed 300
set g_turrets_unit_phaser_std_aim_maxrot 360
set g_turrets_unit_phaser_std_aim_maxpitch 30
set g_turrets_unit_phaser_std_track_type 3
set g_turrets_unit_phaser_std_track_accel_pitch 0.5
set g_turrets_unit_phaser_std_track_accel_rot 0.65
-set g_turrets_unit_phaser_std_track_blendrate 0.5
+set g_turrets_unit_phaser_std_track_blendrate 0.2
// If predicted emeypos is this or closer to predicted impact, fire is ok
set g_turrets_unit_plasma_std_aim_firetolerance_dist 120
// Aim how fast. for track_type 1 this is dgr/sec, for 2 & 3 its the maximum angle speed added each second
-set g_turrets_unit_plasma_std_aim_speed 270
+set g_turrets_unit_plasma_std_aim_speed 200
// Max rottation of head
set g_turrets_unit_plasma_std_aim_maxrot 360
// Max pitch of head
set g_turrets_unit_plasma_std_track_type 3
// Following controls how _track_type = 3 works.
set g_turrets_unit_plasma_std_track_accel_pitch 0.5
-set g_turrets_unit_plasma_std_track_accel_rot 0.8
+set g_turrets_unit_plasma_std_track_accel_rot 0.7
set g_turrets_unit_plasma_std_track_blendrate 0.2
set g_turrets_unit_plasma_dual_aim_firetolerance_dist 200
-set g_turrets_unit_plasma_dual_aim_speed 270
+set g_turrets_unit_plasma_dual_aim_speed 100
set g_turrets_unit_plasma_dual_aim_maxrot 360
set g_turrets_unit_plasma_dual_aim_maxpitch 30
set g_turrets_unit_plasma_dual_track_type 3
set g_turrets_unit_plasma_dual_track_accel_pitch 0.5
-set g_turrets_unit_plasma_dual_track_accel_rot 0.75
-set g_turrets_unit_plasma_dual_track_blendrate 0.75
+set g_turrets_unit_plasma_dual_track_accel_rot 0.7
+set g_turrets_unit_plasma_dual_track_blendrate 0.2
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
*Music / Sound FX
mand1nga
Merlijn Hofstra
+remaxim
*Engine Code Additions & QA
Rudolf "divVerent" Polzer
by Forest "LordHavoc" Hale
**Active Contributors
+Antonio "terencehill" Piu
Ben "MooKow" Banker
+Calinou
Kristian "morfar" Johansson
+kojn
Maik "SavageX" Merten
MrBougo
Stephan "esteel" Stahl