Add code, unknown original date

This commit is contained in:
2026-05-18 12:41:53 -04:00
commit 7fddc22283
2373 changed files with 3420614 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
K 25
svn:wc:ra_dav:version-url
V 65
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3
END

View File

@@ -0,0 +1,40 @@
10
dir
44
https://127.0.0.1/svn/aklabs/trunk/hypermod/code/debug-x86-Linux-2.3/Q3
https://127.0.0.1/svn/aklabs
2007-05-26T21:34:02.309037Z
9
andrew
eb184899-6090-47d4-a65b-558f62f6ea1c
q3_ui
dir
game
dir
CVS
dir
cgame
dir

View File

@@ -0,0 +1,29 @@
K 25
svn:wc:ra_dav:version-url
V 69
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/CVS
END
Repository
K 25
svn:wc:ra_dav:version-url
V 80
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/CVS/Repository
END
Root
K 25
svn:wc:ra_dav:version-url
V 74
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/CVS/Root
END
Entries
K 25
svn:wc:ra_dav:version-url
V 77
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/CVS/Entries
END
Entries.Log
K 25
svn:wc:ra_dav:version-url
V 81
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/CVS/Entries.Log
END

View File

@@ -0,0 +1,164 @@
10
dir
44
https://127.0.0.1/svn/aklabs/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/CVS
https://127.0.0.1/svn/aklabs
2007-05-26T21:34:02.309037Z
9
andrew
eb184899-6090-47d4-a65b-558f62f6ea1c
Repository
file
2010-02-05T03:38:10.401373Z
9c0c7acfed3d12170089400e1caa9258
2007-05-26T21:34:02.309037Z
9
andrew
50
Root
file
2010-02-05T03:38:10.401373Z
7af14a164593104c1e7a07a572dd352a
2007-05-26T21:34:02.309037Z
9
andrew
24
Entries
file
2010-02-05T03:38:10.401373Z
57b8d745384127342f95660d97e1c9c2
2007-05-26T21:34:02.309037Z
9
andrew
2
Entries.Log
file
2010-02-05T03:38:10.416998Z
dc88909a21704ff907c55d6ba5880649
2007-05-26T21:34:02.309037Z
9
andrew
41

View File

@@ -0,0 +1,3 @@
A D/cgame////
A D/game////
A D/q3_ui////

View File

@@ -0,0 +1 @@
D

View File

@@ -0,0 +1 @@
games/quake3/hypermod/code/debug-x86-Linux-2.3/Q3

View File

@@ -0,0 +1 @@
andrew@gabbo:/home/cvsd

View File

@@ -0,0 +1 @@
D

View File

@@ -0,0 +1,3 @@
A D/cgame////
A D/game////
A D/q3_ui////

View File

@@ -0,0 +1 @@
games/quake3/hypermod/code/debug-x86-Linux-2.3/Q3

View File

@@ -0,0 +1 @@
andrew@gabbo:/home/cvsd

View File

@@ -0,0 +1,5 @@
K 25
svn:wc:ra_dav:version-url
V 71
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame
END

View File

@@ -0,0 +1,40 @@
10
dir
44
https://127.0.0.1/svn/aklabs/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame
https://127.0.0.1/svn/aklabs
2007-05-26T21:34:02.309037Z
9
andrew
eb184899-6090-47d4-a65b-558f62f6ea1c
game
dir
CVS
dir
cgame
dir
ui
dir

View File

@@ -0,0 +1,29 @@
K 25
svn:wc:ra_dav:version-url
V 75
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/CVS
END
Repository
K 25
svn:wc:ra_dav:version-url
V 86
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/CVS/Repository
END
Root
K 25
svn:wc:ra_dav:version-url
V 80
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/CVS/Root
END
Entries
K 25
svn:wc:ra_dav:version-url
V 83
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/CVS/Entries
END
Entries.Log
K 25
svn:wc:ra_dav:version-url
V 87
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/CVS/Entries.Log
END

View File

@@ -0,0 +1,164 @@
10
dir
44
https://127.0.0.1/svn/aklabs/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/CVS
https://127.0.0.1/svn/aklabs
2007-05-26T21:34:02.309037Z
9
andrew
eb184899-6090-47d4-a65b-558f62f6ea1c
Repository
file
2010-02-05T03:38:11.541998Z
fe589a9114dbc10a364d946adec5343b
2007-05-26T21:34:02.309037Z
9
andrew
56
Root
file
2010-02-05T03:38:11.557623Z
7af14a164593104c1e7a07a572dd352a
2007-05-26T21:34:02.309037Z
9
andrew
24
Entries
file
2010-02-05T03:38:11.557623Z
57b8d745384127342f95660d97e1c9c2
2007-05-26T21:34:02.309037Z
9
andrew
2
Entries.Log
file
2010-02-05T03:38:11.557623Z
3bfbaaf494411b9ccd4c580f75b41a89
2007-05-26T21:34:02.309037Z
9
andrew
38

View File

@@ -0,0 +1,3 @@
A D/cgame////
A D/game////
A D/ui////

View File

@@ -0,0 +1 @@
D

View File

@@ -0,0 +1 @@
games/quake3/hypermod/code/debug-x86-Linux-2.3/Q3/cgame

View File

@@ -0,0 +1 @@
andrew@gabbo:/home/cvsd

View File

@@ -0,0 +1 @@
D

View File

@@ -0,0 +1,3 @@
A D/cgame////
A D/game////
A D/ui////

View File

@@ -0,0 +1 @@
games/quake3/hypermod/code/debug-x86-Linux-2.3/Q3/cgame

View File

@@ -0,0 +1 @@
andrew@gabbo:/home/cvsd

View File

@@ -0,0 +1,62 @@
cg_ents.o:1080791356 8052345671d7b2fbd0d8f750df5c33d9
cg_draw.o:1080791355 6ac2eb2750ecb8d8d86eacdc8db10654
cg_predict.o:1080791358 2fe26f63507a41632d98a13852db1e38
cg_info.o:1080791356 cf82bd5963ac8b29b63c1071e9323314
cg_info.asm:1080791466 45a91260bfd11c2422b035ee71a79fde
cg_predict.c:1080784657 - 3f8ed64bd3b44b9e38ec92adc2e71931
cg_players.c:1080784657 - 0c2e2ceb72088443e4960d7591d29f50
cg_weapons.asm:1080791467 88d9a1801155584e3981bbcf23ccbe2e
cg_event.asm:1080791466 4e3ad9cc8042f17a048c2f6a9b442a1e
cg_main.o:1080791353 0f464b1f556b07d73553277395498919
cg_main.c:1080784657 - 101b3885fff8d7baf8e4ddbc04f476d7
cgame.qvm:1080791469 22f5e683dab008ee648b8773212c9624
cg_event.c:1080784657 - d15df26c8f572b72ec9a53978c6af5fa
cg_view.o:1080791360 74ac9a8ed55da0b26f4541bcc94878b3
cg_drawtools.o:1080791355 5d643c743d0f5359a9823f21dea60e49
cgamei386.so:1080791361 e765ebf1176e738fa6580139bddbb168
cg_syscalls.c:1080784657 - 22fdc7ddb48285ddcdc3365d99684eec
cg_localents.asm:1080791466 083c69a772f85421b9d2ac6ebb570fd5
cg_local.h:1080784657 - b057d91af178a987ad8a5fbd82b9f298
cg_predict.asm:1080791467 cc7688f5f2ccd40fba7a4e45b15653a7
cg_draw.asm:1080791466 a0def1314954d40ce1252000e342e161
cg_syscalls.o:1080791360 a3fb65dd9ba4f4d7af5ca476f9295b9e
cg_view.c:1080784657 - 8be552e6cbfdaacfaa9846d320b2ac87
cg_consolecmds.c:1080784657 - 802e531b835824b793f522fb555c4dad
cg_syscalls.asm:1080784657 - 667b53ae03139e3a5bafa176d234f859
cg_drawtools.c:1080784657 - 1dda97d31902f3ee93bc45f53f913012
cg_localents.c:1080784657 - adcfb9d3690f417628feeb9f9ef67cf3
cg_players.o:1080791358 76e2a56a1b4542fd8b111dc982a91a7d
cg_consolecmds.asm:1080791466 af11c5600f6c18e36aaa66b0be190bc3
cg_marks.c:1080784657 - 0b8005ee129e94f6d00ac6de7db8b1b4
cg_playerstate.asm:1080791467 89f9af2b9cde629ad78e55584ca096f8
cg_draw.c:1080784657 - 50d395cfdb1321fd867e5c94be1dd48c
cg_ents.c:1080784657 - 7507cd68ae25a485370ced0af66b4995
cg_playerstate.c:1080784657 - bb774d9b112cc40e87507d592db6162d
cg_weapons.o:1080791360 5fc88bf9fcf9cbc9f48e57a781168796
cg_main.asm:1080791466 d42040ad601718f1536021da815a6c0a
cg_drawtools.asm:1080791466 3846e3050b73620a24be2960680d4fe0
cg_info.c:1080784657 - d1c7d2583deefcbc4f40f5a8108c363b
cg_servercmds.o:1080791359 b41f533e5c2ba2026b26059a7beef652
cg_players.asm:1080791467 a7eee052fc139f7ded42659392fd4ec2
cg_effects.o:1080791355 22d554699666847b379bfcb13fc6b1f1
cg_scoreboard.o:1080791359 76a8b4a5673a12b59a28eab83f38650e
cg_snapshot.c:1080784657 - e318325bfbe9dcc3ec7811d1401cd03c
cg_weapons.c:1080784657 - 43b9281a97eb5e15915b4728b573a1e7
cg_consolecmds.o:1080791354 c811fa22959e784c50f78911f881fc1f
cg_effects.c:1080784657 - 935965234b364388481325b7ac2baf91
cg_localents.o:1080791357 892d70ef69ae35dc654db99045dcea43
cg_marks.asm:1080791467 736490e1acb54f24b013b1dc2e9b53ee
cg_scoreboard.c:1080784657 - 40209f2555c330cc002f7dcaf39fa7d6
cg_public.h:1080784657 - a3c0dd7a5eea4276eecf72fd6e4e8033
cg_snapshot.o:1080791359 d3fc16471b68a25d307c50e565941ac3
cg_servercmds.c:1080784657 - 23db883fd3e26c623a3a56e14a5023ef
cg_playerstate.o:1080791358 23de958dd81a26de7cfe6217b70c00ff
cg_scoreboard.asm:1080791467 9f68c56bb6695dc78a46a5aff53d59c6
cg_servercmds.asm:1080791467 c565e26bf99a6e9d32aa1b104a7b2dc0
cg_event.o:1080791356 84df8d72732adf398e038b5ce3379a14
cg_effects.asm:1080791466 a415a7c2373b907639071e378b93a029
tr_types.h:1080784657 - 3c0832ac2e6d1f188b3781f8b7066020
cg_marks.o:1080791357 a803f60783e72829c4753d286900208a
cg_snapshot.asm:1080791467 39922ba5f2b375fc96bada018f8b4916
cg_ents.asm:1080791466 a4fff2e2ad8bffa70a6e4ce69330cbdc
cg_view.asm:1080791467 88daa055b648c1b4dba40c4e01832c0d

View File

@@ -0,0 +1,263 @@
K 25
svn:wc:ra_dav:version-url
V 77
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame
END
cg_predict.asm
K 25
svn:wc:ra_dav:version-url
V 92
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_predict.asm
END
cg_predict.c
K 25
svn:wc:ra_dav:version-url
V 90
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_predict.c
END
cg_playerstate.asm
K 25
svn:wc:ra_dav:version-url
V 96
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_playerstate.asm
END
cg_playerstate.c
K 25
svn:wc:ra_dav:version-url
V 94
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_playerstate.c
END
cg_snapshot.asm
K 25
svn:wc:ra_dav:version-url
V 93
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_snapshot.asm
END
cgame.map
K 25
svn:wc:ra_dav:version-url
V 87
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cgame.map
END
cg_local.h
K 25
svn:wc:ra_dav:version-url
V 88
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_local.h
END
cg_snapshot.c
K 25
svn:wc:ra_dav:version-url
V 91
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_snapshot.c
END
cg_weapons.asm
K 25
svn:wc:ra_dav:version-url
V 92
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_weapons.asm
END
cg_marks.asm
K 25
svn:wc:ra_dav:version-url
V 90
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_marks.asm
END
cg_drawtools.asm
K 25
svn:wc:ra_dav:version-url
V 94
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_drawtools.asm
END
cg_weapons.c
K 25
svn:wc:ra_dav:version-url
V 90
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_weapons.c
END
cg_players.asm
K 25
svn:wc:ra_dav:version-url
V 92
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_players.asm
END
cg_marks.c
K 25
svn:wc:ra_dav:version-url
V 88
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_marks.c
END
cg_drawtools.c
K 25
svn:wc:ra_dav:version-url
V 92
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_drawtools.c
END
cg_players.c
K 25
svn:wc:ra_dav:version-url
V 90
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_players.c
END
cg_event.asm
K 25
svn:wc:ra_dav:version-url
V 90
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_event.asm
END
cg_event.c
K 25
svn:wc:ra_dav:version-url
V 88
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_event.c
END
cg_localents.asm
K 25
svn:wc:ra_dav:version-url
V 94
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_localents.asm
END
cg_localents.c
K 25
svn:wc:ra_dav:version-url
V 92
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_localents.c
END
cg_info.asm
K 25
svn:wc:ra_dav:version-url
V 89
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_info.asm
END
cg_draw.asm
K 25
svn:wc:ra_dav:version-url
V 89
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_draw.asm
END
cg_info.c
K 25
svn:wc:ra_dav:version-url
V 87
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_info.c
END
cg_syscalls.asm
K 25
svn:wc:ra_dav:version-url
V 93
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_syscalls.asm
END
cg_draw.c
K 25
svn:wc:ra_dav:version-url
V 87
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_draw.c
END
cg_syscalls.c
K 25
svn:wc:ra_dav:version-url
V 91
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_syscalls.c
END
tr_types.h
K 25
svn:wc:ra_dav:version-url
V 88
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/tr_types.h
END
cg_consolecmds.asm
K 25
svn:wc:ra_dav:version-url
V 96
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_consolecmds.asm
END
cg_ents.asm
K 25
svn:wc:ra_dav:version-url
V 89
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_ents.asm
END
cg_view.asm
K 25
svn:wc:ra_dav:version-url
V 89
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_view.asm
END
cg_ents.c
K 25
svn:wc:ra_dav:version-url
V 87
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_ents.c
END
cg_consolecmds.c
K 25
svn:wc:ra_dav:version-url
V 94
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_consolecmds.c
END
cg_view.c
K 25
svn:wc:ra_dav:version-url
V 87
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_view.c
END
cg_servercmds.asm
K 25
svn:wc:ra_dav:version-url
V 95
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_servercmds.asm
END
cg_effects.asm
K 25
svn:wc:ra_dav:version-url
V 92
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_effects.asm
END
cg_servercmds.c
K 25
svn:wc:ra_dav:version-url
V 93
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_servercmds.c
END
cg_effects.c
K 25
svn:wc:ra_dav:version-url
V 90
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_effects.c
END
cg_scoreboard.asm
K 25
svn:wc:ra_dav:version-url
V 95
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_scoreboard.asm
END
cg_main.asm
K 25
svn:wc:ra_dav:version-url
V 89
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_main.asm
END
cg_scoreboard.c
K 25
svn:wc:ra_dav:version-url
V 93
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_scoreboard.c
END
cg_public.h
K 25
svn:wc:ra_dav:version-url
V 89
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_public.h
END
cg_main.c
K 25
svn:wc:ra_dav:version-url
V 87
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/cg_main.c
END
.consign
K 25
svn:wc:ra_dav:version-url
V 86
/svn/aklabs/!svn/ver/9/trunk/hypermod/code/debug-x86-Linux-2.3/Q3/cgame/cgame/.consign
END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 0
END

View File

