-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathREADME-wolfcam.txt
3209 lines (2092 loc) · 148 KB
/
README-wolfcam.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
------------------------------------------------------------------------
Introduction:
WolfcamQL is a quakelive/quake3 demo player with some hopefully helpful options for demo viewing and movie making:
* demo pause/rewind/fast forward
* demo viewing without needing an internet connection
* viewing demos from other player's point of view or in freecam mode
* compatibility with all the client features that have been added to quakelive on top of the original quake3
* backwards compatibility with older quake live demos
* adjust player and projectile positions to match more closely what occurred on the demo taker's screen (demo treated as what the 'client saw' not what the 'server saw' and will also compensate for demo taker's ping)
* camera system
* q3mme style scripting to customize graphics and effects
* raise/remove limits for video rendering and also options like motion blur
* other stuff... :p
enjoy!
-------------------------------------------------------------------------------
Installation:
Unzip wolfcamql*.zip anywhere you would like. You do not have to, and it's not recommended to, install into quakelive's directory.
Copy the quakelive paks into baseq3.
To auto-download steam workshop maps for demo playback you should install steamcmd from https://developer.valvesoftware.com/wiki/SteamCMD and set its location in the fs_steamcmd variable.
Ex: set fs_steamcmd "C:\Program Files\steamcmd\steamcmd.exe"
If you want to use the same maps that an older demo was recorded with you can copy over files that start with qz (ex: qzteam1.pk3, qzdm6.pk3) from an older quakelive baseq3/ into wolfcam's baseq3/ . Otherwise, it will use the new maps with old demos.
------------------------------------------------------------------------
If you want to use steam workshop gibs you need to copy workshop_gibs.pk3 into wolfcam-ql/.
Alternatively, if you'd like to have the original quake3 gibs and blood, you need to copy the following files from quake3's pak0.pk3:
First copy:
gfx/damage/blood_spurt.tga
gfx/damage/blood_stain.tga
from quake3 to:
wolfcamql/wolfcam-ql/gfx/damageq3/blood_spurt.tga
wolfcamql/wolfcam-ql/gfx/damageq3/blood_stain.tga
* Notice that the new directory is called damageq3.
Now copy:
models/gibs/gibs.jpg
models/gibs/leg.md3
models/gibs/skull.md3
models/gibs/abdomen.md3
models/gibs/chest.md3
models/gibs/intestine.md3
models/gibs/brain.md3
models/gibs/foot.md3
models/gibs/forearm.md3
models/gibs/arm.md3
models/gibs/fist.md3
from quake3 to:
wolfcamql/wolfcam-ql/models/gibsq3/gibs.jpg
wolfcamql/wolfcam-ql/models/gibsq3/leg.md3
wolfcamql/wolfcam-ql/models/gibsq3/skull.md3
wolfcamql/wolfcam-ql/models/gibsq3/abdomen.md3
wolfcamql/wolfcam-ql/models/gibsq3/chest.md3
wolfcamql/wolfcam-ql/models/gibsq3/intestine.md3
wolfcamql/wolfcam-ql/models/gibsq3/brain.md3
wolfcamql/wolfcam-ql/models/gibsq3/foot.md3
wolfcamql/wolfcam-ql/models/gibsq3/forearm.md3
wolfcamql/wolfcam-ql/models/gibsq3/arm.md3
wolfcamql/wolfcam-ql/models/gibsq3/fist.md3
* Notice that the new directory is called gibsq3
Now copy:
sound/player/gibimp1.wav
sound/player/gibimp2.wav
sound/player/gibimp3.wav
sound/player/gibsplt1.wav
from quake3 to:
and then place in:
wolfcamql/wolfcam-ql/sound/player/gibimp1.wav
wolfcamql/wolfcam-ql/sound/player/gibimp2.wav
wolfcamql/wolfcam-ql/sound/player/gibimp3.wav
wolfcamql/wolfcam-ql/sound/player/gibsplt1.wav
Use cl_useq3gibs 1 to enable, and cl_useq3gibs 0 to use to ql gibs.
When gibs are enabled quake3 gibs are checked first and if they aren't found it falls back to workshop gibs.
------------------------------------------------------------------------
q3 style player bleeding when they are hit:
Enabled when workshop_gibs.pk3 is copied into wolfcam-ql/ or when these are copied from quake3:
models/weaphits/blood201.tga
models/weaphits/blood202.tga
models/weaphits/blood203.tga
models/weaphits/blood204.tga
models/weaphits/blood205.tga
into wolfcamql/wolfcam-ql/gfx/damageq3
wolfcamql/wolfcam-ql/gfx/damageq3/blood201.tga
wolfcamql/wolfcam-ql/gfx/damageq3/blood202.tga
wolfcamql/wolfcam-ql/gfx/damageq3/blood203.tga
wolfcamql/wolfcam-ql/gfx/damageq3/blood204.tga
wolfcamql/wolfcam-ql/gfx/damageq3/blood205.tga
If these files aren't present a substitute blood shader will be used that
uses the blood*.tga images from wolfcamql/wolfcam-ql/gfx/wc. The shader name
is wc/bloodExplostionAlt.
The bleeding effect can be turned on/off with com_blood cvar and the time
can be controlled with cg_bleedTime.
-------------------------------------------------------------------------
* view demo from other player's point of view.
In the console type:
/players
You'll get a list of players and then use /follow [number] to watch them.
Use /follow -1 to return to the demo taker's point of view.
One of the limitations is that they won't always be present in the demo, they need to be close enough to the demo taker.
* /follow killer
/follow victim
Will look ahead in the demo and have those povs ready. "wolfcam_drawFollowing 2" (the default) will highlight their names.
* wolfcam_switchMode 1 (switch back to demo taker if pov not available) 2 (try selected pov, then killer/victim, then demo taker pov) 0 (try selected pov, try closest opponent, demo pov)
* wolfcam_hoverTime "2000"
When you are following other players and they die don't automatically switch to a different pov, wait this amount of time in milliseconds before switching.
* wolfcam_fixedViewAngles "0"
Test/debug cvar. It'll only update the viewangles of the /follow pov this many milliseconds.
* wolfcam_painHealth
For players that don't normally have health information available (ex: players not on demo taker's team), this can use server pain events to briefly update the current health value.
* wolfcam_painHealthColor hud color when pain event is used to determine health value
* wolfcam_painHealthAlpha hud alpha value when pain event is used to determine health value
* wolfcam_painHealthFade
* wolfcam_painHealthFadeTime
Fade out pain event health value.
* wolfcam_painHealthValidTime
Pain event health values become invalid for health updates after this amount of time in milliseconds. Setting to negative value never invalidates the health value.
* wolfcam_painHealthStyle
Since protocol 90, Quake Live doesn't send real health values. It will only send either 20, 40, 60, or 80. If this cvar is set, only a negative sign ('-') is shown for '80' value.
-----------------------------------------------------------------
Matching colors and lighting with quakelive:
In order to match colors and lighting post processing isn't needed, with the exception of bloom.
Quakelive's r_enablePostProcessing and r_enableColorCorrection sort of correspond to the old q3 cvar r_ignorehwgamma.
There's a lot of confusion about what's involved in quakelive's post processing since there isn't much documentation about what the cvars do.
Here's my best take/guess on it:
In quake3 if you want to use r_gamma and r_overbrightbits you need to enable hardware gamma (r_ignorehwgamma 0). The problem is that setting gamma like that changes the color/brightness of your entire desktop not just the quake3 application. In quake3 it isn't a big problem since you usually play fullscreen and don't really care about messed up colors in the desktop underneath. Quakelive was designed to be run in a browser so they wanted to avoid changing gamma for the whole screen and wanted to restrict it to just the quakelive window. The solution was r_enablePostProcessing, which at the price of a little performance drop (an extra rendering step), enabled gamma (r_gamma + r_overbrightbits) just for the quakelive window. At that point in quakelive's history r_enablePostProcessing 1 corresponded to r_ignorehwgamma 0 in quake3 (allow the use of r_gamma and r_overbrightbits).
Bloom was later added and it created a problem since r_enablePostProcessing didn't just deal with gamma anymore (it controlled both bloom and gamma). So a later quakelive patch added r_enableColorCorrection which is basically gamma again. This allowed you to keep r_enablePostProcessing 1 if you wanted bloom and r_enableColorCorrection 0 to disable disable gamma. r_enablePostProcessing became a generic cvar enabling different types of post processing (gamma, bloom, anything else they might want to add, etc.). r_enableColorCorrection 1 became the new r_ignorehwgamma 0.
So basically quakelive and quake3 have the same colors and lighting which are controlled by the usual r_* cvars (r_mapOverBrightBits, r_intensity, etc..). The problem and confusion is that two of those: r_gamma and r_overbrightbits are special and have to be "unlocked" in order to have their settings apply.
In quake3/ioquake3/wolfcam(with post processing disabled) you have to have "r_ignorehwgamma 0" in order to use r_gamma and r_overbrightbits.
In quakelive you need "r_enablePostProcessing 1 and r_enableColorCorrection 1" in order to use r_gamma and r_overbrightbits.
Oh, and to add to the confusion, quakelive still has the r_ignorehwgamma cvar :( It doesn't seem to do anything though.
-----------------------------------------------------------------
It's based on ioquake3 so you have a few features available and changed:
cl_aviFrameRate - the frame rate to use when capturing video
cl_aviMotionJpeg - (this cvar is removed, see cl_aviCodec)
New commands
stopvideo - stop video capture
see README-ioquake3.txt for more stuff.
Note: it's not mentioned in the ioquake3 documentation but you need to disable openal in order to have sound recorded in the avi file. +set s_useopenal 0. You also need to have s_sdlWindowsForceDirectSound 1.
added features:
cl_aviFrameRateDivider integer value that will force rendering at cl_aviFrameRate * blur frames * value and drop frames so that final output still has a rate equal to cl_aviFrameRate. Values less than 2 are ignored.
cl_aviCodec uncompressed, mjpeg, huffyuv
cl_aviAllowLargeFiles 1 to allow opendml avi files (up to about 500 gigabytes)
/video [avi, avins, tga, jpg, png, wav, split, name <file basename>]
All files stored in video/
ex: /video tga wav to dump tga screen-shots and a wav sound recording
ex: /video avins wav name myNewVideo avi file with no sound and a wav file
'name :demoname' will use the current demo filename as the video file basename
'split' option records extra right and left videos with r_anaglyphMode settings. See extensions to r_anaglyphMode.
r_jpegCompressionQuality controls jpeg compression quality
r_pngZlibCompression choose between high speed or higher compression size
cl_aviFetchMode GL_RGB (default switched from ioquake3 GL_RGBA default)
When you take a screen-shot you select what format you would like the video card to send back: "red green blue", "blue green red alpha", etc..
Some video cards might be faster or slower with certain formats.
added default bind:
bind i "toggle cl_avifetchmode gl_rgb gl_rgba gl_bgr gl_bgra; echopopupcva
r cl_avifetchmode"
Do a test run and try the different values to see if you can get a performance boost when rendering. Note that there is no information in the alpha channel, so this isn't a way of getting transparency information.
Note: png output disregards this option and forces GL_RGBA as the fetch mode, motion blur and dof blur disregard this option and force GL_BGR as the fetch mode.
cl_aviNoAudioHWOutput don't pass audio data to sound card when recording, default is 1
cl_freezeDemoPauseVideoRecording to pause recording of video/screen-shots while paused
cl_aviExtension allow changing '.avi' extension to something else to avoid Windows indexing of video file
------------------------------------------------------------------
q3mme fx scripting
/set cg_fxfile "scripts/q3mme.fx"
/fxload
to disable ->
/set cg_fxfile ""
/fxload
/fxload <somefxfile.fx>
These two cvars can be used to control performance for now:
cg_fxinterval how often in milliseconds the scripting code is run (default 25). Lowering lowers performance.
cg_fxratio ratio of distance and size to determine if script code should be run for an entity (default 0.002). Lowering lowers performance
If an fx entity is so small and/or far away (size / distance from you) don't bother running fx code for it in order to improve performance.
cg_fxLightningGunImpactFps how often to run lg impact and look the same at any frame per second value (default is 125, 0 to disable)
cg_fxScriptMinEmitter
cg_fxScriptMinDistance
cg_fxScriptMinInterval
for the three above they are used to prevent values dipping below those
thresholds
cg_fxCompiled enable/disable performance optimization (2 or higher enables debugging output)
cg_vibrate
cg_vibrateForce
cg_vibrateTime
cg_vibrateMaxDistance
/fxmath 2 + 4 * 6.1 if you need a calculator or something
note: all the scripts need to be in one file
Some additions to q3mme fx scripting:
* shadertime to control when shader animations begin
ex:
weapon/rocket/projectile {
model models/powerups/pop.md3
shadertime cgtime / 1000.0 // sets shadertime to current time
// so the shader animation never
// advances
dirModel
}
* soundlocal, soundlistlocal, soundweapon, and soundlistweapon in addition
to sound and souldlist to allow local (not placed inside 3d world) and
weapon (always 'inside player head') channels.
* modulus math operator '%'. Note: both input values are rounded to the nearest integer
* player/head/trail, player/torso/trail, player/legs/trail, player/flight
* the following are passed on to the scripting system where appropriate: team, clientnum (less than 0 signifies non-player), enemy, teammate, ineyes, surfacetype (for impacts). You could have something like custom rails and rockets per team or different settings for enemies and also first person view. See wolfcam-ql/scripts/q3mme.fx for more info.
surfacetype doesn't work that well since the maps only use it occasionally:
surfacetype 1 == metal
2 == wood
3 == dust
4 == snow
* powerup information is passed on to the scripting system where appropriate:
player/torso/trail {
if pwquad { // also pwbattlesuit, pwregen, ...
color 0.2 0.75 1.0
size 200 + rand*32
light
}
}
Available tokens: pwspawnprotection, pwquad, pwbattlesuit, pwhaste, pwinvis,
pwregen, pwflight, pwredflag, pwblueflag, pwneutralflag, pwinvulnerability,
pwscout, pwguard, pwdoubler, pwarmorregn, pwfrozen
* weapon/<weapon name>/impactflesh, also weapon/common/impactflesh
inputs: origin, dir, and end
'origin' is the impact point
'dir' is the reflected bounce direction from missile hits, for
machine gun, chain gun, shotgun, etc.. it's just a random
value
'end' is the direction of the shooter if their position is valid,
otherwise the length of this vector is 0
* 'animFrame' variable added to control model animations, player/[legs|torso|head]/trail automatically set this from current player animation
* additional commands for testing/debugging:
'return' to exit the current script
'continue' to skip the current block (skip to end brace)
'echo <var>' to print a scalar value
* 'command' can be used to send a console command. '%' indicates a script var and the final command will have that script var's value inserted. Use '%%' to print a single percent sign.
Ex:
command echo the value of v00 is %v00
-> will print "the value of v00 is 0.549834" to the console
command echopopup %% t0 is %t0
-> will pop up onscreen message "% t0 is 2.66"
* emitterId float to tag emitters and also, if set to a negative, number will
mark it as low priority (first to be dropped) if the maximum entity is
reached.
Ex:
distance 10.0 {
// check for first person view and tag it
// since 1st and 3rd person gun origin is different. A 1st
// person effect might look bad when you switch to 3rd person.
// You can clear it with: /clearfx 6
if ineyes == 1 { // it's first person view
emitterId 6
}
emitter 0.25 {
// ...
sprite
}
}
/localents
to list fx and local entities
/clearfx [emitter id number]
without id number clears all
* cg_fxDebugEntities (1: print a message when a non low priority entity
needed to be dropped, 2: print a dropped message even for low priority
entities, 3: add on screen display of number of local entities, 4: additional debugging information, -1: only on screen display of number of local entities)
* 'loopcount' as an alternative to 'loop':
repeat 6 {
t0 loop // will go from 0.0 -> 1.0 (0.0, 1.666, ...)
t1 loopcount // will go from 1 to 6 (1, 2, ...)
}
* cullDistance render token and cullDistanceValue variable to prevent rendering of entities far away. Ex:
emitter 2 {
...
cullDistanceValue 400 // set cull value
sprite cullDistance // set sprite to use cullDistanceValue
* some additional trig/math functions: acos, asin, atan, atan2, pow
Note that atan2 and pow have the following syntax:
atan2 val1 val2 // or the following
pow (val1) (val2)
The following syntax is invalid:
pow(10, 2) // invalid
* additional vars that can be read: 'end' (vector) (can also be written), 'cgtime' server time, 'team', 'clientnum', 'enemy', 'teammate', 'ineyes' (is it first person view), 'surfacetype', 'gametype' (see cg_gametype description in ql hud extensions)
* additional vars for reading and writing: t0 up to t9 and v0 up to v9
* impact scripts have the reflected velocity (off surface) in 'velocity', see scripts/dirtest.fx (red stuff is the reflected velocity and blue is 'dir' or the perpendicular vector to the face plane of the struck surface)
* 'emitterf' which lets lerp go from 0.0 to greater than 1.0. checking for lerp >= 1.0 can be used for clean up or to set final values
* 'extraShader', 'extraShaderClear', and 'extraShaderEndTime' for scripts associated with player entities. For 'impactFlesh' scripts these refer to the victim and for other weapon scripts generally the attacker.
* /runfx and /runfxat to run arbitrary scripts and add effects independent of game events and can be used as a generic scripting system
/runfx <fx name> [origin0] [origin1] [origin2] [dir0] [dir1] [dir2] [velocity0] [velocity1] [velocity2]
if origin, dir, or velocity not given, it will use current freecam or 1st person view values.
/runfxat <'now' | server time | clock time> <fx name> [origin0] [origin1] [origin2] [dir0] [dir1] [dir2] [velocity0] [velocity1] [velocity2]
(see 'at' command for time information)
ex: /bind y runfx player/gibbed
ex: /runfx changefov
// fx version of '/cvarinterp cg_fov 0 110 10'
changeFov {
t0 cg_fov
emitterf 10 {
if lerp >= 1.0 {
command cg_fov %t0
return // all done
}
//echo lerp
t1 t0 * lerp
command cg_fov %t1
}
}
Note: /runfix might not work correctly run when the game or demo is paused since fx emitter blocks are not evaulated when paused.
* /runfxall <script name> will run script against all present fx entities
see scripts/alltest.fx :
set cg_fxfile "scripts/alltest.fx"
bind z "runfxall moveup"
/devmap campgrounds
/give all
shoot some lg to generate impact particles and then and hit 'z'
* /listfxscripts
* /printdirvector (prints current viewangles as a dir vector)
Some notes about compatibility with q3mme and some general things:
1) q3mme lists 'cross' as a supported function but it's not implemented in q3mme. You can use this instead:
//cross v0 v1 v2
v20 v11*v22 - v12*v21
v21 v12*v20 - v10*v22
v22 v10*v21 - v11*v20
2) In wolfcamql scripts are not byte compiled or something equivalent so they
run much slower and you might need to be careful with low values of 'distance' and 'interval'. Note that it won't affect how they appear when recording video.
3) 'else' is broken in q3mme. The script will die when it reaches the end of an 'else' block. You can work around it by doing something like this:
t0 time * 2
if loop < 0.5 {
t0 time * 3
}
instead of:
if loop < 0.5 {
t0 time * 3
} else {
t0 time * 2
// q3mme bug -- script will die here
}
4) fps issue:
'interval' and 'distance' used to be triggers, meaning:
weapon/grenade/trail {
//...
interval 0.001 { // if at least this much time has passed, run the following code
//
}
}
but now, in order to be more compatible with q3mme and to reduce timescale and fps issues the total time or distance is split into chunks of the size indicated and the code gets run for each chunk. So, say you have com_maxfps 125, every time the screen gets drawn 8 milliseconds have passed (1000.0 / 125.0) and in earlier versions the code would have been run once (0.008 > 0.001), but now the code will get run 8 times. You can't use 'interval 0' or 'distance 0' any more (see your weapon/grenade/trail).
It's generally better to use 'distance' instead of 'interval' since 'interval' will always be fps and timescale dependent. Imagine the difference between com_maxfps 90 and 30. Projectile positions will be update 3 times more with com_maxfps 90, so if you do something like a trail that just spits out a sprite at origin you'll have 3 sprites clumped together with com_maxfps 30 while com_maxfps 90 will have them spread out.
// test trail
// change around max fps and see how it affects trails
weapon/rocket/trail {
color 1 0 0
green com_mafps / 125.0
alpha 0.33
shader flareShader
rotate 360 * rand
interval 0.012 { // 12 milliseconds
emitter 200 {
alphaFade 0
size 8
sprite
}
}
}
You can fix it be using 'distance' instead. Rockets travel at 900ups, so they will have moved 10.8 (900 * 0.012) game units:
//interval 0.012 { // 12 milliseconds, fps and timescale dependent
distance 10.8 { // will look the same at any fps and timescale
// ...
}
Keep in mind that now that 'interval' and 'distance' blocks can be run multiple times it's now very easy to shoot yourself in the foot. You need to be careful using small values. Using fps 125 the screen is updated every 8 milliseconds so a rocket will move 7.2 (900 * 0.008) units every time the screen is drawn. If you do something like 'distance 0.001 {' the program will freeze as it tries to run that code 7200 times (7.2 / 0.001).
One other issue is using small 'emitter' times as well. If they are too small they might not even be drawn and there's no way around them not being fps and timescale dependent (other than setting a worst case scenario minimum value: cg_fxScriptMinEmitter). Thirty frames per second is common for movies, so that means that emitted entities with lifetimes of less than 33.333_ (1000.0 / 30) milliseconds might not be drawn.
If you have a script that uses small 'emitter' values and you find that it looks well at some low timescale but not at higher ones, you can try to simulate the lower timescale:
//-------------------------------------------------------------
// original version, looks bad at timescale 1.0 and good at
// timescale 0.3
distance rand * 10 {
...
emitter 0.008 * rand {
...
}
}
//-----------------------------------------------------------
change to this:
// script looks good at timescale 0.3 but not at timescale 1.0
// try to simulate 0.3
t0 timescale
t1 1 // random value to check against
if t0 > 0.3 {
t1 1.0 / (t0 / 0.3)
}
distance rand * 10 {
if (rand < t1) { // simulate timescale 0.3
...
emitter 0.008 * rand {
...
}
}
}
5) fx scripting (both q3mme and wolfcamql): don't use multiple 'distance' or 'interval' blocks in scripts. It doesn't break things but wont work as expected:
weapon/rocket/trail {
distance 45 {
// stuff
}
distance 45 { // this wont get run because the last 'distance' block has updated the stored settings about how much the rocket moved
// more stuff
}
6) FIXME -- wolfcamql c-style comments: /* sldkfj */ not supported yet
7) In wolfcamql weapon/*/[fire|trail] uses weapon muzzle point for 'origin' as opposed to player origin in q3mme. The real player origin is passed as 'parentOrigin' for weapon/*/fire scripts. If clientNum < 0 it's a non-player fired
weapon (ex: map grenades in silentnight) and dir, parentOrigin, and parentDir
aren't available.
8) The maximum number of entities for wolfcamql is a little over 16000.
9) The maximum number of dynamic lights for both wolfcamql and q3mme is 32.
You should restrict the use of 'Light' to flash effects, explosions, and
possibly rocket projectiles.
10) wolfcam incompatibility with q3mme fx: In wolfcam scripting for an emitted entity stops once it has been added, so 'impact', 'distance', and 'interval' scripts need to come before 'sprite', 'model', and other rendering directives.
Ex:
emitter 10 {
...
sprite // in wolfcam scripting stops here
distance 50 {
// in wolfcam this is never run, it will run in q3mme
}
//sprite // if it's added here in wolfcam it will now run
}
This is because in q3mme the 'emitter' is the entity and 'sprite' is a directive to draw itself. In wolfcam the 'sprite' is an entity separate from 'emitter'. Ex:
emitter 10 {
...
origin2 origin2 + 100
sprite
...
origin2 origin2 + 100
sprite
...
origin2 origin2 + 100
sprite
...
}
In q3mme this is a 'particle' that will draw itself 3 times in 3 different places at the same time, in wolfcam this creates 3 different and independent 'sprite' particles.
---------------------------------------------------------------
client options:
* You can use really slow timescales (up to 1 millionth of a second: /timescale 0.0000001), for most people you usually couldn't go below 0.1
* com_timescalesafe default 1 high timescales will skip demo snapshots and will break things like camera paths that are synced to server times.
In quake3 with really high timescale values, information from the demo starts to get discarded. You can lose information about frags, chat, etc. Having this set to 1 ensures that all the information (snapshots) in the demo get processed.
* 'fixedtime' cvar can use values less than 1.0
----------------------------------------------------------------
* /clientoverride similar to q3mme
/clientoverride <client number or 'red', 'blue', 'enemy', 'mates', 'us', 'all', 'clear'> <key name> <key value> ... with additional key and value pairs as needed
example: clientoverride 3 model ranger hmodel bones
'clear' option can also be followed by 'red', 'blue', 'enemy', 'mates', 'us', 'all', or a client number. The default is 'all'.
example: clientoverride clear mates
To see what can be changed type /configstrings in the console and scroll up to the player list:
529: n\WolfPlayer\t\1\model\sarge\hmodel\sarge\c1\5\c2\26\hc\100\w\0\l\0\tt\0\tl\0\rp\0\p\0\so\0\pq\0\cn\\su\0
n name
t team
model model
hmodel head model
c1 color1 for rail
c2 color2 for rail
hc handicap
w wins (seen in the old scoreboard for duel)
l losses (seen in the old scoreboard for duel)
cn clan tag
xcn clan name
tt team task (old team arena stuff)
tl team leader (old team arena stuff)
rp ready up status? (qldt)
p ?
so spectator only?
pq player queue
su subscriber (whether the player has a pro or premium account)
c country acronym
The rest I don't remember.
Additionally you can use 'headskin', 'torsoskin', 'legsskin', 'headcolor', 'torsocolor', 'legscolor', 'modelscale', 'legsmodelscale', 'torsomodelscale', 'headmodelscale', 'headoffset', 'modelautoscale' (match this height)
note: skins use model names
ex: /clientoverride 3 hmodel biker headskin xaero/blue
cvar cg_clientOverrideIgnoreTeamSettings setting to 1 will ignore will ignore your settings for things like cg_enemyModel and use the value you set with /clientoverride
----------------------------------------------------------------
/changeconfigstring [force | clear | list] <string number> <new string>
ex: changeconfigstring 3 "Furious Heights" // changes the map name
ex: changeconfigstring force 659 ^6noone
ex: changeconfigstring clear 1
ex: changeconfigstring clear all
ex: changeconfigstring list
3 is map name, 659 is player in first place
'force' option will ignore any changes that occur in the demo and keeps the
value you had set
/cconfigstrings
same as /configstrings but shows strings with overridden values
----------------------------------------------------------------
QuakeLive scripted hud extensions
* you can switch fonts in hud configs, use "font" keyword
* libfreetype2 font support:
Fonts can be set in your hud config and need to have a .ttf extension. Try to avoid putting them in wolfcam-ql/fonts. Ex: copy arial.ttf into wolfcam-ql/myfonts/ and then in your hud config:
// font "fonts/smallfont" 12
// smallFont "fonts/smallfont" 24
// bigFont "fonts/smallfont" 48
font "myfonts/arial.ttf" 12
smallFont "myfonts/arial.ttf" 24
bigFont "myfonts/arial.ttf" 48
q3fonts available as "q3tiny", "q3small", "q3big", "q3giant"
qlfont available as "fontimage"
Fonts can also be used for hud config elements:
itemDef {
name "a"
rect 16 5 63 12
visible 1
textstyle 3
decoration
textscale .45
forecolor 1 1 1 1
ownerdraw CG_PLAYER_AMMO_VALUE
addColorRange 6 999 1 .75 0 1
//font "fontsextra/times.ttf" 48
font "q3small" 48
}
* /loadhud ui/somehud.cfg to avoid having to set cg_hudfiles
* cg_hudRedTeamColor cg_hudBlueTeamColor cg_hudNoTeamColor for use with hud element CG_TEAM_COLORIZED, WCG_[BLUE|RED]_FLAGSTATUS_COLOR, WCG_ONEFLAG_STATUS_COLOR, CG_SELECTED_PLYR_TEAM_COLOR
* cg_hudNeutralTeamColor for use with hud element WCG_ONEFLAG_STATUS_COLOR and neutral flag
* cg_hudForceRedTeamClanTag and cg_hudForceBlueTeamClanTag (edit the team names in score-box)
* allow absolute values for coordinates (see cg_wideScreen)
* hud variables
Anywhere in a hud menu you can use 'setvar @varname (0.8)' to store a value and/or create a variable. You can then use the variable anywhere you would normally use a decimal or integer number. Note: parenthesis, '(' and ')', are required.
ex:
itemDef {
...
setvar @tscale (0.35)
textscale @tscale
...
}
* use math functions and variables to change user created variable values
(same as q3mme fx scripting)
+ - / * %
> < != = (to test equality)
& | (logical AND OR)
sqrt, ceil, floor, sin, cos, wave, clip, acos, asin, atan, atan2, pow
rand (create a random value between 0.0 and 1.0)
crand (create a random value between -1.0 and 1.0)
realtime (system time in milliseconds)
gametime (game/server time in milliseconds)
pi (pi constant)
ownerdrawvalue
ex:
setvar @xscale ((@xscale / 2.0) * rand)
setvar @players (ownerdrawvalue CG_PLAYER_COUNTS)
Note that atan2 and pow have the following syntax:
atan2 val1 val2 // or the following
pow (val1) (val2)
The following syntax is invalid:
pow(10, 2) // invalid
Math processing falls back to trying a cvar if an unknown keyword is found.
ex:
setvar @var (r_fullscreen + @otherVar)
If the cvar doesn't exist an error occurs.
* if/else code blocks within itemDefs (Note: not allowed in higher scopes like menuDef, also menu needs to be visible)
ex:
menuDef_t {
visible 1
itemDef {
...
if (@xscale > 0.35) {
forecolor 1 0 0 1
} else {
forecolor 0 1 0 1
}
...
}
}
* itemDefs can have an optional 'run' script that gets run every screen draw and allows you to change things dynamically
ex:
// silly example that randomly changes the level timer size
itemDef {
name "Timer"
textalign ITEM_ALIGN_LEFT
style 1
rect 0 0 50 12
visible 1
textstyle 3
decoration
forecolor 1 0.64 0.04 .7
ownerdraw CG_LEVELTIMER
run {
setvar @xscale (0.7 * rand)
textscale @xscale
}
}
* itemDef command 'cvarSet' to set a cvar to specified string value
ex: cvarSet tmpCvar "this is a tmpCvar"
* itemdef command 'textExt' to embed script variables and cvar strings into text:
textExt "some text %FORMAT_STRING{SCRIPTVAR_NAME}"
ex:
setvar @numPlayers (ownerdrawvalue CG_PLAYER_COUNTS)
textExt "Number of players: %d{@numPlayers}"
ex:
setvar @speed (ownerdrawvalue CG_SPEEDOMETER)
if (@speed > 320) {
textExt "^1%.2f{@speed} ^7ups"
} else {
textExt "^2%.2f{@speed} ^7ups"
}
ex:
cvarSet myTmpCvar "testing ^3text ^7input"
textExt "show this text: %s{myTmpCvar}"
use '%%' to print a a single '%'
only 'd', 'f', and 'x' accepted as format conversions and a hud script variable is used to get the value
's' will check the string value of a cvar
* itemdef command 'textReset' to remove text entry in menu
* itemdef and menudef command 'backgroundReset' to remove background image
* printval for debugging
ex: printval (@rectWidth)
* itemDef 'visible' can be toggled which might cause incompatibility.
ex:
itemDef {
...
ownerdraw CG_1STPLACE_PLYR_MODEL
visible 1 // in quake live this will make it visible even if you set to '0' later on
visible 0 // ignored in quake live but in wolfcam will disable visibility
...
}
* additional ownerdraws: include ui/wcmenudef.h to use them
WCG_GAMESTATUS
ex:
// quake3 osp style warmup message
setvar @gameStatus (ownerdrawvalue WCG_GAME_STATUS)
if (@gameStatus = W_STATUS_WARMUP) {
font "q3tiny" 48
setvar @fadeTime (900)
setvar @alpha (realtime % (@fadeTime * 2))
if (@alpha > @fadeTime) {
setvar @alpha (1.0 - ((@alpha - @fadeTime) / @fadeTime))
} else {
setvar @alpha (@alpha / @fadeTime)
}
textStyle ITEM_TEXTSTYLE_SHADOWEDMORE
forecolor 1 0 0 @alpha
textExt "Waiting for Players"
}
WCG_WEAPON_SELECTED, WCG_WEAPON_SELECT_TIME, WCG_WEAPON_HAVE_MACHINEGUN, WCG_WEAPON_AMMO_MACHINEGUN, and others to allow creation of custom weapon bars. See wolfcam-ql/ui/wcweaponbar.menu for an example. You can test it in game with '/loadmenu ui/wcweaponbar.menu'.
WCG_KILL_COUNT number of kills since last death or reset ("killcountreset"
command)
WCG_PLAYER_KEY_PRESS_[FORWARD|BACK|RIGHT|LEFT|FIRE|JUMP|CROUCH]
WCG_PLAYER_OBIT same as CG_PLAYER_OBIT but supports align value
WCG_AREA_NEW_CHAT same as CG_AREA_NEW_CHAT but supports align value
WCG_ONEFLAG_STATUS_COLOR same as CG_ONEFLAG_STATUS but colorizes the icon according to cg_hud[Blue|Red|No]TeamColor
WCG_ROUNDTIMER same as CG_ROUNDTIMER but it doesn't ignore text color and alpha
WCG_FOLLOW_PLAYER_NAME_EX same as CG_FOLLOW_PLAYER_NAME_EX but it doesn't colorize name in team games
WCG_1ST_PLYR_READY same as CG_1ST_PLYR_READY without status text
WCG_2ND_PLYR_READY same as CG_2ND_PLYR_READY without status text
WCG_REAL_PLAYER_HEAD draw real player head/icon without substituting team color skins
* cg_gametype variable checking corresponds to quake with additional support for quake3 and cpma gametypes:
0 ffa
1 duel
2 race
3 team death match
4 clan arena
5 ctf
6 one flag ctf
7 obelisk
8 harvester
9 freezetag
10 domination
11 capture strike (ctfs), attack / defend
12 red rover
13 cpma 'not team fortress'
14 cpma 2v2
15 cpma hoony mode
16 quake3 single player
* ownerdraws removed in Aug 27, 2014 quakelive update can still be referenced by including ui/wcmenudef.h
* /loadmenu [menu file]
To test / debug individual menu files.
----------------------------------------------------------------
* cg_quadFireSound to enable/disable the extra sound effect when a player with quad power-up fires their weapon
* cg_animationsIgnoreTimescale animations will play in real-time regardless of what timescale setting is. Default is 0.
* cg_animationsRate you can speed up (> 1.0) or slow down animations (< 1.0). Default is 1.0 .
* cg_markTime and cg_markFadeTime to control wall/floor impact marks
* s_useTimescale adjust audio pitch according to timescale
* s_forceScale force audio to scale pitch
* s_showMiss debug cvar to show skipped sounds (1: skipped because of max repeat rate, 2: also show if it was skipped because of max number of sounds being played, >2: show if sound channel couldn't be allocated)
* s_show >2 will only output when a sound is played
* s_maxSoundRepeatTime skip playing a sound if it is repeated this often in milliseconds (default is 0 to match quakelive, q3 is 50) Noticeable with lg hit beeps
* s_maxSoundInstances (96: default similar to quake live, -1: q3 code which limits either 4 or 8 sounds attached to an entity -- with the bug of the 3d world counting as an entity)
* s_qlAttenuate (0: q3 style -- use smaller distance for sound volume calculation and always play at full volume sounds within 80 game units, 1: default calculate sound volumes like quake live)
* s_debugMissingSounds
* cg_audioAnnouncer (0: disable audio announcer, 1: Vadrigar (Classic), 2: Daemia (Female), 3: new ql announcer)
* cg_ignoreServerPlaySound disable/enable server 'playsound' command. Used with 'crash' tutorial and minqlx custom sounds.
------------------------------------------------------------
Audio messages not dependent on cg_draw2d, use:
cg_audioAnnouncerRewards
cg_audioAnnouncerRound "round begins in ... fight!", "blue wins the round", ...
cg_audioAnnouncerWarmup "3 2 1 fight!", ...
cg_audioAnnouncerVote
cg_audioAnnouncerTeamVote
cg_audioAnnouncerFlagStatus
cg_audioAnnouncerTimeLimit time limit warnings
cg_audioAnnouncerFragLimit frag limit warnings
cg_audioAnnouncerWin
cg_audioAnnouncerScore "red scores", ...
cg_audioAnnouncerLastStanding
cg_audioAnnouncerDominationPoint
cg_audioAnnouncerPowerup powerup pickup
cg_audioAnnouncerLead "taken the lead", "tied", ...
setting this to '2' enables lead announcements in Red Rover game type
* cg_audioAnnouncerRoundReward to enable/disable end of round 'perfect' or 'denied' announcements
* cg_audioAnnouncerRewardsFirst enable first reward having a unique voice over