* -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
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
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)
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_nex_secondary 0
set g_balance_nex_secondary_charge 0
-set g_balance_nex_secondary_charge_rate 200
-set g_balance_nex_secondary_charge_ammo 10
+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_halflife 0
set g_balance_nex_secondary_damagefalloff_forcehalflife 0
-set g_balance_nex_velocitydependent_halflife 0
-set g_balance_nex_velocitydependent_minspeed 400
-set g_balance_nex_velocitydependent_maxspeed 1000
-set g_balance_nex_velocitydependent_falloff_rate 0.001
+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_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_balance_nex_secondary 0
set g_balance_nex_secondary_charge 0
-set g_balance_nex_secondary_charge_rate 200
-set g_balance_nex_secondary_charge_ammo 10
+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_damagefalloff_halflife 9999999
set g_balance_nex_secondary_damagefalloff_forcehalflife 9999999
-set g_balance_nex_velocitydependent_halflife 0
-set g_balance_nex_velocitydependent_minspeed 400
-set g_balance_nex_velocitydependent_maxspeed 1000
-set g_balance_nex_velocitydependent_falloff_rate 0.001
+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_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_nex_secondary 0
set g_balance_nex_secondary_charge 0
-set g_balance_nex_secondary_charge_rate 200
-set g_balance_nex_secondary_charge_ammo 10
+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_halflife 1500
set g_balance_nex_secondary_damagefalloff_forcehalflife 1500
-set g_balance_nex_velocitydependent_halflife 0
-set g_balance_nex_velocitydependent_minspeed 400
-set g_balance_nex_velocitydependent_maxspeed 1000
-set g_balance_nex_velocitydependent_falloff_rate 0.001
+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_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_nex_secondary 0
set g_balance_nex_secondary_charge 0
-set g_balance_nex_secondary_charge_rate 200
-set g_balance_nex_secondary_charge_ammo 10
+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_halflife 1500
set g_balance_nex_secondary_damagefalloff_forcehalflife 1500
-set g_balance_nex_velocitydependent_halflife 0
-set g_balance_nex_velocitydependent_minspeed 400
-set g_balance_nex_velocitydependent_maxspeed 1000
-set g_balance_nex_velocitydependent_falloff_rate 0.001
+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_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
// }}}
// {{{ mortar // TODO
set g_balance_grenadelauncher_primary_type 0
-set g_balance_grenadelauncher_primary_damage 60
+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_remote_minbouncecnt 0
set g_balance_grenadelauncher_secondary_type 1
-set g_balance_grenadelauncher_secondary_damage 80
+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_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 500
-set g_balance_nex_primary_damagefalloff_maxdist 4500
-set g_balance_nex_primary_damagefalloff_halflife 2000
+set g_balance_nex_primary_damagefalloff_mindist 1000
+set g_balance_nex_primary_damagefalloff_maxdist 3000
+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_charge 1
-set g_balance_nex_secondary_charge_rate 200
-set g_balance_nex_secondary_charge_ammo 10
-set g_balance_nex_secondary_damage 125
-set g_balance_nex_secondary_force -700
-set g_balance_nex_secondary_refire 1
-set g_balance_nex_secondary_animtime 0.75
-set g_balance_nex_secondary_ammo 5
-set g_balance_nex_secondary_damagefalloff_mindist 500
-set g_balance_nex_secondary_damagefalloff_maxdist 4500
-set g_balance_nex_secondary_damagefalloff_halflife 4000
-set g_balance_nex_secondary_damagefalloff_forcehalflife 4000
+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_velocitydependent_halflife -500
-set g_balance_nex_velocitydependent_minspeed 400
-set g_balance_nex_velocitydependent_maxspeed 1000
-set g_balance_nex_velocitydependent_falloff_rate 40
+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
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 30000
+set g_balance_campingrifle_secondary_speed 15000
set g_balance_campingrifle_secondary_lifetime 5
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
// }}}
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"
set g_ban_default_bantime 5400 "90 minutes"
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)
r_textbrightness 0.2
r_textcontrast 0.8
r_textshadow 0
-r_font_postprocess_blur 2
+r_font_postprocess_blur 1
r_font_postprocess_outline 1
// good settings for these fonts
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
// 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
float campingrifle_scope;
float nex_scope;
-float nex_velocitydependent;
-float nex_minvelocity;
-float nex_maxvelocity;
-float nex_speed_falloff_rate;
-float nex_speed;
-float nex_charge;
-float nex_charge_rate;
-
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;
}
}
Net_WeaponComplain();
bHandled = true;
break;
- case TE_CSQC_NEX_VELOCITY:
- nex_velocitydependent = ReadByte();
- nex_minvelocity = ReadShort();
- nex_maxvelocity = ReadShort();
- nex_speed_falloff_rate = ReadByte();
- nex_charge = ReadByte();
- nex_charge_rate = ReadByte();
- bHandled = true;
- break;
case TE_CSQC_CR_MAXBULLETS:
cr_maxbullets = ReadByte();
bHandled = true;
float f, a;
wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
- float xyspeed;
- xyspeed = vlen('1 0 0' * pmove_vel_x + '0 1 0' * pmove_vel_y);
- if(xyspeed > nex_speed)
- nex_speed = min(xyspeed, nex_maxvelocity);
- else
- nex_speed = max(nex_minvelocity, nex_speed - nex_speed_falloff_rate * frametime);
-
- if (activeweapon == WEP_NEX && button_attack2 && nex_charge && getstati(GetAmmoStat(3)))
- nex_speed = min(nex_maxvelocity, nex_speed + nex_charge_rate * frametime);
+ float nex_charge;
+ nex_charge = getstatf(STAT_NEX_CHARGE);
// ring around crosshair representing bullets left in camping rifle clip
if (activeweapon == WEP_CAMPINGRIFLE && cr_maxbullets)
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_velocitydependent && nex_speed > nex_minvelocity) // ring around crosshair representing velocity-dependent damage for the nex
+ else if (activeweapon == WEP_NEX && nex_charge) // ring around crosshair representing velocity-dependent damage for the nex
{
- f = bound(0, (nex_speed - nex_minvelocity) / (nex_maxvelocity - nex_minvelocity), 1);
-
a = cvar("crosshair_nexvelocity_alpha");
- DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, "gfx/crosshair_ring.tga", f, wcross_color, wcross_alpha * a, DRAWFLAG_ADDITIVE);
+ 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) \
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;
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 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
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)
{
// 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)
{
remove(self);
return;
}
+ self.drawmask = MASK_NORMAL;
if(self.scale <= 0)
+ {
+ self.drawmask = 0;
return;
- R_AddEntity(self);
+ }
}
void Ent_ModelEffect(float isNew)
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);
}
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)
}
}
music_trigger = world;
+
+ if(best)
+ bgmtime = getsoundtime(best, CHAN_VOICE);
+ else
+ bgmtime = gettime(GETTIME_CDTRACK);
}
void Net_TargetMusic()
.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 = ReadShort() / 256.0;
if(f & 0x20)
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)
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));
+ 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);
}
waypointsprite_initialized = 1;
}
const float TE_CSQC_WEAPONCOMPLAIN = 113;
const float TE_CSQC_CAMPINGRIFLE_SCOPE = 115;
const float TE_CSQC_NEX_SCOPE = 116;
-const float TE_CSQC_NEX_VELOCITY = 117;
-const float TE_CSQC_CR_MAXBULLETS = 118;
+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;
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"), " ");
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
HUD_Panel_GetName_Part2(id)
vector vec2(vector v);
+
+#ifndef MENUQC
+vector NearestPointOnBox(entity box, vector org);
+#endif
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(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'));
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);
WriteByte(0, TE_CSQC_TEAMNAGGER);
}
-void send_CSQC_nexvelocity(entity e) {
- msg_entity = e;
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_NEX_VELOCITY);
- WriteByte(MSG_ONE, bound(0, fabs(cvar("g_balance_nex_velocitydependent_halflife")), 1));
- WriteShort(MSG_ONE, cvar("g_balance_nex_velocitydependent_minspeed"));
- WriteShort(MSG_ONE, cvar("g_balance_nex_velocitydependent_maxspeed"));
- WriteByte(MSG_ONE, cvar("g_balance_nex_velocitydependent_falloff_rate"));
- WriteByte(MSG_ONE, cvar("g_balance_nex_secondary_charge"));
- WriteByte(MSG_ONE, cvar("g_balance_nex_secondary_charge_rate"));
-}
-
void send_CSQC_cr_maxbullets(entity e) {
msg_entity = e;
WriteByte(MSG_ONE, SVC_TEMPENTITY);
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)
{
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)
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_nexvelocity(self);
send_CSQC_cr_maxbullets(self);
CheatInitClient();
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 f;
float xyspeed;
- f = cvar("g_balance_nex_velocitydependent_falloff_rate");
xyspeed = vlen('1 0 0' * self.velocity_x + '0 1 0' * self.velocity_y);
- if(xyspeed > self.nexspeed)
- self.nexspeed = min(xyspeed, cvar("g_balance_nex_velocitydependent_maxspeed"));
- else
- self.nexspeed = max(cvar("g_balance_nex_velocitydependent_minspeed"), self.nexspeed - f * frametime);
+ 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;
// 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;
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
{
// TODO implemented fall and falling
#define ALLPLAYERSOUNDS \
_VOICEMSG(death) \
+ _VOICEMSG(fall) \
_VOICEMSG(drown) \
_VOICEMSG(gasp) \
_VOICEMSG(jump) \
.float active;
.float (float act_state) setactive;
.entity realowner;
+
+.float nex_charge;
//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:
}
}
-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);
WriteShort(MSG_ENTITY, floor(self.scale * 256));
if(sf & 0x20)
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 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);
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
// div0: ticrate independent, 1 = identity (not 20)
other.velocity = other.velocity * pow(self.strength, pushdeltatime);
+ UpdateCSQCProjectile(other);
}
// Spherical (gravity/repulsor) mode
str = self.strength;
other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime;
+ UpdateCSQCProjectile(other);
}
/*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ?
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);
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;
-#ifdef UID
- ban_uid = client.uid;
-#endif
+ if(client.crypto_keyfp)
+ ban_idfp = client.crypto_idfp;
+ else
+ ban_idfp = string_null;
s = client.netaddress;
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
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
+#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);
}
}
{
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"));
}
}
}
/// 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)
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"));
// in order for mines to face properly when sticking to the ground, they must be a server side entity rather than a csqc projectile
- local entity newmine;
+ entity newmine;
newmine = spawn();
newmine.classname = self.classname;
void W_Mine_Attack (void)
{
- local entity mine;
- local entity flash;
+ entity mine;
+ entity flash;
// scan how many mines we placed, and return if we reached our limit
if(cvar("g_balance_minelayer_limit"))
if(skill >= 2) // skill 0 and 1 bots won't detonate mines!
{
// decide whether to detonate mines
- local entity mine, targetlist, targ;
- local float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
- local float selfdamage, teamdamage, enemydamage;
+ 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");
}
mine = find(mine, classname, "mine");
}
- local float desirabledamage;
+ float desirabledamage;
desirabledamage = enemydamage;
if (teamplay != 1 && time > self.invincible_finished && time > self.spawnshieldtime)
desirabledamage = desirabledamage - selfdamage * cvar("g_balance_selfdamagepercent");
targ = targ.chain;
}
}else{
- local float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000);
+ 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)
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, f;
+ 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
- f = ExponentialFalloff(cvar("g_balance_nex_velocitydependent_minspeed"), cvar("g_balance_nex_velocitydependent_maxspeed"), cvar("g_balance_nex_velocitydependent_halflife"), self.nexspeed);
-
- // TODO: make it more obvious (through effects, indicator on weapon) that damage increases when speed increases
- mydmg *= f;
- myforce *= f;
- //print("^1Damage: ^7", ftos(mydmg), "\n");
+ 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);
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(cvar("g_balance_nex_secondary_charge"))
{
- if(self.ammo_cells)
+ dt = frametime / W_TICSPERFRAME;
+ if(self.nex_charge < 1)
{
- self.nexspeed = min(cvar("g_balance_nex_velocitydependent_maxspeed"), self.nexspeed + cvar("g_balance_nex_secondary_charge_rate") * frametime / W_TICSPERFRAME);
- self.ammo_cells = max(0, self.ammo_cells - cvar("g_balance_nex_secondary_charge_ammo") * frametime / W_TICSPERFRAME);
+ 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"))
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 ();
}
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;
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;
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;
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;
}
//startdemos demos/demo1 demos/demo2 demos/demo3
//startdemos
//play announcer/male/welcome.ogg
+crypto_keygen 0 http://rm.endoftheinternet.org/~xonotic/keygen/?ca=0&key=
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
*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