@@ -0,0 +1,62 @@
cg_ents.o:1080791356 8052345671d7b2fbd0d8f750df5c33d9
cg_draw.o:1080791355 6ac2eb2750ecb8d8d86eacdc8db10654
cg_predict.o:1080791358 2fe26f63507a41632d98a13852db1e38
cg_info.o:1080791356 cf82bd5963ac8b29b63c1071e9323314
cg_info.asm:1080791466 45a91260bfd11c2422b035ee71a79fde
cg_predict.c:1080784657 - 3f8ed64bd3b44b9e38ec92adc2e71931
cg_players.c:1080784657 - 0c2e2ceb72088443e4960d7591d29f50
cg_weapons.asm:1080791467 88d9a1801155584e3981bbcf23ccbe2e
cg_event.asm:1080791466 4e3ad9cc8042f17a048c2f6a9b442a1e
cg_main.o:1080791353 0f464b1f556b07d73553277395498919
cg_main.c:1080784657 - 101b3885fff8d7baf8e4ddbc04f476d7
cgame.qvm:1080791469 22f5e683dab008ee648b8773212c9624
cg_event.c:1080784657 - d15df26c8f572b72ec9a53978c6af5fa
cg_view.o:1080791360 74ac9a8ed55da0b26f4541bcc94878b3
cg_drawtools.o:1080791355 5d643c743d0f5359a9823f21dea60e49
cgamei386.so:1080791361 e765ebf1176e738fa6580139bddbb168
cg_syscalls.c:1080784657 - 22fdc7ddb48285ddcdc3365d99684eec
cg_localents.asm:1080791466 083c69a772f85421b9d2ac6ebb570fd5
cg_local.h:1080784657 - b057d91af178a987ad8a5fbd82b9f298
cg_predict.asm:1080791467 cc7688f5f2ccd40fba7a4e45b15653a7
cg_draw.asm:1080791466 a0def1314954d40ce1252000e342e161
cg_syscalls.o:1080791360 a3fb65dd9ba4f4d7af5ca476f9295b9e
cg_view.c:1080784657 - 8be552e6cbfdaacfaa9846d320b2ac87
cg_consolecmds.c:1080784657 - 802e531b835824b793f522fb555c4dad
cg_syscalls.asm:1080784657 - 667b53ae03139e3a5bafa176d234f859
cg_drawtools.c:1080784657 - 1dda97d31902f3ee93bc45f53f913012
cg_localents.c:1080784657 - adcfb9d3690f417628feeb9f9ef67cf3
cg_players.o:1080791358 76e2a56a1b4542fd8b111dc982a91a7d
cg_consolecmds.asm:1080791466 af11c5600f6c18e36aaa66b0be190bc3
cg_marks.c:1080784657 - 0b8005ee129e94f6d00ac6de7db8b1b4
cg_playerstate.asm:1080791467 89f9af2b9cde629ad78e55584ca096f8
cg_draw.c:1080784657 - 50d395cfdb1321fd867e5c94be1dd48c
cg_ents.c:1080784657 - 7507cd68ae25a485370ced0af66b4995
cg_playerstate.c:1080784657 - bb774d9b112cc40e87507d592db6162d
cg_weapons.o:1080791360 5fc88bf9fcf9cbc9f48e57a781168796
cg_main.asm:1080791466 d42040ad601718f1536021da815a6c0a
cg_drawtools.asm:1080791466 3846e3050b73620a24be2960680d4fe0
cg_info.c:1080784657 - d1c7d2583deefcbc4f40f5a8108c363b
cg_servercmds.o:1080791359 b41f533e5c2ba2026b26059a7beef652
cg_players.asm:1080791467 a7eee052fc139f7ded42659392fd4ec2
cg_effects.o:1080791355 22d554699666847b379bfcb13fc6b1f1
cg_scoreboard.o:1080791359 76a8b4a5673a12b59a28eab83f38650e
cg_snapshot.c:1080784657 - e318325bfbe9dcc3ec7811d1401cd03c
cg_weapons.c:1080784657 - 43b9281a97eb5e15915b4728b573a1e7
cg_consolecmds.o:1080791354 c811fa22959e784c50f78911f881fc1f
cg_effects.c:1080784657 - 935965234b364388481325b7ac2baf91
cg_localents.o:1080791357 892d70ef69ae35dc654db99045dcea43
cg_marks.asm:1080791467 736490e1acb54f24b013b1dc2e9b53ee
cg_scoreboard.c:1080784657 - 40209f2555c330cc002f7dcaf39fa7d6
cg_public.h:1080784657 - a3c0dd7a5eea4276eecf72fd6e4e8033
cg_snapshot.o:1080791359 d3fc16471b68a25d307c50e565941ac3
cg_servercmds.c:1080784657 - 23db883fd3e26c623a3a56e14a5023ef
cg_playerstate.o:1080791358 23de958dd81a26de7cfe6217b70c00ff
cg_scoreboard.asm:1080791467 9f68c56bb6695dc78a46a5aff53d59c6
cg_servercmds.asm:1080791467 c565e26bf99a6e9d32aa1b104a7b2dc0
cg_event.o:1080791356 84df8d72732adf398e038b5ce3379a14
cg_effects.asm:1080791466 a415a7c2373b907639071e378b93a029
tr_types.h:1080784657 - 3c0832ac2e6d1f188b3781f8b7066020
cg_marks.o:1080791357 a803f60783e72829c4753d286900208a
cg_snapshot.asm:1080791467 39922ba5f2b375fc96bada018f8b4916
cg_ents.asm:1080791466 a4fff2e2ad8bffa70a6e4ce69330cbdc
cg_view.asm:1080791467 88daa055b648c1b4dba40c4e01832c0d

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,558 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_consolecmds.c -- text commands typed in at the local console, or
// executed by a key binding
#include "cg_local.h"
#include "../ui/ui_shared.h"
#ifdef MISSIONPACK
extern menuDef_t *menuScoreboard;
#endif
void CG_TargetCommand_f( void ) {
int targetNum;
char test[4];
targetNum = CG_CrosshairPlayer();
if (!targetNum ) {
return;
}
trap_Argv( 1, test, 4 );
trap_SendConsoleCommand( va( "gc %i %i", targetNum, atoi( test ) ) );
}
/*
=================
CG_SizeUp_f
Keybinding command
=================
*/
static void CG_SizeUp_f (void) {
trap_Cvar_Set("cg_viewsize", va("%i",(int)(cg_viewsize.integer+10)));
}
/*
=================
CG_SizeDown_f
Keybinding command
=================
*/
static void CG_SizeDown_f (void) {
trap_Cvar_Set("cg_viewsize", va("%i",(int)(cg_viewsize.integer-10)));
}
/*
=============
CG_Viewpos_f
Debugging command to print the current position
=============
*/
static void CG_Viewpos_f (void) {
CG_Printf ("(%i %i %i) : %i\n", (int)cg.refdef.vieworg[0],
(int)cg.refdef.vieworg[1], (int)cg.refdef.vieworg[2],
(int)cg.refdefViewAngles[YAW]);
}
static void CG_ScoresDown_f( void ) {
#ifdef MISSIONPACK
CG_BuildSpectatorString();
#endif
if ( cg.scoresRequestTime + 2000 < cg.time ) {
// the scores are more than two seconds out of data,
// so request new ones
cg.scoresRequestTime = cg.time;
trap_SendClientCommand( "score" );
// leave the current scores up if they were already
// displayed, but if this is the first hit, clear them out
if ( !cg.showScores ) {
cg.showScores = qtrue;
cg.numScores = 0;
}
} else {
// show the cached contents even if they just pressed if it
// is within two seconds
cg.showScores = qtrue;
}
}
static void CG_ScoresUp_f( void ) {
if ( cg.showScores ) {
cg.showScores = qfalse;
cg.scoreFadeTime = cg.time;
}
}
#ifdef MISSIONPACK
extern menuDef_t *menuScoreboard;
void Menu_Reset(); // FIXME: add to right include file
static void CG_LoadHud_f( void) {
char buff[1024];
const char *hudSet;
memset(buff, 0, sizeof(buff));
String_Init();
Menu_Reset();
trap_Cvar_VariableStringBuffer("cg_hudFiles", buff, sizeof(buff));
hudSet = buff;
if (hudSet[0] == '\0') {
hudSet = "ui/hud.txt";
}
CG_LoadMenus(hudSet);
menuScoreboard = NULL;
}
static void CG_scrollScoresDown_f( void) {
if (menuScoreboard && cg.scoreBoardShowing) {
Menu_ScrollFeeder(menuScoreboard, FEEDER_SCOREBOARD, qtrue);
Menu_ScrollFeeder(menuScoreboard, FEEDER_REDTEAM_LIST, qtrue);
Menu_ScrollFeeder(menuScoreboard, FEEDER_BLUETEAM_LIST, qtrue);
}
}
static void CG_scrollScoresUp_f( void) {
if (menuScoreboard && cg.scoreBoardShowing) {
Menu_ScrollFeeder(menuScoreboard, FEEDER_SCOREBOARD, qfalse);
Menu_ScrollFeeder(menuScoreboard, FEEDER_REDTEAM_LIST, qfalse);
Menu_ScrollFeeder(menuScoreboard, FEEDER_BLUETEAM_LIST, qfalse);
}
}
static void CG_spWin_f( void) {
trap_Cvar_Set("cg_cameraOrbit", "2");
trap_Cvar_Set("cg_cameraOrbitDelay", "35");
trap_Cvar_Set("cg_thirdPerson", "1");
trap_Cvar_Set("cg_thirdPersonAngle", "0");
trap_Cvar_Set("cg_thirdPersonRange", "100");
CG_AddBufferedSound(cgs.media.winnerSound);
//trap_S_StartLocalSound(cgs.media.winnerSound, CHAN_ANNOUNCER);
CG_CenterPrint("YOU WIN!", SCREEN_HEIGHT * .30, 0);
}
static void CG_spLose_f( void) {
trap_Cvar_Set("cg_cameraOrbit", "2");
trap_Cvar_Set("cg_cameraOrbitDelay", "35");
trap_Cvar_Set("cg_thirdPerson", "1");
trap_Cvar_Set("cg_thirdPersonAngle", "0");
trap_Cvar_Set("cg_thirdPersonRange", "100");
CG_AddBufferedSound(cgs.media.loserSound);
//trap_S_StartLocalSound(cgs.media.loserSound, CHAN_ANNOUNCER);
CG_CenterPrint("YOU LOSE...", SCREEN_HEIGHT * .30, 0);
}
#endif
static void CG_TellTarget_f( void ) {
int clientNum;
char command[128];
char message[128];
clientNum = CG_CrosshairPlayer();
if ( clientNum == -1 ) {
return;
}
trap_Args( message, 128 );
Com_sprintf( command, 128, "tell %i %s", clientNum, message );
trap_SendClientCommand( command );
}
static void CG_TellAttacker_f( void ) {
int clientNum;
char command[128];
char message[128];
clientNum = CG_LastAttacker();
if ( clientNum == -1 ) {
return;
}
trap_Args( message, 128 );
Com_sprintf( command, 128, "tell %i %s", clientNum, message );
trap_SendClientCommand( command );
}
static void CG_VoiceTellTarget_f( void ) {
int clientNum;
char command[128];
char message[128];
clientNum = CG_CrosshairPlayer();
if ( clientNum == -1 ) {
return;
}
trap_Args( message, 128 );
Com_sprintf( command, 128, "vtell %i %s", clientNum, message );
trap_SendClientCommand( command );
}
static void CG_VoiceTellAttacker_f( void ) {
int clientNum;
char command[128];
char message[128];
clientNum = CG_LastAttacker();
if ( clientNum == -1 ) {
return;
}
trap_Args( message, 128 );
Com_sprintf( command, 128, "vtell %i %s", clientNum, message );
trap_SendClientCommand( command );
}
#ifdef MISSIONPACK
static void CG_NextTeamMember_f( void ) {
CG_SelectNextPlayer();
}
static void CG_PrevTeamMember_f( void ) {
CG_SelectPrevPlayer();
}
// ASS U ME's enumeration order as far as task specific orders, OFFENSE is zero, CAMP is last
//
static void CG_NextOrder_f( void ) {
clientInfo_t *ci = cgs.clientinfo + cg.snap->ps.clientNum;
if (ci) {
if (!ci->teamLeader && sortedTeamPlayers[cg_currentSelectedPlayer.integer] != cg.snap->ps.clientNum) {
return;
}
}
if (cgs.currentOrder < TEAMTASK_CAMP) {
cgs.currentOrder++;
if (cgs.currentOrder == TEAMTASK_RETRIEVE) {
if (!CG_OtherTeamHasFlag()) {
cgs.currentOrder++;
}
}
if (cgs.currentOrder == TEAMTASK_ESCORT) {
if (!CG_YourTeamHasFlag()) {
cgs.currentOrder++;
}
}
} else {
cgs.currentOrder = TEAMTASK_OFFENSE;
}
cgs.orderPending = qtrue;
cgs.orderTime = cg.time + 3000;
}
static void CG_ConfirmOrder_f (void ) {
trap_SendConsoleCommand(va("cmd vtell %d %s\n", cgs.acceptLeader, VOICECHAT_YES));
trap_SendConsoleCommand("+button5; wait; -button5");
if (cg.time < cgs.acceptOrderTime) {
trap_SendClientCommand(va("teamtask %d\n", cgs.acceptTask));
cgs.acceptOrderTime = 0;
}
}
static void CG_DenyOrder_f (void ) {
trap_SendConsoleCommand(va("cmd vtell %d %s\n", cgs.acceptLeader, VOICECHAT_NO));
trap_SendConsoleCommand("+button6; wait; -button6");
if (cg.time < cgs.acceptOrderTime) {
cgs.acceptOrderTime = 0;
}
}
static void CG_TaskOffense_f (void ) {
if (cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF) {
trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONGETFLAG));
} else {
trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONOFFENSE));
}
trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_OFFENSE));
}
static void CG_TaskDefense_f (void ) {
trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONDEFENSE));
trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_DEFENSE));
}
static void CG_TaskPatrol_f (void ) {
trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONPATROL));
trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_PATROL));
}
static void CG_TaskCamp_f (void ) {
trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONCAMPING));
trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_CAMP));
}
static void CG_TaskFollow_f (void ) {
trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONFOLLOW));
trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_FOLLOW));
}
static void CG_TaskRetrieve_f (void ) {
trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONRETURNFLAG));
trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_RETRIEVE));
}
static void CG_TaskEscort_f (void ) {
trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_ONFOLLOWCARRIER));
trap_SendClientCommand(va("teamtask %d\n", TEAMTASK_ESCORT));
}
static void CG_TaskOwnFlag_f (void ) {
trap_SendConsoleCommand(va("cmd vsay_team %s\n", VOICECHAT_IHAVEFLAG));
}
static void CG_TauntKillInsult_f (void ) {
trap_SendConsoleCommand("cmd vsay kill_insult\n");
}
static void CG_TauntPraise_f (void ) {
trap_SendConsoleCommand("cmd vsay praise\n");
}
static void CG_TauntTaunt_f (void ) {
trap_SendConsoleCommand("cmd vtaunt\n");
}
static void CG_TauntDeathInsult_f (void ) {
trap_SendConsoleCommand("cmd vsay death_insult\n");
}
static void CG_TauntGauntlet_f (void ) {
trap_SendConsoleCommand("cmd vsay kill_guantlet\n");
}
static void CG_TaskSuicide_f (void ) {
int clientNum;
char command[128];
clientNum = CG_CrosshairPlayer();
if ( clientNum == -1 ) {
return;
}
Com_sprintf( command, 128, "tell %i suicide", clientNum );
trap_SendClientCommand( command );
}
/*
==================
CG_TeamMenu_f
==================
*/
/*
static void CG_TeamMenu_f( void ) {
if (trap_Key_GetCatcher() & KEYCATCH_CGAME) {
CG_EventHandling(CGAME_EVENT_NONE);
trap_Key_SetCatcher(0);
} else {
CG_EventHandling(CGAME_EVENT_TEAMMENU);
//trap_Key_SetCatcher(KEYCATCH_CGAME);
}
}
*/
/*
==================
CG_EditHud_f
==================
*/
/*
static void CG_EditHud_f( void ) {
//cls.keyCatchers ^= KEYCATCH_CGAME;
//VM_Call (cgvm, CG_EVENT_HANDLING, (cls.keyCatchers & KEYCATCH_CGAME) ? CGAME_EVENT_EDITHUD : CGAME_EVENT_NONE);
}
*/
#endif
/*
==================
CG_StartOrbit_f
==================
*/
static void CG_StartOrbit_f( void ) {
char var[MAX_TOKEN_CHARS];
trap_Cvar_VariableStringBuffer( "developer", var, sizeof( var ) );
if ( !atoi(var) ) {
return;
}
if (cg_cameraOrbit.value != 0) {
trap_Cvar_Set ("cg_cameraOrbit", "0");
trap_Cvar_Set("cg_thirdPerson", "0");
} else {
trap_Cvar_Set("cg_cameraOrbit", "5");
trap_Cvar_Set("cg_thirdPerson", "1");
trap_Cvar_Set("cg_thirdPersonAngle", "0");
trap_Cvar_Set("cg_thirdPersonRange", "100");
}
}
/*
static void CG_Camera_f( void ) {
char name[1024];
trap_Argv( 1, name, sizeof(name));
if (trap_loadCamera(name)) {
cg.cameraMode = qtrue;
trap_startCamera(cg.time);
} else {
CG_Printf ("Unable to load camera %s\n",name);
}
}
*/
typedef struct {
char *cmd;
void (*function)(void);
} consoleCommand_t;
static consoleCommand_t commands[] = {
{ "testgun", CG_TestGun_f },
{ "testmodel", CG_TestModel_f },
{ "nextframe", CG_TestModelNextFrame_f },
{ "prevframe", CG_TestModelPrevFrame_f },
{ "nextskin", CG_TestModelNextSkin_f },
{ "prevskin", CG_TestModelPrevSkin_f },
{ "viewpos", CG_Viewpos_f },
{ "+scores", CG_ScoresDown_f },
{ "-scores", CG_ScoresUp_f },
{ "+zoom", CG_ZoomDown_f },
{ "-zoom", CG_ZoomUp_f },
{ "sizeup", CG_SizeUp_f },
{ "sizedown", CG_SizeDown_f },
{ "weapnext", CG_NextWeapon_f },
{ "weapprev", CG_PrevWeapon_f },
{ "weapon", CG_Weapon_f },
{ "tell_target", CG_TellTarget_f },
{ "tell_attacker", CG_TellAttacker_f },
{ "vtell_target", CG_VoiceTellTarget_f },
{ "vtell_attacker", CG_VoiceTellAttacker_f },
{ "tcmd", CG_TargetCommand_f },
#ifdef MISSIONPACK
{ "loadhud", CG_LoadHud_f },
{ "nextTeamMember", CG_NextTeamMember_f },
{ "prevTeamMember", CG_PrevTeamMember_f },
{ "nextOrder", CG_NextOrder_f },
{ "confirmOrder", CG_ConfirmOrder_f },
{ "denyOrder", CG_DenyOrder_f },
{ "taskOffense", CG_TaskOffense_f },
{ "taskDefense", CG_TaskDefense_f },
{ "taskPatrol", CG_TaskPatrol_f },
{ "taskCamp", CG_TaskCamp_f },
{ "taskFollow", CG_TaskFollow_f },
{ "taskRetrieve", CG_TaskRetrieve_f },
{ "taskEscort", CG_TaskEscort_f },
{ "taskSuicide", CG_TaskSuicide_f },
{ "taskOwnFlag", CG_TaskOwnFlag_f },
{ "tauntKillInsult", CG_TauntKillInsult_f },
{ "tauntPraise", CG_TauntPraise_f },
{ "tauntTaunt", CG_TauntTaunt_f },
{ "tauntDeathInsult", CG_TauntDeathInsult_f },
{ "tauntGauntlet", CG_TauntGauntlet_f },
{ "spWin", CG_spWin_f },
{ "spLose", CG_spLose_f },
{ "scoresDown", CG_scrollScoresDown_f },
{ "scoresUp", CG_scrollScoresUp_f },
#endif
{ "startOrbit", CG_StartOrbit_f },
//{ "camera", CG_Camera_f },
{ "loaddeferred", CG_LoadDeferredPlayers }
};
/*
=================
CG_ConsoleCommand
The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
qboolean CG_ConsoleCommand( void ) {
const char *cmd;
int i;
cmd = CG_Argv(0);
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
if ( !Q_stricmp( cmd, commands[i].cmd ) ) {
commands[i].function();
return qtrue;
}
}
return qfalse;
}
/*
=================
CG_InitConsoleCommands
Let the client system know about all of our commands
so it can perform tab completion
=================
*/
void CG_InitConsoleCommands( void ) {
int i;
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
trap_AddCommand( commands[i].cmd );
}
//
// the game server will interpret these commands, which will be automatically
// forwarded to the server after they are not recognized locally
//
trap_AddCommand ("kill");
trap_AddCommand ("say");
trap_AddCommand ("say_team");
trap_AddCommand ("tell");
trap_AddCommand ("vsay");
trap_AddCommand ("vsay_team");
trap_AddCommand ("vtell");
trap_AddCommand ("vtaunt");
trap_AddCommand ("vosay");
trap_AddCommand ("vosay_team");
trap_AddCommand ("votell");
trap_AddCommand ("give");
trap_AddCommand ("god");
trap_AddCommand ("notarget");
trap_AddCommand ("noclip");
trap_AddCommand ("team");
trap_AddCommand ("follow");
trap_AddCommand ("levelshot");
trap_AddCommand ("addbot");
trap_AddCommand ("setviewpos");
trap_AddCommand ("callvote");
trap_AddCommand ("vote");
trap_AddCommand ("callteamvote");
trap_AddCommand ("teamvote");
trap_AddCommand ("stats");
trap_AddCommand ("teamtask");
trap_AddCommand ("loaddefered"); // spelled wrong, but not changing for demo
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,804 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_drawtools.c -- helper functions called by cg_draw, cg_scoreboard, cg_info, etc
#include "cg_local.h"
/*
================
CG_AdjustFrom640
Adjusted for resolution and screen aspect ratio
================
*/
void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) {
#if 0
// adjust for wide screens
if ( cgs.glconfig.vidWidth * 480 > cgs.glconfig.vidHeight * 640 ) {
*x += 0.5 * ( cgs.glconfig.vidWidth - ( cgs.glconfig.vidHeight * 640 / 480 ) );
}
#endif
// scale for screen sizes
*x *= cgs.screenXScale;
*y *= cgs.screenYScale;
*w *= cgs.screenXScale;
*h *= cgs.screenYScale;
}
/*
================
CG_FillRect
Coordinates are 640*480 virtual values
=================
*/
void CG_FillRect( float x, float y, float width, float height, const float *color ) {
trap_R_SetColor( color );
CG_AdjustFrom640( &x, &y, &width, &height );
trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, cgs.media.whiteShader );
trap_R_SetColor( NULL );
}
/*
================
CG_DrawSides
Coords are virtual 640x480
================
*/
void CG_DrawSides(float x, float y, float w, float h, float size) {
CG_AdjustFrom640( &x, &y, &w, &h );
size *= cgs.screenXScale;
trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, cgs.media.whiteShader );
trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, cgs.media.whiteShader );
}
void CG_DrawTopBottom(float x, float y, float w, float h, float size) {
CG_AdjustFrom640( &x, &y, &w, &h );
size *= cgs.screenYScale;
trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, cgs.media.whiteShader );
trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, cgs.media.whiteShader );
}
/*
================
UI_DrawRect
Coordinates are 640*480 virtual values
=================
*/
void CG_DrawRect( float x, float y, float width, float height, float size, const float *color ) {
trap_R_SetColor( color );
CG_DrawTopBottom(x, y, width, height, size);
CG_DrawSides(x, y, width, height, size);
trap_R_SetColor( NULL );
}
/*
================
CG_DrawPic
Coordinates are 640*480 virtual values
=================
*/
void CG_DrawPic( float x, float y, float width, float height, qhandle_t hShader ) {
CG_AdjustFrom640( &x, &y, &width, &height );
trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader );
}
/*
===============
CG_DrawChar
Coordinates and size in 640*480 virtual screen size
===============
*/
void CG_DrawChar( int x, int y, int width, int height, int ch ) {
int row, col;
float frow, fcol;
float size;
float ax, ay, aw, ah;
ch &= 255;
if ( ch == ' ' ) {
return;
}
ax = x;
ay = y;
aw = width;
ah = height;
CG_AdjustFrom640( &ax, &ay, &aw, &ah );
row = ch>>4;
col = ch&15;
frow = row*0.0625;
fcol = col*0.0625;
size = 0.0625;
trap_R_DrawStretchPic( ax, ay, aw, ah,
fcol, frow,
fcol + size, frow + size,
cgs.media.charsetShader );
}
/*
==================
CG_DrawStringExt
Draws a multi-colored string with a drop shadow, optionally forcing
to a fixed color.
Coordinates are at 640 by 480 virtual resolution
==================
*/
void CG_DrawStringExt( int x, int y, const char *string, const float *setColor,
qboolean forceColor, qboolean shadow, int charWidth, int charHeight, int maxChars ) {
vec4_t color;
const char *s;
int xx;
int cnt;
if (maxChars <= 0)
maxChars = 32767; // do them all!
// draw the drop shadow
if (shadow) {
color[0] = color[1] = color[2] = 0;
color[3] = setColor[3];
trap_R_SetColor( color );
s = string;
xx = x;
cnt = 0;
while ( *s && cnt < maxChars) {
if ( Q_IsColorString( s ) ) {
s += 2;
continue;
}
CG_DrawChar( xx + 2, y + 2, charWidth, charHeight, *s );
cnt++;
xx += charWidth;
s++;
}
}
// draw the colored text
s = string;
xx = x;
cnt = 0;
trap_R_SetColor( setColor );
while ( *s && cnt < maxChars) {
if ( Q_IsColorString( s ) ) {
if ( !forceColor ) {
memcpy( color, g_color_table[ColorIndex(*(s+1))], sizeof( color ) );
color[3] = setColor[3];
trap_R_SetColor( color );
}
s += 2;
continue;
}
CG_DrawChar( xx, y, charWidth, charHeight, *s );
xx += charWidth;
cnt++;
s++;
}
trap_R_SetColor( NULL );
}
void CG_DrawBigString( int x, int y, const char *s, float alpha ) {
float color[4];
color[0] = color[1] = color[2] = 1.0;
color[3] = alpha;
CG_DrawStringExt( x, y, s, color, qfalse, qtrue, BIGCHAR_WIDTH, BIGCHAR_HEIGHT, 0 );
}
void CG_DrawBigStringColor( int x, int y, const char *s, vec4_t color ) {
CG_DrawStringExt( x, y, s, color, qtrue, qtrue, BIGCHAR_WIDTH, BIGCHAR_HEIGHT, 0 );
}
void CG_DrawSmallString( int x, int y, const char *s, float alpha ) {
float color[4];
color[0] = color[1] = color[2] = 1.0;
color[3] = alpha;
CG_DrawStringExt( x, y, s, color, qfalse, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, 0 );
}
void CG_DrawSmallStringColor( int x, int y, const char *s, vec4_t color ) {
CG_DrawStringExt( x, y, s, color, qtrue, qfalse, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, 0 );
}
/*
=================
CG_DrawStrlen
Returns character count, skiping color escape codes
=================
*/
int CG_DrawStrlen( const char *str ) {
const char *s = str;
int count = 0;
while ( *s ) {
if ( Q_IsColorString( s ) ) {
s += 2;
} else {
count++;
s++;
}
}
return count;
}
/*
=============
CG_TileClearBox
This repeats a 64*64 tile graphic to fill the screen around a sized down
refresh window.
=============
*/
static void CG_TileClearBox( int x, int y, int w, int h, qhandle_t hShader ) {
float s1, t1, s2, t2;
s1 = x/64.0;
t1 = y/64.0;
s2 = (x+w)/64.0;
t2 = (y+h)/64.0;
trap_R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, hShader );
}
/*
==============
CG_TileClear
Clear around a sized down screen
==============
*/
void CG_TileClear( void ) {
int top, bottom, left, right;
int w, h;
w = cgs.glconfig.vidWidth;
h = cgs.glconfig.vidHeight;
if ( cg.refdef.x == 0 && cg.refdef.y == 0 &&
cg.refdef.width == w && cg.refdef.height == h ) {
return; // full screen rendering
}
top = cg.refdef.y;
bottom = top + cg.refdef.height-1;
left = cg.refdef.x;
right = left + cg.refdef.width-1;
// clear above view screen
CG_TileClearBox( 0, 0, w, top, cgs.media.backTileShader );
// clear below view screen
CG_TileClearBox( 0, bottom, w, h - bottom, cgs.media.backTileShader );
// clear left of view screen
CG_TileClearBox( 0, top, left, bottom - top + 1, cgs.media.backTileShader );
// clear right of view screen
CG_TileClearBox( right, top, w - right, bottom - top + 1, cgs.media.backTileShader );
}
/*
================
CG_FadeColor
================
*/
float *CG_FadeColor( int startMsec, int totalMsec ) {
static vec4_t color;
int t;
if ( startMsec == 0 ) {
return NULL;
}
t = cg.time - startMsec;
if ( t >= totalMsec ) {
return NULL;
}
// fade out
if ( totalMsec - t < FADE_TIME ) {
color[3] = ( totalMsec - t ) * 1.0/FADE_TIME;
} else {
color[3] = 1.0;
}
color[0] = color[1] = color[2] = 1;
return color;
}
/*
================
CG_TeamColor
================
*/
float *CG_TeamColor( int team ) {
static vec4_t red = {1, 0.2f, 0.2f, 1};
static vec4_t blue = {0.2f, 0.2f, 1, 1};
static vec4_t other = {1, 1, 1, 1};
static vec4_t spectator = {0.7f, 0.7f, 0.7f, 1};
switch ( team ) {
case TEAM_RED:
return red;
case TEAM_BLUE:
return blue;
case TEAM_SPECTATOR:
return spectator;
default:
return other;
}
}
/*
=================
CG_GetColorForHealth
=================
*/
void CG_GetColorForHealth( int health, int armor, vec4_t hcolor ) {
int count;
int max;
// calculate the total points of damage that can
// be sustained at the current health / armor level
if ( health <= 0 ) {
VectorClear( hcolor ); // black
hcolor[3] = 1;
return;
}
count = armor;
max = health * ARMOR_PROTECTION / ( 1.0 - ARMOR_PROTECTION );
if ( max < count ) {
count = max;
}
health += count;
// set the color based on health
hcolor[0] = 1.0;
hcolor[3] = 1.0;
if ( health >= 100 ) {
hcolor[2] = 1.0;
} else if ( health < 66 ) {
hcolor[2] = 0;
} else {
hcolor[2] = ( health - 66 ) / 33.0;
}
if ( health > 60 ) {
hcolor[1] = 1.0;
} else if ( health < 30 ) {
hcolor[1] = 0;
} else {
hcolor[1] = ( health - 30 ) / 30.0;
}
}
/*
=================
CG_ColorForHealth
=================
*/
void CG_ColorForHealth( vec4_t hcolor ) {
CG_GetColorForHealth( cg.snap->ps.stats[STAT_HEALTH],
cg.snap->ps.stats[STAT_ARMOR], hcolor );
}
// bk001205 - code below duplicated in q3_ui/ui-atoms.c
// bk001205 - FIXME: does this belong in ui_shared.c?
// bk001205 - FIXME: HARD_LINKED flags not visible here
#ifndef Q3_STATIC // bk001205 - q_shared defines not visible here
/*
=================
UI_DrawProportionalString2
=================
*/
static int propMap[128][3] = {
{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1},
{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1},
{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1},
{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1},
{0, 0, PROP_SPACE_WIDTH}, // SPACE
{11, 122, 7}, // !
{154, 181, 14}, // "
{55, 122, 17}, // #
{79, 122, 18}, // $
{101, 122, 23}, // %
{153, 122, 18}, // &
{9, 93, 7}, // '
{207, 122, 8}, // (
{230, 122, 9}, // )
{177, 122, 18}, // *
{30, 152, 18}, // +
{85, 181, 7}, // ,
{34, 93, 11}, // -
{110, 181, 6}, // .
{130, 152, 14}, // /
{22, 64, 17}, // 0
{41, 64, 12}, // 1
{58, 64, 17}, // 2
{78, 64, 18}, // 3
{98, 64, 19}, // 4
{120, 64, 18}, // 5
{141, 64, 18}, // 6
{204, 64, 16}, // 7
{162, 64, 17}, // 8
{182, 64, 18}, // 9
{59, 181, 7}, // :
{35,181, 7}, // ;
{203, 152, 14}, // <
{56, 93, 14}, // =
{228, 152, 14}, // >
{177, 181, 18}, // ?
{28, 122, 22}, // @
{5, 4, 18}, // A
{27, 4, 18}, // B
{48, 4, 18}, // C
{69, 4, 17}, // D
{90, 4, 13}, // E
{106, 4, 13}, // F
{121, 4, 18}, // G
{143, 4, 17}, // H
{164, 4, 8}, // I
{175, 4, 16}, // J
{195, 4, 18}, // K
{216, 4, 12}, // L
{230, 4, 23}, // M
{6, 34, 18}, // N
{27, 34, 18}, // O
{48, 34, 18}, // P
{68, 34, 18}, // Q
{90, 34, 17}, // R
{110, 34, 18}, // S
{130, 34, 14}, // T
{146, 34, 18}, // U
{166, 34, 19}, // V
{185, 34, 29}, // W
{215, 34, 18}, // X
{234, 34, 18}, // Y
{5, 64, 14}, // Z
{60, 152, 7}, // [
{106, 151, 13}, // '\'
{83, 152, 7}, // ]
{128, 122, 17}, // ^
{4, 152, 21}, // _
{134, 181, 5}, // '
{5, 4, 18}, // A
{27, 4, 18}, // B
{48, 4, 18}, // C
{69, 4, 17}, // D
{90, 4, 13}, // E
{106, 4, 13}, // F
{121, 4, 18}, // G
{143, 4, 17}, // H
{164, 4, 8}, // I
{175, 4, 16}, // J
{195, 4, 18}, // K
{216, 4, 12}, // L
{230, 4, 23}, // M
{6, 34, 18}, // N
{27, 34, 18}, // O
{48, 34, 18}, // P
{68, 34, 18}, // Q
{90, 34, 17}, // R
{110, 34, 18}, // S
{130, 34, 14}, // T
{146, 34, 18}, // U
{166, 34, 19}, // V
{185, 34, 29}, // W
{215, 34, 18}, // X
{234, 34, 18}, // Y
{5, 64, 14}, // Z
{153, 152, 13}, // {
{11, 181, 5}, // |
{180, 152, 13}, // }
{79, 93, 17}, // ~
{0, 0, -1} // DEL
};
static int propMapB[26][3] = {
{11, 12, 33},
{49, 12, 31},
{85, 12, 31},
{120, 12, 30},
{156, 12, 21},
{183, 12, 21},
{207, 12, 32},
{13, 55, 30},
{49, 55, 13},
{66, 55, 29},
{101, 55, 31},
{135, 55, 21},
{158, 55, 40},
{204, 55, 32},
{12, 97, 31},
{48, 97, 31},
{82, 97, 30},
{118, 97, 30},
{153, 97, 30},
{185, 97, 25},
{213, 97, 30},
{11, 139, 32},
{42, 139, 51},
{93, 139, 32},
{126, 139, 31},
{158, 139, 25},
};
#define PROPB_GAP_WIDTH 4
#define PROPB_SPACE_WIDTH 12
#define PROPB_HEIGHT 36
/*
=================
UI_DrawBannerString
=================
*/
static void UI_DrawBannerString2( int x, int y, const char* str, vec4_t color )
{
const char* s;
unsigned char ch; // bk001204 : array subscript
float ax;
float ay;
float aw;
float ah;
float frow;
float fcol;
float fwidth;
float fheight;
// draw the colored text
trap_R_SetColor( color );
ax = x * cgs.screenXScale + cgs.screenXBias;
ay = y * cgs.screenXScale;
s = str;
while ( *s )
{
ch = *s & 127;
if ( ch == ' ' ) {
ax += ((float)PROPB_SPACE_WIDTH + (float)PROPB_GAP_WIDTH)* cgs.screenXScale;
}
else if ( ch >= 'A' && ch <= 'Z' ) {
ch -= 'A';
fcol = (float)propMapB[ch][0] / 256.0f;
frow = (float)propMapB[ch][1] / 256.0f;
fwidth = (float)propMapB[ch][2] / 256.0f;
fheight = (float)PROPB_HEIGHT / 256.0f;
aw = (float)propMapB[ch][2] * cgs.screenXScale;
ah = (float)PROPB_HEIGHT * cgs.screenXScale;
trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, cgs.media.charsetPropB );
ax += (aw + (float)PROPB_GAP_WIDTH * cgs.screenXScale);
}
s++;
}
trap_R_SetColor( NULL );
}
void UI_DrawBannerString( int x, int y, const char* str, int style, vec4_t color ) {
const char * s;
int ch;
int width;
vec4_t drawcolor;
// find the width of the drawn text
s = str;
width = 0;
while ( *s ) {
ch = *s;
if ( ch == ' ' ) {
width += PROPB_SPACE_WIDTH;
}
else if ( ch >= 'A' && ch <= 'Z' ) {
width += propMapB[ch - 'A'][2] + PROPB_GAP_WIDTH;
}
s++;
}
width -= PROPB_GAP_WIDTH;
switch( style & UI_FORMATMASK ) {
case UI_CENTER:
x -= width / 2;
break;
case UI_RIGHT:
x -= width;
break;
case UI_LEFT:
default:
break;
}
if ( style & UI_DROPSHADOW ) {
drawcolor[0] = drawcolor[1] = drawcolor[2] = 0;
drawcolor[3] = color[3];
UI_DrawBannerString2( x+2, y+2, str, drawcolor );
}
UI_DrawBannerString2( x, y, str, color );
}
int UI_ProportionalStringWidth( const char* str ) {
const char * s;
int ch;
int charWidth;
int width;
s = str;
width = 0;
while ( *s ) {
ch = *s & 127;
charWidth = propMap[ch][2];
if ( charWidth != -1 ) {
width += charWidth;
width += PROP_GAP_WIDTH;
}
s++;
}
width -= PROP_GAP_WIDTH;
return width;
}
static void UI_DrawProportionalString2( int x, int y, const char* str, vec4_t color, float sizeScale, qhandle_t charset )
{
const char* s;
unsigned char ch; // bk001204 - unsigned
float ax;
float ay;
float aw;
float ah;
float frow;
float fcol;
float fwidth;
float fheight;
// draw the colored text
trap_R_SetColor( color );
ax = x * cgs.screenXScale + cgs.screenXBias;
ay = y * cgs.screenXScale;
s = str;
while ( *s )
{
ch = *s & 127;
if ( ch == ' ' ) {
aw = (float)PROP_SPACE_WIDTH * cgs.screenXScale * sizeScale;
} else if ( propMap[ch][2] != -1 ) {
fcol = (float)propMap[ch][0] / 256.0f;
frow = (float)propMap[ch][1] / 256.0f;
fwidth = (float)propMap[ch][2] / 256.0f;
fheight = (float)PROP_HEIGHT / 256.0f;
aw = (float)propMap[ch][2] * cgs.screenXScale * sizeScale;
ah = (float)PROP_HEIGHT * cgs.screenXScale * sizeScale;
trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, charset );
} else {
aw = 0;
}
ax += (aw + (float)PROP_GAP_WIDTH * cgs.screenXScale * sizeScale);
s++;
}
trap_R_SetColor( NULL );
}
/*
=================
UI_ProportionalSizeScale
=================
*/
float UI_ProportionalSizeScale( int style ) {
if( style & UI_SMALLFONT ) {
return 0.75;
}
return 1.00;
}
/*
=================
UI_DrawProportionalString
=================
*/
void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color ) {
vec4_t drawcolor;
int width;
float sizeScale;
sizeScale = UI_ProportionalSizeScale( style );
switch( style & UI_FORMATMASK ) {
case UI_CENTER:
width = UI_ProportionalStringWidth( str ) * sizeScale;
x -= width / 2;
break;
case UI_RIGHT:
width = UI_ProportionalStringWidth( str ) * sizeScale;
x -= width;
break;
case UI_LEFT:
default:
break;
}
if ( style & UI_DROPSHADOW ) {
drawcolor[0] = drawcolor[1] = drawcolor[2] = 0;
drawcolor[3] = color[3];
UI_DrawProportionalString2( x+2, y+2, str, drawcolor, sizeScale, cgs.media.charsetProp );
}
if ( style & UI_INVERSE ) {
drawcolor[0] = color[0] * 0.8;
drawcolor[1] = color[1] * 0.8;
drawcolor[2] = color[2] * 0.8;
drawcolor[3] = color[3];
UI_DrawProportionalString2( x, y, str, drawcolor, sizeScale, cgs.media.charsetProp );
return;
}
if ( style & UI_PULSE ) {
drawcolor[0] = color[0] * 0.8;
drawcolor[1] = color[1] * 0.8;
drawcolor[2] = color[2] * 0.8;
drawcolor[3] = color[3];
UI_DrawProportionalString2( x, y, str, color, sizeScale, cgs.media.charsetProp );
drawcolor[0] = color[0];
drawcolor[1] = color[1];
drawcolor[2] = color[2];
drawcolor[3] = 0.5 + 0.5 * sin( cg.time / PULSE_DIVISOR );
UI_DrawProportionalString2( x, y, str, drawcolor, sizeScale, cgs.media.charsetPropGlow );
return;
}
UI_DrawProportionalString2( x, y, str, color, sizeScale, cgs.media.charsetProp );
}
#endif // Q3STATIC

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,698 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_effects.c -- these functions generate localentities, usually as a result
// of event processing
#include "cg_local.h"
/*
==================
CG_BubbleTrail
Bullets shot underwater
==================
*/
void CG_BubbleTrail( vec3_t start, vec3_t end, float spacing ) {
vec3_t move;
vec3_t vec;
float len;
int i;
if ( cg_noProjectileTrail.integer ) {
return;
}
VectorCopy (start, move);
VectorSubtract (end, start, vec);
len = VectorNormalize (vec);
// advance a random amount first
i = rand() % (int)spacing;
VectorMA( move, i, vec, move );
VectorScale (vec, spacing, vec);
for ( ; i < len; i += spacing ) {
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
le->leFlags = LEF_PUFF_DONT_SCALE;
le->leType = LE_MOVE_SCALE_FADE;
le->startTime = cg.time;
le->endTime = cg.time + 1000 + random() * 250;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
re = &le->refEntity;
re->shaderTime = cg.time / 1000.0f;
re->reType = RT_SPRITE;
re->rotation = 0;
re->radius = 3;
re->customShader = cgs.media.waterBubbleShader;
re->shaderRGBA[0] = 0xff;
re->shaderRGBA[1] = 0xff;
re->shaderRGBA[2] = 0xff;
re->shaderRGBA[3] = 0xff;
le->color[3] = 1.0;
le->pos.trType = TR_LINEAR;
le->pos.trTime = cg.time;
VectorCopy( move, le->pos.trBase );
le->pos.trDelta[0] = crandom()*5;
le->pos.trDelta[1] = crandom()*5;
le->pos.trDelta[2] = crandom()*5 + 6;
VectorAdd (move, vec, move);
}
}
/*
=====================
CG_SmokePuff
Adds a smoke puff or blood trail localEntity.
=====================
*/
localEntity_t *CG_SmokePuff( const vec3_t p, const vec3_t vel,
float radius,
float r, float g, float b, float a,
float duration,
int startTime,
int fadeInTime,
int leFlags,
qhandle_t hShader ) {
static int seed = 0x92;
localEntity_t *le;
refEntity_t *re;
// int fadeInTime = startTime + duration / 2;
le = CG_AllocLocalEntity();
le->leFlags = leFlags;
le->radius = radius;
re = &le->refEntity;
re->rotation = Q_random( &seed ) * 360;
re->radius = radius;
re->shaderTime = startTime / 1000.0f;
le->leType = LE_MOVE_SCALE_FADE;
le->startTime = startTime;
le->fadeInTime = fadeInTime;
le->endTime = startTime + duration;
if ( fadeInTime > startTime ) {
le->lifeRate = 1.0 / ( le->endTime - le->fadeInTime );
}
else {
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
}
le->color[0] = r;
le->color[1] = g;
le->color[2] = b;
le->color[3] = a;
le->pos.trType = TR_LINEAR;
le->pos.trTime = startTime;
VectorCopy( vel, le->pos.trDelta );
VectorCopy( p, le->pos.trBase );
VectorCopy( p, re->origin );
re->customShader = hShader;
// rage pro can't alpha fade, so use a different shader
if ( cgs.glconfig.hardwareType == GLHW_RAGEPRO ) {
re->customShader = cgs.media.smokePuffRageProShader;
re->shaderRGBA[0] = 0xff;
re->shaderRGBA[1] = 0xff;
re->shaderRGBA[2] = 0xff;
re->shaderRGBA[3] = 0xff;
} else {
re->shaderRGBA[0] = le->color[0] * 0xff;
re->shaderRGBA[1] = le->color[1] * 0xff;
re->shaderRGBA[2] = le->color[2] * 0xff;
re->shaderRGBA[3] = 0xff;
}
re->reType = RT_SPRITE;
re->radius = le->radius;
return le;
}
/*
==================
CG_SpawnEffect
Player teleporting in or out
==================
*/
void CG_SpawnEffect( vec3_t org ) {
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_FADE_RGB;
le->startTime = cg.time;
le->endTime = cg.time + 500;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
re = &le->refEntity;
re->reType = RT_MODEL;
re->shaderTime = cg.time / 1000.0f;
#ifndef MISSIONPACK
re->customShader = cgs.media.teleportEffectShader;
#endif
re->hModel = cgs.media.teleportEffectModel;
AxisClear( re->axis );
VectorCopy( org, re->origin );
#ifdef MISSIONPACK
re->origin[2] += 16;
#else
re->origin[2] -= 24;
#endif
}
#ifdef MISSIONPACK
/*
===============
CG_LightningBoltBeam
===============
*/
void CG_LightningBoltBeam( vec3_t start, vec3_t end ) {
localEntity_t *le;
refEntity_t *beam;
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_SHOWREFENTITY;
le->startTime = cg.time;
le->endTime = cg.time + 50;
beam = &le->refEntity;
VectorCopy( start, beam->origin );
// this is the end point
VectorCopy( end, beam->oldorigin );
beam->reType = RT_LIGHTNING;
beam->customShader = cgs.media.lightningShader;
}
/*
==================
CG_KamikazeEffect
==================
*/
void CG_KamikazeEffect( vec3_t org ) {
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_KAMIKAZE;
le->startTime = cg.time;
le->endTime = cg.time + 3000;//2250;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
VectorClear(le->angles.trBase);
re = &le->refEntity;
re->reType = RT_MODEL;
re->shaderTime = cg.time / 1000.0f;
re->hModel = cgs.media.kamikazeEffectModel;
VectorCopy( org, re->origin );
}
/*
==================
CG_ObeliskExplode
==================
*/
void CG_ObeliskExplode( vec3_t org, int entityNum ) {
localEntity_t *le;
vec3_t origin;
// create an explosion
VectorCopy( org, origin );
origin[2] += 64;
le = CG_MakeExplosion( origin, vec3_origin,
cgs.media.dishFlashModel,
cgs.media.rocketExplosionShader,
600, qtrue );
le->light = 300;
le->lightColor[0] = 1;
le->lightColor[1] = 0.75;
le->lightColor[2] = 0.0;
}
/*
==================
CG_ObeliskPain
==================
*/
void CG_ObeliskPain( vec3_t org ) {
float r;
sfxHandle_t sfx;
// hit sound
r = rand() & 3;
if ( r < 2 ) {
sfx = cgs.media.obeliskHitSound1;
} else if ( r == 2 ) {
sfx = cgs.media.obeliskHitSound2;
} else {
sfx = cgs.media.obeliskHitSound3;
}
trap_S_StartSound ( org, ENTITYNUM_NONE, CHAN_BODY, sfx );
}
/*
==================
CG_InvulnerabilityImpact
==================
*/
void CG_InvulnerabilityImpact( vec3_t org, vec3_t angles ) {
localEntity_t *le;
refEntity_t *re;
int r;
sfxHandle_t sfx;
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_INVULIMPACT;
le->startTime = cg.time;
le->endTime = cg.time + 1000;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
re = &le->refEntity;
re->reType = RT_MODEL;
re->shaderTime = cg.time / 1000.0f;
re->hModel = cgs.media.invulnerabilityImpactModel;
VectorCopy( org, re->origin );
AnglesToAxis( angles, re->axis );
r = rand() & 3;
if ( r < 2 ) {
sfx = cgs.media.invulnerabilityImpactSound1;
} else if ( r == 2 ) {
sfx = cgs.media.invulnerabilityImpactSound2;
} else {
sfx = cgs.media.invulnerabilityImpactSound3;
}
trap_S_StartSound (org, ENTITYNUM_NONE, CHAN_BODY, sfx );
}
/*
==================
CG_InvulnerabilityJuiced
==================
*/
void CG_InvulnerabilityJuiced( vec3_t org ) {
localEntity_t *le;
refEntity_t *re;
vec3_t angles;
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_INVULJUICED;
le->startTime = cg.time;
le->endTime = cg.time + 10000;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
re = &le->refEntity;
re->reType = RT_MODEL;
re->shaderTime = cg.time / 1000.0f;
re->hModel = cgs.media.invulnerabilityJuicedModel;
VectorCopy( org, re->origin );
VectorClear(angles);
AnglesToAxis( angles, re->axis );
trap_S_StartSound (org, ENTITYNUM_NONE, CHAN_BODY, cgs.media.invulnerabilityJuicedSound );
}
#endif
/*
==================
CG_ScorePlum
==================
*/
void CG_ScorePlum( int client, vec3_t org, int score ) {
localEntity_t *le;
refEntity_t *re;
vec3_t angles;
static vec3_t lastPos;
// only visualize for the client that scored
if (client != cg.predictedPlayerState.clientNum || cg_scorePlum.integer == 0) {
return;
}
le = CG_AllocLocalEntity();
le->leFlags = 0;
le->leType = LE_SCOREPLUM;
le->startTime = cg.time;
le->endTime = cg.time + 4000;
le->lifeRate = 1.0 / ( le->endTime - le->startTime );
le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0;
le->radius = score;
VectorCopy( org, le->pos.trBase );
if (org[2] >= lastPos[2] - 20 && org[2] <= lastPos[2] + 20) {
le->pos.trBase[2] -= 20;
}
//CG_Printf( "Plum origin %i %i %i -- %i\n", (int)org[0], (int)org[1], (int)org[2], (int)Distance(org, lastPos));
VectorCopy(org, lastPos);
re = &le->refEntity;
re->reType = RT_SPRITE;
re->radius = 16;
VectorClear(angles);
AnglesToAxis( angles, re->axis );
}
/*
====================
CG_MakeExplosion
====================
*/
localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
qhandle_t hModel, qhandle_t shader,
int msec, qboolean isSprite ) {
float ang;
localEntity_t *ex;
int offset;
vec3_t tmpVec, newOrigin;
if ( msec <= 0 ) {
CG_Error( "CG_MakeExplosion: msec = %i", msec );
}
// skew the time a bit so they aren't all in sync
offset = rand() & 63;
ex = CG_AllocLocalEntity();
if ( isSprite ) {
ex->leType = LE_SPRITE_EXPLOSION;
// randomly rotate sprite orientation
ex->refEntity.rotation = rand() % 360;
VectorScale( dir, 16, tmpVec );
VectorAdd( tmpVec, origin, newOrigin );
} else {
ex->leType = LE_EXPLOSION;
VectorCopy( origin, newOrigin );
// set axis with random rotate
if ( !dir ) {
AxisClear( ex->refEntity.axis );
} else {
ang = rand() % 360;
VectorCopy( dir, ex->refEntity.axis[0] );
RotateAroundDirection( ex->refEntity.axis, ang );
}
}
ex->startTime = cg.time - offset;
ex->endTime = ex->startTime + msec;
// bias the time so all shader effects start correctly
ex->refEntity.shaderTime = ex->startTime / 1000.0f;
ex->refEntity.hModel = hModel;
ex->refEntity.customShader = shader;
// set origin
VectorCopy( newOrigin, ex->refEntity.origin );
VectorCopy( newOrigin, ex->refEntity.oldorigin );
ex->color[0] = ex->color[1] = ex->color[2] = 1.0;
return ex;
}
/*
=================
CG_Bleed
This is the spurt of blood when a character gets hit
=================
*/
void CG_Bleed( vec3_t origin, int entityNum ) {
localEntity_t *ex;
if ( !cg_blood.integer ) {
return;
}
ex = CG_AllocLocalEntity();
ex->leType = LE_EXPLOSION;
ex->startTime = cg.time;
ex->endTime = ex->startTime + 500;
VectorCopy ( origin, ex->refEntity.origin);
ex->refEntity.reType = RT_SPRITE;
ex->refEntity.rotation = rand() % 360;
ex->refEntity.radius = 24;
ex->refEntity.customShader = cgs.media.bloodExplosionShader;
// don't show player's own blood in view
if ( entityNum == cg.snap->ps.clientNum ) {
ex->refEntity.renderfx |= RF_THIRD_PERSON;
}
}
/*
==================
CG_LaunchGib
==================
*/
void CG_LaunchGib( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
re = &le->refEntity;
le->leType = LE_FRAGMENT;
le->startTime = cg.time;
le->endTime = le->startTime + 5000 + random() * 3000;
VectorCopy( origin, re->origin );
AxisCopy( axisDefault, re->axis );
re->hModel = hModel;
le->pos.trType = TR_GRAVITY;
VectorCopy( origin, le->pos.trBase );
VectorCopy( velocity, le->pos.trDelta );
le->pos.trTime = cg.time;
le->bounceFactor = 0.6f;
le->leBounceSoundType = LEBS_BLOOD;
le->leMarkType = LEMT_BLOOD;
}
/*
===================
CG_GibPlayer
Generated a bunch of gibs launching out from the bodies location
===================
*/
#define GIB_VELOCITY 250
#define GIB_JUMP 250
void CG_GibPlayer( vec3_t playerOrigin ) {
vec3_t origin, velocity;
if ( !cg_blood.integer ) {
return;
}
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
if ( rand() & 1 ) {
CG_LaunchGib( origin, velocity, cgs.media.gibSkull );
} else {
CG_LaunchGib( origin, velocity, cgs.media.gibBrain );
}
// allow gibs to be turned off for speed
if ( !cg_gibs.integer ) {
return;
}
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibAbdomen );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibArm );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibChest );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibFist );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibFoot );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibForearm );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibIntestine );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibLeg );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*GIB_VELOCITY;
velocity[1] = crandom()*GIB_VELOCITY;
velocity[2] = GIB_JUMP + crandom()*GIB_VELOCITY;
CG_LaunchGib( origin, velocity, cgs.media.gibLeg );
}
/*
==================
CG_LaunchGib
==================
*/
void CG_LaunchExplode( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
localEntity_t *le;
refEntity_t *re;
le = CG_AllocLocalEntity();
re = &le->refEntity;
le->leType = LE_FRAGMENT;
le->startTime = cg.time;
le->endTime = le->startTime + 10000 + random() * 6000;
VectorCopy( origin, re->origin );
AxisCopy( axisDefault, re->axis );
re->hModel = hModel;
le->pos.trType = TR_GRAVITY;
VectorCopy( origin, le->pos.trBase );
VectorCopy( velocity, le->pos.trDelta );
le->pos.trTime = cg.time;
le->bounceFactor = 0.1f;
le->leBounceSoundType = LEBS_BRASS;
le->leMarkType = LEMT_NONE;
}
#define EXP_VELOCITY 100
#define EXP_JUMP 150
/*
===================
CG_GibPlayer
Generated a bunch of gibs launching out from the bodies location
===================
*/
void CG_BigExplode( vec3_t playerOrigin ) {
vec3_t origin, velocity;
if ( !cg_blood.integer ) {
return;
}
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY;
velocity[1] = crandom()*EXP_VELOCITY;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY;
velocity[1] = crandom()*EXP_VELOCITY;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY*1.5;
velocity[1] = crandom()*EXP_VELOCITY*1.5;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY*2.0;
velocity[1] = crandom()*EXP_VELOCITY*2.0;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
VectorCopy( playerOrigin, origin );
velocity[0] = crandom()*EXP_VELOCITY*2.5;
velocity[1] = crandom()*EXP_VELOCITY*2.5;
velocity[2] = EXP_JUMP + crandom()*EXP_VELOCITY;
CG_LaunchExplode( origin, velocity, cgs.media.smoke2 );
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,277 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_info.c -- display information while data is being loading
#include "cg_local.h"
#define MAX_LOADING_PLAYER_ICONS 16
#define MAX_LOADING_ITEM_ICONS 26
static int loadingPlayerIconCount;
static int loadingItemIconCount;
static qhandle_t loadingPlayerIcons[MAX_LOADING_PLAYER_ICONS];
static qhandle_t loadingItemIcons[MAX_LOADING_ITEM_ICONS];
/*
===================
CG_DrawLoadingIcons
===================
*/
static void CG_DrawLoadingIcons( void ) {
int n;
int x, y;
for( n = 0; n < loadingPlayerIconCount; n++ ) {
x = 16 + n * 78;
y = 324-40;
CG_DrawPic( x, y, 64, 64, loadingPlayerIcons[n] );
}
for( n = 0; n < loadingItemIconCount; n++ ) {
y = 400-40;
if( n >= 13 ) {
y += 40;
}
x = 16 + n % 13 * 48;
CG_DrawPic( x, y, 32, 32, loadingItemIcons[n] );
}
}
/*
======================
CG_LoadingString
======================
*/
void CG_LoadingString( const char *s ) {
Q_strncpyz( cg.infoScreenText, s, sizeof( cg.infoScreenText ) );
trap_UpdateScreen();
}
/*
===================
CG_LoadingItem
===================
*/
void CG_LoadingItem( int itemNum ) {
gitem_t *item;
item = &bg_itemlist[itemNum];
if ( item->icon && loadingItemIconCount < MAX_LOADING_ITEM_ICONS ) {
loadingItemIcons[loadingItemIconCount++] = trap_R_RegisterShaderNoMip( item->icon );
}
CG_LoadingString( item->pickup_name );
}
/*
===================
CG_LoadingClient
===================
*/
void CG_LoadingClient( int clientNum ) {
const char *info;
char *skin;
char personality[MAX_QPATH];
char model[MAX_QPATH];
char iconName[MAX_QPATH];
info = CG_ConfigString( CS_PLAYERS + clientNum );
if ( loadingPlayerIconCount < MAX_LOADING_PLAYER_ICONS ) {
Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) );
skin = Q_strrchr( model, '/' );
if ( skin ) {
*skin++ = '\0';
} else {
skin = "default";
}
Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", model, skin );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
Com_sprintf( iconName, MAX_QPATH, "models/players/characters/%s/icon_%s.tga", model, skin );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
}
if ( !loadingPlayerIcons[loadingPlayerIconCount] ) {
Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", DEFAULT_MODEL, "default" );
loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName );
}
if ( loadingPlayerIcons[loadingPlayerIconCount] ) {
loadingPlayerIconCount++;
}
}
Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) );
Q_CleanStr( personality );
if( cgs.gametype == GT_SINGLE_PLAYER ) {
trap_S_RegisterSound( va( "sound/player/announce/%s.wav", personality ), qtrue );
}
CG_LoadingString( personality );
}
/*
====================
CG_DrawInformation
Draw all the status / pacifier stuff during level loading
====================
*/
void CG_DrawInformation( void ) {
const char *s;
const char *info;
const char *sysInfo;
int y;
int value;
qhandle_t levelshot;
qhandle_t detail;
char buf[1024];
info = CG_ConfigString( CS_SERVERINFO );
sysInfo = CG_ConfigString( CS_SYSTEMINFO );
s = Info_ValueForKey( info, "mapname" );
levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s.tga", s ) );
if ( !levelshot ) {
levelshot = trap_R_RegisterShaderNoMip( "menu/art/unknownmap" );
}
trap_R_SetColor( NULL );
CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot );
// blend a detail texture over it
detail = trap_R_RegisterShader( "levelShotDetail" );
trap_R_DrawStretchPic( 0, 0, cgs.glconfig.vidWidth, cgs.glconfig.vidHeight, 0, 0, 2.5, 2, detail );
// draw the icons of things as they are loaded
CG_DrawLoadingIcons();
// the first 150 rows are reserved for the client connection
// screen to write into
if ( cg.infoScreenText[0] ) {
UI_DrawProportionalString( 320, 128-32, va("Loading... %s", cg.infoScreenText),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
} else {
UI_DrawProportionalString( 320, 128-32, "Awaiting snapshot...",
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
}
// draw info string information
y = 180-32;
// don't print server lines if playing a local game
trap_Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) );
if ( !atoi( buf ) ) {
// server hostname
Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), 1024);
Q_CleanStr(buf);
UI_DrawProportionalString( 320, y, buf,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
// pure server
s = Info_ValueForKey( sysInfo, "sv_pure" );
if ( s[0] == '1' ) {
UI_DrawProportionalString( 320, y, "Pure Server",
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
}
// server-specific message of the day
s = CG_ConfigString( CS_MOTD );
if ( s[0] ) {
UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
}
// some extra space after hostname and motd
y += 10;
}
// map-specific message (long map name)
s = CG_ConfigString( CS_MESSAGE );
if ( s[0] ) {
UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
}
// cheats warning
s = Info_ValueForKey( sysInfo, "sv_cheats" );
if ( s[0] == '1' ) {
UI_DrawProportionalString( 320, y, "CHEATS ARE ENABLED",
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
}
// game type
switch ( cgs.gametype ) {
case GT_FFA:
s = "Free For All";
break;
case GT_SINGLE_PLAYER:
s = "Single Player";
break;
case GT_TOURNAMENT:
s = "Tournament";
break;
case GT_TEAM:
s = "Team Deathmatch";
break;
case GT_CTF:
s = "Capture The Flag";
break;
#ifdef MISSIONPACK
case GT_1FCTF:
s = "One Flag CTF";
break;
case GT_OBELISK:
s = "Overload";
break;
case GT_HARVESTER:
s = "Harvester";
break;
#endif
default:
s = "Unknown Gametype";
break;
}
UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
value = atoi( Info_ValueForKey( info, "timelimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "timelimit %i", value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
}
if (cgs.gametype < GT_CTF ) {
value = atoi( Info_ValueForKey( info, "fraglimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "fraglimit %i", value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
}
}
if (cgs.gametype >= GT_CTF) {
value = atoi( Info_ValueForKey( info, "capturelimit" ) );
if ( value ) {
UI_DrawProportionalString( 320, y, va( "capturelimit %i", value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,866 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_localents.c -- every frame, generate renderer commands for locally
// processed entities, like smoke puffs, gibs, shells, etc.
#include "cg_local.h"
#define MAX_LOCAL_ENTITIES 512
localEntity_t cg_localEntities[MAX_LOCAL_ENTITIES];
localEntity_t cg_activeLocalEntities; // double linked list
localEntity_t *cg_freeLocalEntities; // single linked list
/*
===================
CG_InitLocalEntities
This is called at startup and for tournement restarts
===================
*/
void CG_InitLocalEntities( void ) {
int i;
memset( cg_localEntities, 0, sizeof( cg_localEntities ) );
cg_activeLocalEntities.next = &cg_activeLocalEntities;
cg_activeLocalEntities.prev = &cg_activeLocalEntities;
cg_freeLocalEntities = cg_localEntities;
for ( i = 0 ; i < MAX_LOCAL_ENTITIES - 1 ; i++ ) {
cg_localEntities[i].next = &cg_localEntities[i+1];
}
}
/*
==================
CG_FreeLocalEntity
==================
*/
void CG_FreeLocalEntity( localEntity_t *le ) {
if ( !le->prev ) {
CG_Error( "CG_FreeLocalEntity: not active" );
}
// remove from the doubly linked active list
le->prev->next = le->next;
le->next->prev = le->prev;
// the free list is only singly linked
le->next = cg_freeLocalEntities;
cg_freeLocalEntities = le;
}
/*
===================
CG_AllocLocalEntity
Will allways succeed, even if it requires freeing an old active entity
===================
*/
localEntity_t *CG_AllocLocalEntity( void ) {
localEntity_t *le;
if ( !cg_freeLocalEntities ) {
// no free entities, so free the one at the end of the chain
// remove the oldest active entity
CG_FreeLocalEntity( cg_activeLocalEntities.prev );
}
le = cg_freeLocalEntities;
cg_freeLocalEntities = cg_freeLocalEntities->next;
memset( le, 0, sizeof( *le ) );
// link into the active list
le->next = cg_activeLocalEntities.next;
le->prev = &cg_activeLocalEntities;
cg_activeLocalEntities.next->prev = le;
cg_activeLocalEntities.next = le;
return le;
}
/*
====================================================================================
FRAGMENT PROCESSING
A fragment localentity interacts with the environment in some way (hitting walls),
or generates more localentities along a trail.
====================================================================================
*/
/*
================
CG_BloodTrail
Leave expanding blood puffs behind gibs
================
*/
void CG_BloodTrail( localEntity_t *le ) {
int t;
int t2;
int step;
vec3_t newOrigin;
localEntity_t *blood;
step = 150;
t = step * ( (cg.time - cg.frametime + step ) / step );
t2 = step * ( cg.time / step );
for ( ; t <= t2; t += step ) {
BG_EvaluateTrajectory( &le->pos, t, newOrigin );
blood = CG_SmokePuff( newOrigin, vec3_origin,
20, // radius
1, 1, 1, 1, // color
2000, // trailTime
t, // startTime
0, // fadeInTime
0, // flags
cgs.media.bloodTrailShader );
// use the optimized version
blood->leType = LE_FALL_SCALE_FADE;
// drop a total of 40 units over its lifetime
blood->pos.trDelta[2] = 40;
}
}
/*
================
CG_FragmentBounceMark
================
*/
void CG_FragmentBounceMark( localEntity_t *le, trace_t *trace ) {
int radius;
if ( le->leMarkType == LEMT_BLOOD ) {
radius = 16 + (rand()&31);
CG_ImpactMark( cgs.media.bloodMarkShader, trace->endpos, trace->plane.normal, random()*360,
1,1,1,1, qtrue, radius, qfalse );
} else if ( le->leMarkType == LEMT_BURN ) {
radius = 8 + (rand()&15);
CG_ImpactMark( cgs.media.burnMarkShader, trace->endpos, trace->plane.normal, random()*360,
1,1,1,1, qtrue, radius, qfalse );
}
// don't allow a fragment to make multiple marks, or they
// pile up while settling
le->leMarkType = LEMT_NONE;
}
/*
================
CG_FragmentBounceSound
================
*/
void CG_FragmentBounceSound( localEntity_t *le, trace_t *trace ) {
if ( le->leBounceSoundType == LEBS_BLOOD ) {
// half the gibs will make splat sounds
if ( rand() & 1 ) {
int r = rand()&3;
sfxHandle_t s;
if ( r == 0 ) {
s = cgs.media.gibBounce1Sound;
} else if ( r == 1 ) {
s = cgs.media.gibBounce2Sound;
} else {
s = cgs.media.gibBounce3Sound;
}
trap_S_StartSound( trace->endpos, ENTITYNUM_WORLD, CHAN_AUTO, s );
}
} else if ( le->leBounceSoundType == LEBS_BRASS ) {
}
// don't allow a fragment to make multiple bounce sounds,
// or it gets too noisy as they settle
le->leBounceSoundType = LEBS_NONE;
}
/*
================
CG_ReflectVelocity
================
*/
void CG_ReflectVelocity( localEntity_t *le, trace_t *trace ) {
vec3_t velocity;
float dot;
int hitTime;
// reflect the velocity on the trace plane
hitTime = cg.time - cg.frametime + cg.frametime * trace->fraction;
BG_EvaluateTrajectoryDelta( &le->pos, hitTime, velocity );
dot = DotProduct( velocity, trace->plane.normal );
VectorMA( velocity, -2*dot, trace->plane.normal, le->pos.trDelta );
VectorScale( le->pos.trDelta, le->bounceFactor, le->pos.trDelta );
VectorCopy( trace->endpos, le->pos.trBase );
le->pos.trTime = cg.time;
// check for stop, making sure that even on low FPS systems it doesn't bobble
if ( trace->allsolid ||
( trace->plane.normal[2] > 0 &&
( le->pos.trDelta[2] < 40 || le->pos.trDelta[2] < -cg.frametime * le->pos.trDelta[2] ) ) ) {
le->pos.trType = TR_STATIONARY;
} else {
}
}
/*
================
CG_AddFragment
================
*/
void CG_AddFragment( localEntity_t *le ) {
vec3_t newOrigin;
trace_t trace;
if ( le->pos.trType == TR_STATIONARY ) {
// sink into the ground if near the removal time
int t;
float oldZ;
t = le->endTime - cg.time;
if ( t < SINK_TIME ) {
// we must use an explicit lighting origin, otherwise the
// lighting would be lost as soon as the origin went
// into the ground
VectorCopy( le->refEntity.origin, le->refEntity.lightingOrigin );
le->refEntity.renderfx |= RF_LIGHTING_ORIGIN;
oldZ = le->refEntity.origin[2];
le->refEntity.origin[2] -= 16 * ( 1.0 - (float)t / SINK_TIME );
trap_R_AddRefEntityToScene( &le->refEntity );
le->refEntity.origin[2] = oldZ;
} else {
trap_R_AddRefEntityToScene( &le->refEntity );
}
return;
}
// calculate new position
BG_EvaluateTrajectory( &le->pos, cg.time, newOrigin );
// trace a line from previous position to new position
CG_Trace( &trace, le->refEntity.origin, NULL, NULL, newOrigin, -1, CONTENTS_SOLID );
if ( trace.fraction == 1.0 ) {
// still in free fall
VectorCopy( newOrigin, le->refEntity.origin );
if ( le->leFlags & LEF_TUMBLE ) {
vec3_t angles;
BG_EvaluateTrajectory( &le->angles, cg.time, angles );
AnglesToAxis( angles, le->refEntity.axis );
}
trap_R_AddRefEntityToScene( &le->refEntity );
// add a blood trail
if ( le->leBounceSoundType == LEBS_BLOOD ) {
CG_BloodTrail( le );
}
return;
}
// if it is in a nodrop zone, remove it
// this keeps gibs from waiting at the bottom of pits of death
// and floating levels
if ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP ) {
CG_FreeLocalEntity( le );
return;
}
// leave a mark
CG_FragmentBounceMark( le, &trace );
// do a bouncy sound
CG_FragmentBounceSound( le, &trace );
// reflect the velocity on the trace plane
CG_ReflectVelocity( le, &trace );
trap_R_AddRefEntityToScene( &le->refEntity );
}
/*
=====================================================================
TRIVIAL LOCAL ENTITIES
These only do simple scaling or modulation before passing to the renderer
=====================================================================
*/
/*
====================
CG_AddFadeRGB
====================
*/
void CG_AddFadeRGB( localEntity_t *le ) {
refEntity_t *re;
float c;
re = &le->refEntity;
c = ( le->endTime - cg.time ) * le->lifeRate;
c *= 0xff;
re->shaderRGBA[0] = le->color[0] * c;
re->shaderRGBA[1] = le->color[1] * c;
re->shaderRGBA[2] = le->color[2] * c;
re->shaderRGBA[3] = le->color[3] * c;
trap_R_AddRefEntityToScene( re );
}
/*
==================
CG_AddMoveScaleFade
==================
*/
static void CG_AddMoveScaleFade( localEntity_t *le ) {
refEntity_t *re;
float c;
vec3_t delta;
float len;
re = &le->refEntity;
if ( le->fadeInTime > le->startTime && cg.time < le->fadeInTime ) {
// fade / grow time
c = 1.0 - (float) ( le->fadeInTime - cg.time ) / ( le->fadeInTime - le->startTime );
}
else {
// fade / grow time
c = ( le->endTime - cg.time ) * le->lifeRate;
}
re->shaderRGBA[3] = 0xff * c * le->color[3];
if ( !( le->leFlags & LEF_PUFF_DONT_SCALE ) ) {
re->radius = le->radius * ( 1.0 - c ) + 8;
}
BG_EvaluateTrajectory( &le->pos, cg.time, re->origin );
// if the view would be "inside" the sprite, kill the sprite
// so it doesn't add too much overdraw
VectorSubtract( re->origin, cg.refdef.vieworg, delta );
len = VectorLength( delta );
if ( len < le->radius ) {
CG_FreeLocalEntity( le );
return;
}
trap_R_AddRefEntityToScene( re );
}
/*
===================
CG_AddScaleFade
For rocket smokes that hang in place, fade out, and are
removed if the view passes through them.
There are often many of these, so it needs to be simple.
===================
*/
static void CG_AddScaleFade( localEntity_t *le ) {
refEntity_t *re;
float c;
vec3_t delta;
float len;
re = &le->refEntity;
// fade / grow time
c = ( le->endTime - cg.time ) * le->lifeRate;
re->shaderRGBA[3] = 0xff * c * le->color[3];
re->radius = le->radius * ( 1.0 - c ) + 8;
// if the view would be "inside" the sprite, kill the sprite
// so it doesn't add too much overdraw
VectorSubtract( re->origin, cg.refdef.vieworg, delta );
len = VectorLength( delta );
if ( len < le->radius ) {
CG_FreeLocalEntity( le );
return;
}
trap_R_AddRefEntityToScene( re );
}
/*
=================
CG_AddFallScaleFade
This is just an optimized CG_AddMoveScaleFade
For blood mists that drift down, fade out, and are
removed if the view passes through them.
There are often 100+ of these, so it needs to be simple.
=================
*/
static void CG_AddFallScaleFade( localEntity_t *le ) {
refEntity_t *re;
float c;
vec3_t delta;
float len;
re = &le->refEntity;
// fade time
c = ( le->endTime - cg.time ) * le->lifeRate;
re->shaderRGBA[3] = 0xff * c * le->color[3];
re->origin[2] = le->pos.trBase[2] - ( 1.0 - c ) * le->pos.trDelta[2];
re->radius = le->radius * ( 1.0 - c ) + 16;
// if the view would be "inside" the sprite, kill the sprite
// so it doesn't add too much overdraw
VectorSubtract( re->origin, cg.refdef.vieworg, delta );
len = VectorLength( delta );
if ( len < le->radius ) {
CG_FreeLocalEntity( le );
return;
}
trap_R_AddRefEntityToScene( re );
}
/*
================
CG_AddExplosion
================
*/
static void CG_AddExplosion( localEntity_t *ex ) {
refEntity_t *ent;
ent = &ex->refEntity;
// add the entity
trap_R_AddRefEntityToScene(ent);
// add the dlight
if ( ex->light ) {
float light;
light = (float)( cg.time - ex->startTime ) / ( ex->endTime - ex->startTime );
if ( light < 0.5 ) {
light = 1.0;
} else {
light = 1.0 - ( light - 0.5 ) * 2;
}
light = ex->light * light;
trap_R_AddLightToScene(ent->origin, light, ex->lightColor[0], ex->lightColor[1], ex->lightColor[2] );
}
}
/*
================
CG_AddSpriteExplosion
================
*/
static void CG_AddSpriteExplosion( localEntity_t *le ) {
refEntity_t re;
float c;
re = le->refEntity;
c = ( le->endTime - cg.time ) / ( float ) ( le->endTime - le->startTime );
if ( c > 1 ) {
c = 1.0; // can happen during connection problems
}
re.shaderRGBA[0] = 0xff;
re.shaderRGBA[1] = 0xff;
re.shaderRGBA[2] = 0xff;
re.shaderRGBA[3] = 0xff * c * 0.33;
re.reType = RT_SPRITE;
re.radius = 42 * ( 1.0 - c ) + 30;
trap_R_AddRefEntityToScene( &re );
// add the dlight
if ( le->light ) {
float light;
light = (float)( cg.time - le->startTime ) / ( le->endTime - le->startTime );
if ( light < 0.5 ) {
light = 1.0;
} else {
light = 1.0 - ( light - 0.5 ) * 2;
}
light = le->light * light;
trap_R_AddLightToScene(re.origin, light, le->lightColor[0], le->lightColor[1], le->lightColor[2] );
}
}
#ifdef MISSIONPACK
/*
====================
CG_AddKamikaze
====================
*/
void CG_AddKamikaze( localEntity_t *le ) {
refEntity_t *re;
refEntity_t shockwave;
float c;
vec3_t test, axis[3];
int t;
re = &le->refEntity;
t = cg.time - le->startTime;
VectorClear( test );
AnglesToAxis( test, axis );
if (t > KAMI_SHOCKWAVE_STARTTIME && t < KAMI_SHOCKWAVE_ENDTIME) {
if (!(le->leFlags & LEF_SOUND1)) {
// trap_S_StartSound (re->origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.kamikazeExplodeSound );
trap_S_StartLocalSound(cgs.media.kamikazeExplodeSound, CHAN_AUTO);
le->leFlags |= LEF_SOUND1;
}
// 1st kamikaze shockwave
memset(&shockwave, 0, sizeof(shockwave));
shockwave.hModel = cgs.media.kamikazeShockWave;
shockwave.reType = RT_MODEL;
shockwave.shaderTime = re->shaderTime;
VectorCopy(re->origin, shockwave.origin);
c = (float)(t - KAMI_SHOCKWAVE_STARTTIME) / (float)(KAMI_SHOCKWAVE_ENDTIME - KAMI_SHOCKWAVE_STARTTIME);
VectorScale( axis[0], c * KAMI_SHOCKWAVE_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[0] );
VectorScale( axis[1], c * KAMI_SHOCKWAVE_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[1] );
VectorScale( axis[2], c * KAMI_SHOCKWAVE_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[2] );
shockwave.nonNormalizedAxes = qtrue;
if (t > KAMI_SHOCKWAVEFADE_STARTTIME) {
c = (float)(t - KAMI_SHOCKWAVEFADE_STARTTIME) / (float)(KAMI_SHOCKWAVE_ENDTIME - KAMI_SHOCKWAVEFADE_STARTTIME);
}
else {
c = 0;
}
c *= 0xff;
shockwave.shaderRGBA[0] = 0xff - c;
shockwave.shaderRGBA[1] = 0xff - c;
shockwave.shaderRGBA[2] = 0xff - c;
shockwave.shaderRGBA[3] = 0xff - c;
trap_R_AddRefEntityToScene( &shockwave );
}
if (t > KAMI_EXPLODE_STARTTIME && t < KAMI_IMPLODE_ENDTIME) {
// explosion and implosion
c = ( le->endTime - cg.time ) * le->lifeRate;
c *= 0xff;
re->shaderRGBA[0] = le->color[0] * c;
re->shaderRGBA[1] = le->color[1] * c;
re->shaderRGBA[2] = le->color[2] * c;
re->shaderRGBA[3] = le->color[3] * c;
if( t < KAMI_IMPLODE_STARTTIME ) {
c = (float)(t - KAMI_EXPLODE_STARTTIME) / (float)(KAMI_IMPLODE_STARTTIME - KAMI_EXPLODE_STARTTIME);
}
else {
if (!(le->leFlags & LEF_SOUND2)) {
// trap_S_StartSound (re->origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.kamikazeImplodeSound );
trap_S_StartLocalSound(cgs.media.kamikazeImplodeSound, CHAN_AUTO);
le->leFlags |= LEF_SOUND2;
}
c = (float)(KAMI_IMPLODE_ENDTIME - t) / (float) (KAMI_IMPLODE_ENDTIME - KAMI_IMPLODE_STARTTIME);
}
VectorScale( axis[0], c * KAMI_BOOMSPHERE_MAXRADIUS / KAMI_BOOMSPHEREMODEL_RADIUS, re->axis[0] );
VectorScale( axis[1], c * KAMI_BOOMSPHERE_MAXRADIUS / KAMI_BOOMSPHEREMODEL_RADIUS, re->axis[1] );
VectorScale( axis[2], c * KAMI_BOOMSPHERE_MAXRADIUS / KAMI_BOOMSPHEREMODEL_RADIUS, re->axis[2] );
re->nonNormalizedAxes = qtrue;
trap_R_AddRefEntityToScene( re );
// add the dlight
trap_R_AddLightToScene( re->origin, c * 1000.0, 1.0, 1.0, c );
}
if (t > KAMI_SHOCKWAVE2_STARTTIME && t < KAMI_SHOCKWAVE2_ENDTIME) {
// 2nd kamikaze shockwave
if (le->angles.trBase[0] == 0 &&
le->angles.trBase[1] == 0 &&
le->angles.trBase[2] == 0) {
le->angles.trBase[0] = random() * 360;
le->angles.trBase[1] = random() * 360;
le->angles.trBase[2] = random() * 360;
}
else {
c = 0;
}
memset(&shockwave, 0, sizeof(shockwave));
shockwave.hModel = cgs.media.kamikazeShockWave;
shockwave.reType = RT_MODEL;
shockwave.shaderTime = re->shaderTime;
VectorCopy(re->origin, shockwave.origin);
test[0] = le->angles.trBase[0];
test[1] = le->angles.trBase[1];
test[2] = le->angles.trBase[2];
AnglesToAxis( test, axis );
c = (float)(t - KAMI_SHOCKWAVE2_STARTTIME) / (float)(KAMI_SHOCKWAVE2_ENDTIME - KAMI_SHOCKWAVE2_STARTTIME);
VectorScale( axis[0], c * KAMI_SHOCKWAVE2_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[0] );
VectorScale( axis[1], c * KAMI_SHOCKWAVE2_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[1] );
VectorScale( axis[2], c * KAMI_SHOCKWAVE2_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[2] );
shockwave.nonNormalizedAxes = qtrue;
if (t > KAMI_SHOCKWAVE2FADE_STARTTIME) {
c = (float)(t - KAMI_SHOCKWAVE2FADE_STARTTIME) / (float)(KAMI_SHOCKWAVE2_ENDTIME - KAMI_SHOCKWAVE2FADE_STARTTIME);
}
else {
c = 0;
}
c *= 0xff;
shockwave.shaderRGBA[0] = 0xff - c;
shockwave.shaderRGBA[1] = 0xff - c;
shockwave.shaderRGBA[2] = 0xff - c;
shockwave.shaderRGBA[3] = 0xff - c;
trap_R_AddRefEntityToScene( &shockwave );
}
}
/*
===================
CG_AddInvulnerabilityImpact
===================
*/
void CG_AddInvulnerabilityImpact( localEntity_t *le ) {
trap_R_AddRefEntityToScene( &le->refEntity );
}
/*
===================
CG_AddInvulnerabilityJuiced
===================
*/
void CG_AddInvulnerabilityJuiced( localEntity_t *le ) {
int t;
t = cg.time - le->startTime;
if ( t > 3000 ) {
le->refEntity.axis[0][0] = (float) 1.0 + 0.3 * (t - 3000) / 2000;
le->refEntity.axis[1][1] = (float) 1.0 + 0.3 * (t - 3000) / 2000;
le->refEntity.axis[2][2] = (float) 0.7 + 0.3 * (2000 - (t - 3000)) / 2000;
}
if ( t > 5000 ) {
le->endTime = 0;
CG_GibPlayer( le->refEntity.origin );
}
else {
trap_R_AddRefEntityToScene( &le->refEntity );
}
}
/*
===================
CG_AddRefEntity
===================
*/
void CG_AddRefEntity( localEntity_t *le ) {
if (le->endTime < cg.time) {
CG_FreeLocalEntity( le );
return;
}
trap_R_AddRefEntityToScene( &le->refEntity );
}
#endif
/*
===================
CG_AddScorePlum
===================
*/
#define NUMBER_SIZE 8
void CG_AddScorePlum( localEntity_t *le ) {
refEntity_t *re;
vec3_t origin, delta, dir, vec, up = {0, 0, 1};
float c, len;
int i, score, digits[10], numdigits, negative;
re = &le->refEntity;
c = ( le->endTime - cg.time ) * le->lifeRate;
score = le->radius;
if (score < 0) {
re->shaderRGBA[0] = 0xff;
re->shaderRGBA[1] = 0x11;
re->shaderRGBA[2] = 0x11;
}
else {
re->shaderRGBA[0] = 0xff;
re->shaderRGBA[1] = 0xff;
re->shaderRGBA[2] = 0xff;
if (score >= 50) {
re->shaderRGBA[1] = 0;
} else if (score >= 20) {
re->shaderRGBA[0] = re->shaderRGBA[1] = 0;
} else if (score >= 10) {
re->shaderRGBA[2] = 0;
} else if (score >= 2) {
re->shaderRGBA[0] = re->shaderRGBA[2] = 0;
}
}
if (c < 0.25)
re->shaderRGBA[3] = 0xff * 4 * c;
else
re->shaderRGBA[3] = 0xff;
re->radius = NUMBER_SIZE / 2;
VectorCopy(le->pos.trBase, origin);
origin[2] += 110 - c * 100;
VectorSubtract(cg.refdef.vieworg, origin, dir);
CrossProduct(dir, up, vec);
VectorNormalize(vec);
VectorMA(origin, -10 + 20 * sin(c * 2 * M_PI), vec, origin);
// if the view would be "inside" the sprite, kill the sprite
// so it doesn't add too much overdraw
VectorSubtract( origin, cg.refdef.vieworg, delta );
len = VectorLength( delta );
if ( len < 20 ) {
CG_FreeLocalEntity( le );
return;
}
negative = qfalse;
if (score < 0) {
negative = qtrue;
score = -score;
}
for (numdigits = 0; !(numdigits && !score); numdigits++) {
digits[numdigits] = score % 10;
score = score / 10;
}
if (negative) {
digits[numdigits] = 10;
numdigits++;
}
for (i = 0; i < numdigits; i++) {
VectorMA(origin, (float) (((float) numdigits / 2) - i) * NUMBER_SIZE, vec, re->origin);
re->customShader = cgs.media.numberShaders[digits[numdigits-1-i]];
trap_R_AddRefEntityToScene( re );
}
}
//==============================================================================
/*
===================
CG_AddLocalEntities
===================
*/
void CG_AddLocalEntities( void ) {
localEntity_t *le, *next;
// walk the list backwards, so any new local entities generated
// (trails, marks, etc) will be present this frame
le = cg_activeLocalEntities.prev;
for ( ; le != &cg_activeLocalEntities ; le = next ) {
// grab next now, so if the local entity is freed we
// still have it
next = le->prev;
if ( cg.time >= le->endTime ) {
CG_FreeLocalEntity( le );
continue;
}
switch ( le->leType ) {
default:
CG_Error( "Bad leType: %i", le->leType );
break;
case LE_MARK:
break;
case LE_SPRITE_EXPLOSION:
CG_AddSpriteExplosion( le );
break;
case LE_EXPLOSION:
CG_AddExplosion( le );
break;
case LE_FRAGMENT: // gibs and brass
CG_AddFragment( le );
break;
case LE_MOVE_SCALE_FADE: // water bubbles
CG_AddMoveScaleFade( le );
break;
case LE_FADE_RGB: // teleporters, railtrails
CG_AddFadeRGB( le );
break;
case LE_FALL_SCALE_FADE: // gib blood trails
CG_AddFallScaleFade( le );
break;
case LE_SCALE_FADE: // rocket trails
CG_AddScaleFade( le );
break;
case LE_SCOREPLUM:
CG_AddScorePlum( le );
break;
#ifdef MISSIONPACK
case LE_KAMIKAZE:
CG_AddKamikaze( le );
break;
case LE_INVULIMPACT:
CG_AddInvulnerabilityImpact( le );
break;
case LE_INVULJUICED:
CG_AddInvulnerabilityJuiced( le );
break;
case LE_SHOWREFENTITY:
CG_AddRefEntity( le );
break;
#endif
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,506 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_playerstate.c -- this file acts on changes in a new playerState_t
// With normal play, this will be done after local prediction, but when
// following another player or playing back a demo, it will be checked
// when the snapshot transitions like all the other entities
#include "cg_local.h"
/*
==============
CG_CheckAmmo
If the ammo has gone low enough to generate the warning, play a sound
==============
*/
void CG_CheckAmmo( void ) {
int i;
int total;
int previous;
int weapons;
// see about how many seconds of ammo we have remaining
weapons = cg.snap->ps.stats[ STAT_WEAPONS ];
total = 0;
for ( i = WP_MACHINEGUN ; i < WP_NUM_WEAPONS ; i++ ) {
if ( ! ( weapons & ( 1 << i ) ) ) {
continue;
}
switch ( i ) {
case WP_ROCKET_LAUNCHER:
case WP_GRENADE_LAUNCHER:
case WP_RAILGUN:
case WP_SHOTGUN:
#ifdef MISSIONPACK
case WP_PROX_LAUNCHER:
#endif
total += cg.snap->ps.ammo[i] * 1000;
break;
default:
total += cg.snap->ps.ammo[i] * 200;
break;
}
if ( total >= 5000 ) {
cg.lowAmmoWarning = 0;
return;
}
}
previous = cg.lowAmmoWarning;
if ( total == 0 ) {
cg.lowAmmoWarning = 2;
} else {
cg.lowAmmoWarning = 1;
}
// play a sound on transitions
if ( cg.lowAmmoWarning != previous ) {
trap_S_StartLocalSound( cgs.media.noAmmoSound, CHAN_LOCAL_SOUND );
}
}
/*
==============
CG_DamageFeedback
==============
*/
void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
float left, front, up;
float kick;
int health;
float scale;
vec3_t dir;
vec3_t angles;
float dist;
float yaw, pitch;
// show the attacking player's head and name in corner
cg.attackerTime = cg.time;
// the lower on health you are, the greater the view kick will be
health = cg.snap->ps.stats[STAT_HEALTH];
if ( health < 40 ) {
scale = 1;
} else {
scale = 40.0 / health;
}
kick = damage * scale;
if (kick < 5)
kick = 5;
if (kick > 10)
kick = 10;
// if yaw and pitch are both 255, make the damage always centered (falling, etc)
if ( yawByte == 255 && pitchByte == 255 ) {
cg.damageX = 0;
cg.damageY = 0;
cg.v_dmg_roll = 0;
cg.v_dmg_pitch = -kick;
} else {
// positional
pitch = pitchByte / 255.0 * 360;
yaw = yawByte / 255.0 * 360;
angles[PITCH] = pitch;
angles[YAW] = yaw;
angles[ROLL] = 0;
AngleVectors( angles, dir, NULL, NULL );
VectorSubtract( vec3_origin, dir, dir );
front = DotProduct (dir, cg.refdef.viewaxis[0] );
left = DotProduct (dir, cg.refdef.viewaxis[1] );
up = DotProduct (dir, cg.refdef.viewaxis[2] );
dir[0] = front;
dir[1] = left;
dir[2] = 0;
dist = VectorLength( dir );
if ( dist < 0.1 ) {
dist = 0.1f;
}
cg.v_dmg_roll = kick * left;
cg.v_dmg_pitch = -kick * front;
if ( front <= 0.1 ) {
front = 0.1f;
}
cg.damageX = -left / front;
cg.damageY = up / dist;
}
// clamp the position
if ( cg.damageX > 1.0 ) {
cg.damageX = 1.0;
}
if ( cg.damageX < - 1.0 ) {
cg.damageX = -1.0;
}
if ( cg.damageY > 1.0 ) {
cg.damageY = 1.0;
}
if ( cg.damageY < - 1.0 ) {
cg.damageY = -1.0;
}
// don't let the screen flashes vary as much
if ( kick > 10 ) {
kick = 10;
}
cg.damageValue = kick;
cg.v_dmg_time = cg.time + DAMAGE_TIME;
cg.damageTime = cg.snap->serverTime;
}
/*
================
CG_Respawn
A respawn happened this snapshot
================
*/
void CG_Respawn( void ) {
// no error decay on player movement
cg.thisFrameTeleport = qtrue;
// display weapons available
cg.weaponSelectTime = cg.time;
// select the weapon the server says we are using
cg.weaponSelect = cg.snap->ps.weapon;
}
extern char *eventnames[];
/*
==============
CG_CheckPlayerstateEvents
==============
*/
void CG_CheckPlayerstateEvents( playerState_t *ps, playerState_t *ops ) {
int i;
int event;
centity_t *cent;
if ( ps->externalEvent && ps->externalEvent != ops->externalEvent ) {
cent = &cg_entities[ ps->clientNum ];
cent->currentState.event = ps->externalEvent;
cent->currentState.eventParm = ps->externalEventParm;
CG_EntityEvent( cent, cent->lerpOrigin );
}
cent = &cg.predictedPlayerEntity; // cg_entities[ ps->clientNum ];
// go through the predictable events buffer
for ( i = ps->eventSequence - MAX_PS_EVENTS ; i < ps->eventSequence ; i++ ) {
// if we have a new predictable event
if ( i >= ops->eventSequence
// or the server told us to play another event instead of a predicted event we already issued
// or something the server told us changed our prediction causing a different event
|| (i > ops->eventSequence - MAX_PS_EVENTS && ps->events[i & (MAX_PS_EVENTS-1)] != ops->events[i & (MAX_PS_EVENTS-1)]) ) {
event = ps->events[ i & (MAX_PS_EVENTS-1) ];
cent->currentState.event = event;
cent->currentState.eventParm = ps->eventParms[ i & (MAX_PS_EVENTS-1) ];
CG_EntityEvent( cent, cent->lerpOrigin );
cg.predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
cg.eventSequence++;
}
}
}
/*
==================
CG_CheckChangedPredictableEvents
==================
*/
void CG_CheckChangedPredictableEvents( playerState_t *ps ) {
int i;
int event;
centity_t *cent;
cent = &cg.predictedPlayerEntity;
for ( i = ps->eventSequence - MAX_PS_EVENTS ; i < ps->eventSequence ; i++ ) {
//
if (i >= cg.eventSequence) {
continue;
}
// if this event is not further back in than the maximum predictable events we remember
if (i > cg.eventSequence - MAX_PREDICTED_EVENTS) {
// if the new playerstate event is different from a previously predicted one
if ( ps->events[i & (MAX_PS_EVENTS-1)] != cg.predictableEvents[i & (MAX_PREDICTED_EVENTS-1) ] ) {
event = ps->events[ i & (MAX_PS_EVENTS-1) ];
cent->currentState.event = event;
cent->currentState.eventParm = ps->eventParms[ i & (MAX_PS_EVENTS-1) ];
CG_EntityEvent( cent, cent->lerpOrigin );
cg.predictableEvents[ i & (MAX_PREDICTED_EVENTS-1) ] = event;
if ( cg_showmiss.integer ) {
CG_Printf("WARNING: changed predicted event\n");
}
}
}
}
}
/*
==================
pushReward
==================
*/
static void pushReward(sfxHandle_t sfx, qhandle_t shader, int rewardCount) {
if (cg.rewardStack < (MAX_REWARDSTACK-1)) {
cg.rewardStack++;
cg.rewardSound[cg.rewardStack] = sfx;
cg.rewardShader[cg.rewardStack] = shader;
cg.rewardCount[cg.rewardStack] = rewardCount;
}
}
/*
==================
CG_CheckLocalSounds
==================
*/
void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
int highScore, health, armor, reward;
sfxHandle_t sfx;
// don't play the sounds if the player just changed teams
if ( ps->persistant[PERS_TEAM] != ops->persistant[PERS_TEAM] ) {
return;
}
// hit changes
if ( ps->persistant[PERS_HITS] > ops->persistant[PERS_HITS] ) {
armor = ps->persistant[PERS_ATTACKEE_ARMOR] & 0xff;
health = ps->persistant[PERS_ATTACKEE_ARMOR] >> 8;
#ifdef MISSIONPACK
if (armor > 50 ) {
trap_S_StartLocalSound( cgs.media.hitSoundHighArmor, CHAN_LOCAL_SOUND );
} else if (armor || health > 100) {
trap_S_StartLocalSound( cgs.media.hitSoundLowArmor, CHAN_LOCAL_SOUND );
} else {
trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
}
#else
trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
#endif
} else if ( ps->persistant[PERS_HITS] < ops->persistant[PERS_HITS] ) {
trap_S_StartLocalSound( cgs.media.hitTeamSound, CHAN_LOCAL_SOUND );
}
// health changes of more than -1 should make pain sounds
if ( ps->stats[STAT_HEALTH] < ops->stats[STAT_HEALTH] - 1 ) {
if ( ps->stats[STAT_HEALTH] > 0 ) {
CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[STAT_HEALTH] );
}
}
// if we are going into the intermission, don't start any voices
if ( cg.intermissionStarted ) {
return;
}
// reward sounds
reward = qfalse;
if (ps->persistant[PERS_CAPTURES] != ops->persistant[PERS_CAPTURES]) {
pushReward(cgs.media.captureAwardSound, cgs.media.medalCapture, ps->persistant[PERS_CAPTURES]);
reward = qtrue;
//Com_Printf("capture\n");
}
if (ps->persistant[PERS_IMPRESSIVE_COUNT] != ops->persistant[PERS_IMPRESSIVE_COUNT]) {
#ifdef MISSIONPACK
if (ps->persistant[PERS_IMPRESSIVE_COUNT] == 1) {
sfx = cgs.media.firstImpressiveSound;
} else {
sfx = cgs.media.impressiveSound;
}
#else
sfx = cgs.media.impressiveSound;
#endif
pushReward(sfx, cgs.media.medalImpressive, ps->persistant[PERS_IMPRESSIVE_COUNT]);
reward = qtrue;
//Com_Printf("impressive\n");
}
if (ps->persistant[PERS_EXCELLENT_COUNT] != ops->persistant[PERS_EXCELLENT_COUNT]) {
#ifdef MISSIONPACK
if (ps->persistant[PERS_EXCELLENT_COUNT] == 1) {
sfx = cgs.media.firstExcellentSound;
} else {
sfx = cgs.media.excellentSound;
}
#else
sfx = cgs.media.excellentSound;
#endif
pushReward(sfx, cgs.media.medalExcellent, ps->persistant[PERS_EXCELLENT_COUNT]);
reward = qtrue;
//Com_Printf("excellent\n");
}
if (ps->persistant[PERS_GAUNTLET_FRAG_COUNT] != ops->persistant[PERS_GAUNTLET_FRAG_COUNT]) {
#ifdef MISSIONPACK
if (ops->persistant[PERS_GAUNTLET_FRAG_COUNT] == 1) {
sfx = cgs.media.firstHumiliationSound;
} else {
sfx = cgs.media.humiliationSound;
}
#else
sfx = cgs.media.humiliationSound;
#endif
pushReward(sfx, cgs.media.medalGauntlet, ps->persistant[PERS_GAUNTLET_FRAG_COUNT]);
reward = qtrue;
//Com_Printf("guantlet frag\n");
}
if (ps->persistant[PERS_DEFEND_COUNT] != ops->persistant[PERS_DEFEND_COUNT]) {
pushReward(cgs.media.defendSound, cgs.media.medalDefend, ps->persistant[PERS_DEFEND_COUNT]);
reward = qtrue;
//Com_Printf("defend\n");
}
if (ps->persistant[PERS_ASSIST_COUNT] != ops->persistant[PERS_ASSIST_COUNT]) {
pushReward(cgs.media.assistSound, cgs.media.medalAssist, ps->persistant[PERS_ASSIST_COUNT]);
reward = qtrue;
//Com_Printf("assist\n");
}
// if any of the player event bits changed
if (ps->persistant[PERS_PLAYEREVENTS] != ops->persistant[PERS_PLAYEREVENTS]) {
if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_DENIEDREWARD) !=
(ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_DENIEDREWARD)) {
trap_S_StartLocalSound( cgs.media.deniedSound, CHAN_ANNOUNCER );
}
else if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_GAUNTLETREWARD) !=
(ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_GAUNTLETREWARD)) {
trap_S_StartLocalSound( cgs.media.humiliationSound, CHAN_ANNOUNCER );
}
else if ((ps->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_HOLYSHIT) !=
(ops->persistant[PERS_PLAYEREVENTS] & PLAYEREVENT_HOLYSHIT)) {
trap_S_StartLocalSound( cgs.media.holyShitSound, CHAN_ANNOUNCER );
}
reward = qtrue;
}
// check for flag pickup
if ( cgs.gametype >= GT_TEAM ) {
if ((ps->powerups[PW_REDFLAG] != ops->powerups[PW_REDFLAG] && ps->powerups[PW_REDFLAG]) ||
(ps->powerups[PW_BLUEFLAG] != ops->powerups[PW_BLUEFLAG] && ps->powerups[PW_BLUEFLAG]) ||
(ps->powerups[PW_NEUTRALFLAG] != ops->powerups[PW_NEUTRALFLAG] && ps->powerups[PW_NEUTRALFLAG]) )
{
trap_S_StartLocalSound( cgs.media.youHaveFlagSound, CHAN_ANNOUNCER );
}
}
// lead changes
if (!reward) {
//
if ( !cg.warmup ) {
// never play lead changes during warmup
if ( ps->persistant[PERS_RANK] != ops->persistant[PERS_RANK] ) {
if ( cgs.gametype < GT_TEAM) {
if ( ps->persistant[PERS_RANK] == 0 ) {
CG_AddBufferedSound(cgs.media.takenLeadSound);
} else if ( ps->persistant[PERS_RANK] == RANK_TIED_FLAG ) {
CG_AddBufferedSound(cgs.media.tiedLeadSound);
} else if ( ( ops->persistant[PERS_RANK] & ~RANK_TIED_FLAG ) == 0 ) {
CG_AddBufferedSound(cgs.media.lostLeadSound);
}
}
}
}
}
// timelimit warnings
if ( cgs.timelimit > 0 ) {
int msec;
msec = cg.time - cgs.levelStartTime;
if ( !( cg.timelimitWarnings & 4 ) && msec > ( cgs.timelimit * 60 + 2 ) * 1000 ) {
cg.timelimitWarnings |= 1 | 2 | 4;
trap_S_StartLocalSound( cgs.media.suddenDeathSound, CHAN_ANNOUNCER );
}
else if ( !( cg.timelimitWarnings & 2 ) && msec > (cgs.timelimit - 1) * 60 * 1000 ) {
cg.timelimitWarnings |= 1 | 2;
trap_S_StartLocalSound( cgs.media.oneMinuteSound, CHAN_ANNOUNCER );
}
else if ( cgs.timelimit > 5 && !( cg.timelimitWarnings & 1 ) && msec > (cgs.timelimit - 5) * 60 * 1000 ) {
cg.timelimitWarnings |= 1;
trap_S_StartLocalSound( cgs.media.fiveMinuteSound, CHAN_ANNOUNCER );
}
}
// fraglimit warnings
if ( cgs.fraglimit > 0 && cgs.gametype < GT_CTF) {
highScore = cgs.scores1;
if ( !( cg.fraglimitWarnings & 4 ) && highScore == (cgs.fraglimit - 1) ) {
cg.fraglimitWarnings |= 1 | 2 | 4;
CG_AddBufferedSound(cgs.media.oneFragSound);
}
else if ( cgs.fraglimit > 2 && !( cg.fraglimitWarnings & 2 ) && highScore == (cgs.fraglimit - 2) ) {
cg.fraglimitWarnings |= 1 | 2;
CG_AddBufferedSound(cgs.media.twoFragSound);
}
else if ( cgs.fraglimit > 3 && !( cg.fraglimitWarnings & 1 ) && highScore == (cgs.fraglimit - 3) ) {
cg.fraglimitWarnings |= 1;
CG_AddBufferedSound(cgs.media.threeFragSound);
}
}
}
/*
===============
CG_TransitionPlayerState
===============
*/
void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) {
// check for changing follow mode
if ( ps->clientNum != ops->clientNum ) {
cg.thisFrameTeleport = qtrue;
// make sure we don't get any unwanted transition effects
*ops = *ps;
}
// damage events (player is getting wounded)
if ( ps->damageEvent != ops->damageEvent && ps->damageCount ) {
CG_DamageFeedback( ps->damageYaw, ps->damagePitch, ps->damageCount );
}
// respawning
if ( ps->persistant[PERS_SPAWN_COUNT] != ops->persistant[PERS_SPAWN_COUNT] ) {
CG_Respawn();
}
if ( cg.mapRestart ) {
CG_Respawn();
cg.mapRestart = qfalse;
}
if ( cg.snap->ps.pm_type != PM_INTERMISSION
&& ps->persistant[PERS_TEAM] != TEAM_SPECTATOR ) {
CG_CheckLocalSounds( ps, ops );
}
// check for going low on ammo
CG_CheckAmmo();
// run events
CG_CheckPlayerstateEvents( ps, ops );
// smooth the ducking viewheight change
if ( ps->viewheight != ops->viewheight ) {
cg.duckChange = ps->viewheight - ops->viewheight;
cg.duckTime = cg.time;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,608 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_predict.c -- this file generates cg.predictedPlayerState by either
// interpolating between snapshots from the server or locally predicting
// ahead the client's movement.
// It also handles local physics interaction, like fragments bouncing off walls
#include "cg_local.h"
static pmove_t cg_pmove;
static int cg_numSolidEntities;
static centity_t *cg_solidEntities[MAX_ENTITIES_IN_SNAPSHOT];
static int cg_numTriggerEntities;
static centity_t *cg_triggerEntities[MAX_ENTITIES_IN_SNAPSHOT];
/*
====================
CG_BuildSolidList
When a new cg.snap has been set, this function builds a sublist
of the entities that are actually solid, to make for more
efficient collision detection
====================
*/
void CG_BuildSolidList( void ) {
int i;
centity_t *cent;
snapshot_t *snap;
entityState_t *ent;
cg_numSolidEntities = 0;
cg_numTriggerEntities = 0;
if ( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) {
snap = cg.nextSnap;
} else {
snap = cg.snap;
}
for ( i = 0 ; i < snap->numEntities ; i++ ) {
cent = &cg_entities[ snap->entities[ i ].number ];
ent = &cent->currentState;
if ( ent->eType == ET_ITEM || ent->eType == ET_PUSH_TRIGGER || ent->eType == ET_TELEPORT_TRIGGER ) {
cg_triggerEntities[cg_numTriggerEntities] = cent;
cg_numTriggerEntities++;
continue;
}
if ( cent->nextState.solid ) {
cg_solidEntities[cg_numSolidEntities] = cent;
cg_numSolidEntities++;
continue;
}
}
}
/*
====================
CG_ClipMoveToEntities
====================
*/
static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
int skipNumber, int mask, trace_t *tr ) {
int i, x, zd, zu;
trace_t trace;
entityState_t *ent;
clipHandle_t cmodel;
vec3_t bmins, bmaxs;
vec3_t origin, angles;
centity_t *cent;
for ( i = 0 ; i < cg_numSolidEntities ; i++ ) {
cent = cg_solidEntities[ i ];
ent = &cent->currentState;
if ( ent->number == skipNumber ) {
continue;
}
if ( ent->solid == SOLID_BMODEL ) {
// special value for bmodel
cmodel = trap_CM_InlineModel( ent->modelindex );
VectorCopy( cent->lerpAngles, angles );
BG_EvaluateTrajectory( &cent->currentState.pos, cg.physicsTime, origin );
} else {
// encoded bbox
x = (ent->solid & 255);
zd = ((ent->solid>>8) & 255);
zu = ((ent->solid>>16) & 255) - 32;
bmins[0] = bmins[1] = -x;
bmaxs[0] = bmaxs[1] = x;
bmins[2] = -zd;
bmaxs[2] = zu;
cmodel = trap_CM_TempBoxModel( bmins, bmaxs );
VectorCopy( vec3_origin, angles );
VectorCopy( cent->lerpOrigin, origin );
}
trap_CM_TransformedBoxTrace ( &trace, start, end,
mins, maxs, cmodel, mask, origin, angles);
if (trace.allsolid || trace.fraction < tr->fraction) {
trace.entityNum = ent->number;
*tr = trace;
} else if (trace.startsolid) {
tr->startsolid = qtrue;
}
if ( tr->allsolid ) {
return;
}
}
}
/*
================
CG_Trace
================
*/
void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
int skipNumber, int mask ) {
trace_t t;
trap_CM_BoxTrace ( &t, start, end, mins, maxs, 0, mask);
t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE;
// check all other solid models
CG_ClipMoveToEntities (start, mins, maxs, end, skipNumber, mask, &t);
*result = t;
}
/*
================
CG_PointContents
================
*/
int CG_PointContents( const vec3_t point, int passEntityNum ) {
int i;
entityState_t *ent;
centity_t *cent;
clipHandle_t cmodel;
int contents;
contents = trap_CM_PointContents (point, 0);
for ( i = 0 ; i < cg_numSolidEntities ; i++ ) {
cent = cg_solidEntities[ i ];
ent = &cent->currentState;
if ( ent->number == passEntityNum ) {
continue;
}
if (ent->solid != SOLID_BMODEL) { // special value for bmodel
continue;
}
cmodel = trap_CM_InlineModel( ent->modelindex );
if ( !cmodel ) {
continue;
}
contents |= trap_CM_TransformedPointContents( point, cmodel, ent->origin, ent->angles );
}
return contents;
}
/*
========================
CG_InterpolatePlayerState
Generates cg.predictedPlayerState by interpolating between
cg.snap->player_state and cg.nextFrame->player_state
========================
*/
static void CG_InterpolatePlayerState( qboolean grabAngles ) {
float f;
int i;
playerState_t *out;
snapshot_t *prev, *next;
out = &cg.predictedPlayerState;
prev = cg.snap;
next = cg.nextSnap;
*out = cg.snap->ps;
// if we are still allowing local input, short circuit the view angles
if ( grabAngles ) {
usercmd_t cmd;
int cmdNum;
cmdNum = trap_GetCurrentCmdNumber();
trap_GetUserCmd( cmdNum, &cmd );
PM_UpdateViewAngles( out, &cmd );
}
// if the next frame is a teleport, we can't lerp to it
if ( cg.nextFrameTeleport ) {
return;
}
if ( !next || next->serverTime <= prev->serverTime ) {
return;
}
f = (float)( cg.time - prev->serverTime ) / ( next->serverTime - prev->serverTime );
i = next->ps.bobCycle;
if ( i < prev->ps.bobCycle ) {
i += 256; // handle wraparound
}
out->bobCycle = prev->ps.bobCycle + f * ( i - prev->ps.bobCycle );
for ( i = 0 ; i < 3 ; i++ ) {
out->origin[i] = prev->ps.origin[i] + f * (next->ps.origin[i] - prev->ps.origin[i] );
if ( !grabAngles ) {
out->viewangles[i] = LerpAngle(
prev->ps.viewangles[i], next->ps.viewangles[i], f );
}
out->velocity[i] = prev->ps.velocity[i] +
f * (next->ps.velocity[i] - prev->ps.velocity[i] );
}
}
/*
===================
CG_TouchItem
===================
*/
static void CG_TouchItem( centity_t *cent ) {
gitem_t *item;
if ( !cg_predictItems.integer ) {
return;
}
if ( !BG_PlayerTouchesItem( &cg.predictedPlayerState, &cent->currentState, cg.time ) ) {
return;
}
// never pick an item up twice in a prediction
if ( cent->miscTime == cg.time ) {
return;
}
if ( !BG_CanItemBeGrabbed( cgs.gametype, &cent->currentState, &cg.predictedPlayerState ) ) {
return; // can't hold it
}
item = &bg_itemlist[ cent->currentState.modelindex ];
// Special case for flags.
// We don't predict touching our own flag
#ifdef MISSIONPACK
if( cgs.gametype == GT_1FCTF ) {
if( item->giTag != PW_NEUTRALFLAG ) {
return;
}
}
if( cgs.gametype == GT_CTF || cgs.gametype == GT_HARVESTER ) {
#else
if( cgs.gametype == GT_CTF ) {
#endif
if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_RED &&
item->giTag == PW_REDFLAG)
return;
if (cg.predictedPlayerState.persistant[PERS_TEAM] == TEAM_BLUE &&
item->giTag == PW_BLUEFLAG)
return;
}
// grab it
BG_AddPredictableEventToPlayerstate( EV_ITEM_PICKUP, cent->currentState.modelindex , &cg.predictedPlayerState);
// remove it from the frame so it won't be drawn
cent->currentState.eFlags |= EF_NODRAW;
// don't touch it again this prediction
cent->miscTime = cg.time;
// if its a weapon, give them some predicted ammo so the autoswitch will work
if ( item->giType == IT_WEAPON ) {
cg.predictedPlayerState.stats[ STAT_WEAPONS ] |= 1 << item->giTag;
if ( !cg.predictedPlayerState.ammo[ item->giTag ] ) {
cg.predictedPlayerState.ammo[ item->giTag ] = 1;
}
}
}
/*
=========================
CG_TouchTriggerPrediction
Predict push triggers and items
=========================
*/
static void CG_TouchTriggerPrediction( void ) {
int i;
trace_t trace;
entityState_t *ent;
clipHandle_t cmodel;
centity_t *cent;
qboolean spectator;
// dead clients don't activate triggers
if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
return;
}
spectator = ( cg.predictedPlayerState.pm_type == PM_SPECTATOR );
if ( cg.predictedPlayerState.pm_type != PM_NORMAL && !spectator ) {
return;
}
for ( i = 0 ; i < cg_numTriggerEntities ; i++ ) {
cent = cg_triggerEntities[ i ];
ent = &cent->currentState;
if ( ent->eType == ET_ITEM && !spectator ) {
CG_TouchItem( cent );
continue;
}
if ( ent->solid != SOLID_BMODEL ) {
continue;
}
cmodel = trap_CM_InlineModel( ent->modelindex );
if ( !cmodel ) {
continue;
}
trap_CM_BoxTrace( &trace, cg.predictedPlayerState.origin, cg.predictedPlayerState.origin,
cg_pmove.mins, cg_pmove.maxs, cmodel, -1 );
if ( !trace.startsolid ) {
continue;
}
if ( ent->eType == ET_TELEPORT_TRIGGER ) {
cg.hyperspace = qtrue;
} else if ( ent->eType == ET_PUSH_TRIGGER ) {
BG_TouchJumpPad( &cg.predictedPlayerState, ent );
}
}
// if we didn't touch a jump pad this pmove frame
if ( cg.predictedPlayerState.jumppad_frame != cg.predictedPlayerState.pmove_framecount ) {
cg.predictedPlayerState.jumppad_frame = 0;
cg.predictedPlayerState.jumppad_ent = 0;
}
}
/*
=================
CG_PredictPlayerState
Generates cg.predictedPlayerState for the current cg.time
cg.predictedPlayerState is guaranteed to be valid after exiting.
For demo playback, this will be an interpolation between two valid
playerState_t.
For normal gameplay, it will be the result of predicted usercmd_t on
top of the most recent playerState_t received from the server.
Each new snapshot will usually have one or more new usercmd over the last,
but we simulate all unacknowledged commands each time, not just the new ones.
This means that on an internet connection, quite a few pmoves may be issued
each frame.
OPTIMIZE: don't re-simulate unless the newly arrived snapshot playerState_t
differs from the predicted one. Would require saving all intermediate
playerState_t during prediction.
We detect prediction errors and allow them to be decayed off over several frames
to ease the jerk.
=================
*/
void CG_PredictPlayerState( void ) {
int cmdNum, current;
playerState_t oldPlayerState;
qboolean moved;
usercmd_t oldestCmd;
usercmd_t latestCmd;
cg.hyperspace = qfalse; // will be set if touching a trigger_teleport
// if this is the first frame we must guarantee
// predictedPlayerState is valid even if there is some
// other error condition
if ( !cg.validPPS ) {
cg.validPPS = qtrue;
cg.predictedPlayerState = cg.snap->ps;
}
// demo playback just copies the moves
if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) ) {
CG_InterpolatePlayerState( qfalse );
return;
}
// non-predicting local movement will grab the latest angles
if ( cg_nopredict.integer || cg_synchronousClients.integer ) {
CG_InterpolatePlayerState( qtrue );
return;
}
// prepare for pmove
cg_pmove.ps = &cg.predictedPlayerState;
cg_pmove.trace = CG_Trace;
cg_pmove.pointcontents = CG_PointContents;
if ( cg_pmove.ps->pm_type == PM_DEAD ) {
cg_pmove.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
}
else {
cg_pmove.tracemask = MASK_PLAYERSOLID;
}
if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
cg_pmove.tracemask &= ~CONTENTS_BODY; // spectators can fly through bodies
}
cg_pmove.noFootsteps = ( cgs.dmflags & DF_NO_FOOTSTEPS ) > 0;
// save the state before the pmove so we can detect transitions
oldPlayerState = cg.predictedPlayerState;
current = trap_GetCurrentCmdNumber();
// if we don't have the commands right after the snapshot, we
// can't accurately predict a current position, so just freeze at
// the last good position we had
cmdNum = current - CMD_BACKUP + 1;
trap_GetUserCmd( cmdNum, &oldestCmd );
if ( oldestCmd.serverTime > cg.snap->ps.commandTime
&& oldestCmd.serverTime < cg.time ) { // special check for map_restart
if ( cg_showmiss.integer ) {
CG_Printf ("exceeded PACKET_BACKUP on commands\n");
}
return;
}
// get the latest command so we can know which commands are from previous map_restarts
trap_GetUserCmd( current, &latestCmd );
// get the most recent information we have, even if
// the server time is beyond our current cg.time,
// because predicted player positions are going to
// be ahead of everything else anyway
if ( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) {
cg.predictedPlayerState = cg.nextSnap->ps;
cg.physicsTime = cg.nextSnap->serverTime;
} else {
cg.predictedPlayerState = cg.snap->ps;
cg.physicsTime = cg.snap->serverTime;
}
if ( pmove_msec.integer < 8 ) {
trap_Cvar_Set("pmove_msec", "8");
}
else if (pmove_msec.integer > 33) {
trap_Cvar_Set("pmove_msec", "33");
}
cg_pmove.pmove_fixed = pmove_fixed.integer;// | cg_pmove_fixed.integer;
cg_pmove.pmove_msec = pmove_msec.integer;
// run cmds
moved = qfalse;
for ( cmdNum = current - CMD_BACKUP + 1 ; cmdNum <= current ; cmdNum++ ) {
// get the command
trap_GetUserCmd( cmdNum, &cg_pmove.cmd );
if ( cg_pmove.pmove_fixed ) {
PM_UpdateViewAngles( cg_pmove.ps, &cg_pmove.cmd );
}
// don't do anything if the time is before the snapshot player time
if ( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime ) {
continue;
}
// don't do anything if the command was from a previous map_restart
if ( cg_pmove.cmd.serverTime > latestCmd.serverTime ) {
continue;
}
// check for a prediction error from last frame
// on a lan, this will often be the exact value
// from the snapshot, but on a wan we will have
// to predict several commands to get to the point
// we want to compare
if ( cg.predictedPlayerState.commandTime == oldPlayerState.commandTime ) {
vec3_t delta;
float len;
if ( cg.thisFrameTeleport ) {
// a teleport will not cause an error decay
VectorClear( cg.predictedError );
if ( cg_showmiss.integer ) {
CG_Printf( "PredictionTeleport\n" );
}
cg.thisFrameTeleport = qfalse;
} else {
vec3_t adjusted;
CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
cg.predictedPlayerState.groundEntityNum, cg.physicsTime, cg.oldTime, adjusted );
if ( cg_showmiss.integer ) {
if (!VectorCompare( oldPlayerState.origin, adjusted )) {
CG_Printf("prediction error\n");
}
}
VectorSubtract( oldPlayerState.origin, adjusted, delta );
len = VectorLength( delta );
if ( len > 0.1 ) {
if ( cg_showmiss.integer ) {
CG_Printf("Prediction miss: %f\n", len);
}
if ( cg_errorDecay.integer ) {
int t;
float f;
t = cg.time - cg.predictedErrorTime;
f = ( cg_errorDecay.value - t ) / cg_errorDecay.value;
if ( f < 0 ) {
f = 0;
}
if ( f > 0 && cg_showmiss.integer ) {
CG_Printf("Double prediction decay: %f\n", f);
}
VectorScale( cg.predictedError, f, cg.predictedError );
} else {
VectorClear( cg.predictedError );
}
VectorAdd( delta, cg.predictedError, cg.predictedError );
cg.predictedErrorTime = cg.oldTime;
}
}
}
// don't predict gauntlet firing, which is only supposed to happen
// when it actually inflicts damage
cg_pmove.gauntletHit = qfalse;
if ( cg_pmove.pmove_fixed ) {
cg_pmove.cmd.serverTime = ((cg_pmove.cmd.serverTime + pmove_msec.integer-1) / pmove_msec.integer) * pmove_msec.integer;
}
Pmove (&cg_pmove);
moved = qtrue;
// add push trigger movement effects
CG_TouchTriggerPrediction();
// check for predictable events that changed from previous predictions
//CG_CheckChangedPredictableEvents(&cg.predictedPlayerState);
}
if ( cg_showmiss.integer > 1 ) {
CG_Printf( "[%i : %i] ", cg_pmove.cmd.serverTime, cg.time );
}
if ( !moved ) {
if ( cg_showmiss.integer ) {
CG_Printf( "not moved\n" );
}
return;
}
// adjust for the movement of the groundentity
CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
cg.predictedPlayerState.groundEntityNum,
cg.physicsTime, cg.time, cg.predictedPlayerState.origin );
if ( cg_showmiss.integer ) {
if (cg.predictedPlayerState.eventSequence > oldPlayerState.eventSequence + MAX_PS_EVENTS) {
CG_Printf("WARNING: dropped event\n");
}
}
// fire events and other transition triggered things
CG_TransitionPlayerState( &cg.predictedPlayerState, &oldPlayerState );
if ( cg_showmiss.integer ) {
if (cg.eventSequence > cg.predictedPlayerState.eventSequence) {
CG_Printf("WARNING: double event\n");
cg.eventSequence = cg.predictedPlayerState.eventSequence;
}
}
}

View File

@@ -0,0 +1,218 @@
// Copyright (C) 1999-2000 Id Software, Inc.
//
#define CMD_BACKUP 64
#define CMD_MASK (CMD_BACKUP - 1)
// allow a lot of command backups for very fast systems
// multiple commands may be combined into a single packet, so this
// needs to be larger than PACKET_BACKUP
#define MAX_ENTITIES_IN_SNAPSHOT 256
// snapshots are a view of the server at a given time
// Snapshots are generated at regular time intervals by the server,
// but they may not be sent if a client's rate level is exceeded, or
// they may be dropped by the network.
typedef struct {
int snapFlags; // SNAPFLAG_RATE_DELAYED, etc
int ping;
int serverTime; // server time the message is valid for (in msec)
byte areamask[MAX_MAP_AREA_BYTES]; // portalarea visibility bits
playerState_t ps; // complete information about the current player at this time
int numEntities; // all of the entities that need to be presented
entityState_t entities[MAX_ENTITIES_IN_SNAPSHOT]; // at the time of this snapshot
int numServerCommands; // text based server commands to execute when this
int serverCommandSequence; // snapshot becomes current
} snapshot_t;
enum {
CGAME_EVENT_NONE,
CGAME_EVENT_TEAMMENU,
CGAME_EVENT_SCOREBOARD,
CGAME_EVENT_EDITHUD
};
/*
==================================================================
functions imported from the main executable
==================================================================
*/
#define CGAME_IMPORT_API_VERSION 4
typedef enum {
CG_PRINT,
CG_ERROR,
CG_MILLISECONDS,
CG_CVAR_REGISTER,
CG_CVAR_UPDATE,
CG_CVAR_SET,
CG_CVAR_VARIABLESTRINGBUFFER,
CG_ARGC,
CG_ARGV,
CG_ARGS,
CG_FS_FOPENFILE,
CG_FS_READ,
CG_FS_WRITE,
CG_FS_FCLOSEFILE,
CG_SENDCONSOLECOMMAND,
CG_ADDCOMMAND,
CG_SENDCLIENTCOMMAND,
CG_UPDATESCREEN,
CG_CM_LOADMAP,
CG_CM_NUMINLINEMODELS,
CG_CM_INLINEMODEL,
CG_CM_LOADMODEL,
CG_CM_TEMPBOXMODEL,
CG_CM_POINTCONTENTS,
CG_CM_TRANSFORMEDPOINTCONTENTS,
CG_CM_BOXTRACE,
CG_CM_TRANSFORMEDBOXTRACE,
CG_CM_MARKFRAGMENTS,
CG_S_STARTSOUND,
CG_S_STARTLOCALSOUND,
CG_S_CLEARLOOPINGSOUNDS,
CG_S_ADDLOOPINGSOUND,
CG_S_UPDATEENTITYPOSITION,
CG_S_RESPATIALIZE,
CG_S_REGISTERSOUND,
CG_S_STARTBACKGROUNDTRACK,
CG_R_LOADWORLDMAP,
CG_R_REGISTERMODEL,
CG_R_REGISTERSKIN,
CG_R_REGISTERSHADER,
CG_R_CLEARSCENE,
CG_R_ADDREFENTITYTOSCENE,
CG_R_ADDPOLYTOSCENE,
CG_R_ADDLIGHTTOSCENE,
CG_R_RENDERSCENE,
CG_R_SETCOLOR,
CG_R_DRAWSTRETCHPIC,
CG_R_MODELBOUNDS,
CG_R_LERPTAG,
CG_GETGLCONFIG,
CG_GETGAMESTATE,
CG_GETCURRENTSNAPSHOTNUMBER,
CG_GETSNAPSHOT,
CG_GETSERVERCOMMAND,
CG_GETCURRENTCMDNUMBER,
CG_GETUSERCMD,
CG_SETUSERCMDVALUE,
CG_R_REGISTERSHADERNOMIP,
CG_MEMORY_REMAINING,
CG_R_REGISTERFONT,
CG_KEY_ISDOWN,
CG_KEY_GETCATCHER,
CG_KEY_SETCATCHER,
CG_KEY_GETKEY,
CG_PC_ADD_GLOBAL_DEFINE,
CG_PC_LOAD_SOURCE,
CG_PC_FREE_SOURCE,
CG_PC_READ_TOKEN,
CG_PC_SOURCE_FILE_AND_LINE,
CG_S_STOPBACKGROUNDTRACK,
CG_REAL_TIME,
CG_SNAPVECTOR,
CG_REMOVECOMMAND,
CG_R_LIGHTFORPOINT,
CG_CIN_PLAYCINEMATIC,
CG_CIN_STOPCINEMATIC,
CG_CIN_RUNCINEMATIC,
CG_CIN_DRAWCINEMATIC,
CG_CIN_SETEXTENTS,
CG_R_REMAP_SHADER,
CG_S_ADDREALLOOPINGSOUND,
CG_S_STOPLOOPINGSOUND,
CG_CM_TEMPCAPSULEMODEL,
CG_CM_CAPSULETRACE,
CG_CM_TRANSFORMEDCAPSULETRACE,
CG_R_ADDADDITIVELIGHTTOSCENE,
CG_GET_ENTITY_TOKEN,
CG_R_ADDPOLYSTOSCENE,
CG_R_INPVS,
// 1.32
CG_FS_SEEK,
/*
CG_LOADCAMERA,
CG_STARTCAMERA,
CG_GETCAMERAINFO,
*/
CG_MEMSET = 100,
CG_MEMCPY,
CG_STRNCPY,
CG_SIN,
CG_COS,
CG_ATAN2,
CG_SQRT,
CG_FLOOR,
CG_CEIL,
CG_TESTPRINTINT,
CG_TESTPRINTFLOAT,
CG_ACOS
} cgameImport_t;
/*
==================================================================
functions exported to the main executable
==================================================================
*/
typedef enum {
CG_INIT,
// void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
// called when the level loads or when the renderer is restarted
// all media should be registered at this time
// cgame will display loading status by calling SCR_Update, which
// will call CG_DrawInformation during the loading process
// reliableCommandSequence will be 0 on fresh loads, but higher for
// demos, tourney restarts, or vid_restarts
CG_SHUTDOWN,
// void (*CG_Shutdown)( void );
// oportunity to flush and close any open files
CG_CONSOLE_COMMAND,
// qboolean (*CG_ConsoleCommand)( void );
// a console command has been issued locally that is not recognized by the
// main game system.
// use Cmd_Argc() / Cmd_Argv() to read the command, return qfalse if the
// command is not known to the game
CG_DRAW_ACTIVE_FRAME,
// void (*CG_DrawActiveFrame)( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback );
// Generates and draws a game scene and status information at the given time.
// If demoPlayback is set, local movement prediction will not be enabled
CG_CROSSHAIR_PLAYER,
// int (*CG_CrosshairPlayer)( void );
CG_LAST_ATTACKER,
// int (*CG_LastAttacker)( void );
CG_KEY_EVENT,
// void (*CG_KeyEvent)( int key, qboolean down );
CG_MOUSE_EVENT,
// void (*CG_MouseEvent)( int dx, int dy );
CG_EVENT_HANDLING
// void (*CG_EventHandling)(int type);
} cgameExport_t;
//----------------------------------------------

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More