Compare commits
525
Commits
nomobjshadows
..
v7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0544811c7d | ||
|
|
e079bac283 | ||
|
|
862f1fce2c | ||
|
|
5aeb78f2a5 | ||
|
|
cb42bc581b | ||
|
|
5fc9410b59 | ||
|
|
84d3ee7170 | ||
|
|
accef8f1e1 | ||
|
|
4a8edff694 | ||
|
|
aac3b8d025 | ||
|
|
4034658e44 | ||
|
|
7d4898dd8b | ||
|
|
71fe6ec9da | ||
|
|
075097c219 | ||
|
|
f70ec60ae4 | ||
|
|
aeafd46f24 | ||
|
|
5f57044118 | ||
|
|
65006c11d3 | ||
|
|
76bc184f6c | ||
|
|
dd39a444f2 | ||
|
|
1a16012a5c | ||
|
|
c49aae8d49 | ||
|
|
d5dc52d3d3 | ||
|
|
4f1f1ede97 | ||
|
|
c98b896fc8 | ||
|
|
3714735c2a | ||
|
|
025cc093db | ||
|
|
924d79c20d | ||
|
|
0926f68776 | ||
|
|
26f3806b3c | ||
|
|
d628320c8d | ||
|
|
41fc4c7cfd | ||
|
|
1c8ca2b110 | ||
|
|
241d107485 | ||
|
|
8d0601c2ad | ||
|
|
31118254a0 | ||
|
|
85a1636776 | ||
|
|
3b227932e9 | ||
|
|
ff591bce04 | ||
|
|
c3a03d89c4 | ||
|
|
dd405532af | ||
|
|
677cdc77e4 | ||
|
|
f9463d8efa | ||
|
|
77c9badeca | ||
|
|
926287eb97 | ||
|
|
7a91b19962 | ||
|
|
c148ff5a05 | ||
|
|
ef7e658f9d | ||
|
|
0e9b9d15ea | ||
|
|
dd2d437a21 | ||
|
|
b9779d4dba | ||
|
|
1d40d8c4ef | ||
|
|
847b1f5cb7 | ||
|
|
9448a98573 | ||
|
|
14bce36b95 | ||
|
|
ba4c54004a | ||
|
|
9fdfc09229 | ||
|
|
b19bc7d77e | ||
|
|
58815ae9c4 | ||
|
|
0b12c9b5a8 | ||
|
|
863abe86ca | ||
|
|
f54d2fb0fe | ||
|
|
8824ba3824 | ||
|
|
8a8db796be | ||
|
|
4f532b766f | ||
|
|
e175a4e00b | ||
|
|
473e843142 | ||
|
|
ef8e71cb11 | ||
|
|
ea985151dd | ||
|
|
62fae0ad8b | ||
|
|
f9210ee3bc | ||
|
|
d5101dd0b2 | ||
|
|
2a7940bfd1 | ||
|
|
047d38daab | ||
|
|
2d61f5c861 | ||
|
|
750f305c46 | ||
|
|
51b79e58d3 | ||
|
|
915b4e9d15 | ||
|
|
c9c0c06763 | ||
|
|
406037dabe | ||
|
|
d9affe2331 | ||
|
|
6df675523f | ||
|
|
65e66e8ace | ||
|
|
5efb0c7136 | ||
|
|
1793340474 | ||
|
|
d10db6d1d2 | ||
|
|
9eefbcea72 | ||
|
|
d56b70a8e7 | ||
|
|
54ebb9dfec | ||
|
|
43b6597ec0 | ||
|
|
b7d887d610 | ||
|
|
ff9b35ab45 | ||
|
|
20b5175180 | ||
|
|
596c8e2ecc | ||
|
|
94218a6549 | ||
|
|
2d36f798e7 | ||
|
|
853004dad9 | ||
|
|
0cc86430ca | ||
|
|
8760886f57 | ||
|
|
821669d03d | ||
|
|
17f8996afc | ||
|
|
7ef4eedd06 | ||
|
|
df6a31767e | ||
|
|
882a3b7824 | ||
|
|
94ddd01427 | ||
|
|
e614decae0 | ||
|
|
e0f46ea80d | ||
|
|
3391018606 | ||
|
|
61fd11f7cd | ||
|
|
4a469aebdc | ||
|
|
341815c0ed | ||
|
|
5830270bda | ||
|
|
8a1ff58dff | ||
|
|
0523d98a1c | ||
|
|
983af4e7a1 | ||
|
|
f8bec7296c | ||
|
|
2be4bd3d6a | ||
|
|
7d74296604 | ||
|
|
0504a355d2 | ||
|
|
036df817f1 | ||
|
|
ba331caff6 | ||
|
|
e2ac9708cb | ||
|
|
783ce7bada | ||
|
|
594931e07e | ||
|
|
3e245d49d8 | ||
|
|
76ed4aae12 | ||
|
|
565f36d4b7 | ||
|
|
75a94b050d | ||
|
|
91fac0880d | ||
|
|
42fa29f78b | ||
|
|
28d8e84d6b | ||
|
|
c11d925580 | ||
|
|
d7c1b12dbd | ||
|
|
e2c3d5b20d | ||
|
|
8581d87e41 | ||
|
|
fe853d4bee | ||
|
|
b8038130b8 | ||
|
|
31c5d8d67c | ||
|
|
a2f4430378 | ||
|
|
a8e4f6e2ea | ||
|
|
aac89f270b | ||
|
|
9022e02ccd | ||
|
|
5ddd2e4fbc | ||
|
|
3b500add73 | ||
|
|
4a6635f8a8 | ||
|
|
af6393af50 | ||
|
|
6a14543e9e | ||
|
|
3d827570e6 | ||
|
|
9f8eb07442 | ||
|
|
31c64b63de | ||
|
|
cf5c0ca5f7 | ||
|
|
f0d91a9708 | ||
|
|
0f94a26dc6 | ||
|
|
cded0af061 | ||
|
|
fffa7e44c5 | ||
|
|
a38aee7fe3 | ||
|
|
4d03fa06e1 | ||
|
|
dcd470b2e1 | ||
|
|
2259ef3f71 | ||
|
|
af18e2b7d1 | ||
|
|
9e8d79f246 | ||
|
|
5b480be6dc | ||
|
|
54d897fc33 | ||
|
|
cfebe422d3 | ||
|
|
fcc5c13274 | ||
|
|
707448193b | ||
|
|
84a1f86037 | ||
|
|
b2129011c2 | ||
|
|
9d359ef8c5 | ||
|
|
87a2b74a88 | ||
|
|
d5388e8dad | ||
|
|
fe7677c5c8 | ||
|
|
f36ac0bb4b | ||
|
|
d24bcc9fd7 | ||
|
|
daf8151a32 | ||
|
|
b432491d34 | ||
|
|
1313b4c112 | ||
|
|
164d7399d2 | ||
|
|
87176cfd0b | ||
|
|
bab96b73e0 | ||
|
|
f10db3900a | ||
|
|
7d4b1d0852 | ||
|
|
6ab99218f2 | ||
|
|
1959edf357 | ||
|
|
6fc2681b34 | ||
|
|
02dcf85c46 | ||
|
|
89f0521cce | ||
|
|
35029e826f | ||
|
|
f6c170b53c | ||
|
|
7991a5ce5e | ||
|
|
3973851dd2 | ||
|
|
f6361e29bd | ||
|
|
9f8db631f0 | ||
|
|
ada1de7ad6 | ||
|
|
ac55d473e7 | ||
|
|
2100f11af7 | ||
|
|
ea1b5cd1a9 | ||
|
|
e100fff230 | ||
|
|
5393ac526a | ||
|
|
808f7baf53 | ||
|
|
35f54822be | ||
|
|
94714fe571 | ||
|
|
5bdf8698bd | ||
|
|
2398e60e89 | ||
|
|
b4e563bfd6 | ||
|
|
a56ce09923 | ||
|
|
68c7a6bd93 | ||
|
|
b4612d6bd4 | ||
|
|
c2cfc96d87 | ||
|
|
8db99291ac | ||
|
|
c9aa764444 | ||
|
|
ee4869993d | ||
|
|
0758cf39c2 | ||
|
|
bb0c777cac | ||
|
|
0bd2c49dae | ||
|
|
d25c6fa0b2 | ||
|
|
8f2d36aab0 | ||
|
|
6c764a8487 | ||
|
|
dd6056a07a | ||
|
|
a83d364ba7 | ||
|
|
9c4b2b0abf | ||
|
|
4235801ae4 | ||
|
|
6791f2e883 | ||
|
|
caeec35c66 | ||
|
|
7b95df150a | ||
|
|
852651cefe | ||
|
|
22b9915ad7 | ||
|
|
0f994a0676 | ||
|
|
5d68fd690b | ||
|
|
c55bc6db4d | ||
|
|
a77d8b4762 | ||
|
|
23596d2516 | ||
|
|
352b958da1 | ||
|
|
e9f2ef1422 | ||
|
|
7baa711744 | ||
|
|
65e274a65f | ||
|
|
a874691bce | ||
|
|
d60d101e75 | ||
|
|
8d9a648dce | ||
|
|
2332cc76ee | ||
|
|
5c3a2bf5be | ||
|
|
5e2b50c49e | ||
|
|
3a56bf2bb5 | ||
|
|
3f4afb604a | ||
|
|
77a2976d05 | ||
|
|
0eda508cf6 | ||
|
|
4301e0f750 | ||
|
|
c5eb81c26a | ||
|
|
47d3cf3e62 | ||
|
|
41dc34efe8 | ||
|
|
4acbca4c8f | ||
|
|
11329d5794 | ||
|
|
b0880607d4 | ||
|
|
2afa18bbdd | ||
|
|
acad230daa | ||
|
|
49fcf3e486 | ||
|
|
acb0144742 | ||
|
|
6efc8fdad3 | ||
|
|
c75e6ba63c | ||
|
|
7bd1808c88 | ||
|
|
fe8e00895a | ||
|
|
9dc5e3d338 | ||
|
|
694c1ad808 | ||
|
|
754b028623 | ||
|
|
4423fb300f | ||
|
|
5c7d9327e3 | ||
|
|
cd72bce3cb | ||
|
|
64ef0465d5 | ||
|
|
fe6ad4f762 | ||
|
|
4b69b39d39 | ||
|
|
a6fc237c88 | ||
|
|
2448a0b735 | ||
|
|
685220140a | ||
|
|
99779629d0 | ||
|
|
9fceabed8f | ||
|
|
e11363db3a | ||
|
|
023cade51d | ||
|
|
d675b98330 | ||
|
|
b3f16e935d | ||
|
|
5b9e179017 | ||
|
|
6f53263107 | ||
|
|
fd797436fa | ||
|
|
96ee117657 | ||
|
|
8b60fb6b6c | ||
|
|
67542d3cf1 | ||
|
|
41e97ffa79 | ||
|
|
ffcff99a79 | ||
|
|
48bcaacada | ||
|
|
01b060b0fe | ||
|
|
51ce092a6a | ||
|
|
d09e02721b | ||
|
|
88b81aa28b | ||
|
|
84c4f4f428 | ||
|
|
ab5bc92a95 | ||
|
|
b44dd3edf0 | ||
|
|
80498a78ea | ||
|
|
40663eb2b5 | ||
|
|
dca2827154 | ||
|
|
eec069b4e8 | ||
|
|
26eedc3341 | ||
|
|
b19cefee3c | ||
|
|
fb54b969d1 | ||
|
|
034724b03e | ||
|
|
b80762eaf5 | ||
|
|
d5258786e5 | ||
|
|
9bfe2d3138 | ||
|
|
ae3b3f750d | ||
|
|
f83090e299 | ||
|
|
3e4f497cbc | ||
|
|
ce2398fdb7 | ||
|
|
f545cce6fe | ||
|
|
f614725fcb | ||
|
|
59e4f9ce4a | ||
|
|
dff6b15263 | ||
|
|
977ee8ccfc | ||
|
|
161815e6fb | ||
|
|
8dda864909 | ||
|
|
f6f9542d6e | ||
|
|
6655c0d881 | ||
|
|
98c8176d59 | ||
|
|
2e7f64458d | ||
|
|
d6a9cdc452 | ||
|
|
17dbe77cd3 | ||
|
|
4b71d9a48d | ||
|
|
1f41cb9a3f | ||
|
|
c6351c6c53 | ||
|
|
283218f2d6 | ||
|
|
4de22e9d66 | ||
|
|
b4a737d910 | ||
|
|
0f2c17324a | ||
|
|
6a1b10eaf9 | ||
|
|
824211c2f6 | ||
|
|
02d115f119 | ||
|
|
b44617413b | ||
|
|
c447f25e0a | ||
|
|
34ce92d9fa | ||
|
|
7ad5dc61ac | ||
|
|
7072332ab7 | ||
|
|
60e933eb00 | ||
|
|
43e3d07acb | ||
|
|
228252ee6f | ||
|
|
56a919eb60 | ||
|
|
bfcb906b12 | ||
|
|
b94776063f | ||
|
|
3f412373bc | ||
|
|
e7d1858052 | ||
|
|
bd106308fc | ||
|
|
6ec96b37bd | ||
|
|
3653786e14 | ||
|
|
5824d9e803 | ||
|
|
3ad3cdfa38 | ||
|
|
efcd1df365 | ||
|
|
aef62c45de | ||
|
|
94bd1cb37b | ||
|
|
f7bf3fe510 | ||
|
|
a771ebf0e8 | ||
|
|
6b4d02ae99 | ||
|
|
3e6cab1ec9 | ||
|
|
147c59c26b | ||
|
|
db6f76d12d | ||
|
|
86950c26d0 | ||
|
|
e1d4f10223 | ||
|
|
01c1ae42a1 | ||
|
|
550871f576 | ||
|
|
56fcca1f6b | ||
|
|
930bde785c | ||
|
|
13aadc41ff | ||
|
|
ea4998f666 | ||
|
|
6f0e92e0d1 | ||
|
|
a4085cb155 | ||
|
|
b7e77e10b6 | ||
|
|
8f195530b5 | ||
|
|
048ccf52b0 | ||
|
|
df9ad5a31f | ||
|
|
0b3284e23c | ||
|
|
36d598440a | ||
|
|
9cc42e6430 | ||
|
|
3f5c19bffd | ||
|
|
800dbf5e78 | ||
|
|
2b5db9ff3f | ||
|
|
b07c8848ca | ||
|
|
9bff8dd91f | ||
|
|
19eee66c39 | ||
|
|
fbf7be8808 | ||
|
|
fcda4c1188 | ||
|
|
deae234afa | ||
|
|
82e33fd4e4 | ||
|
|
15914c2f25 | ||
|
|
da64d3ccbf | ||
|
|
79a5d174a5 | ||
|
|
295d9768ce | ||
|
|
9490b1235d | ||
|
|
55eb984ccd | ||
|
|
4b1a82e14e | ||
|
|
3c224923e9 | ||
|
|
2c4f5a68b9 | ||
|
|
d324c917ad | ||
|
|
bd8ff77fe0 | ||
|
|
35d40e1d37 | ||
|
|
e9e281fd2a | ||
|
|
2437c5a19a | ||
|
|
b9b4de929d | ||
|
|
28fc55b653 | ||
|
|
8f4df0ceca | ||
|
|
ecde8a5e8b | ||
|
|
715b106c9e | ||
|
|
2114afa536 | ||
|
|
c78816a8d1 | ||
|
|
28516c4833 | ||
|
|
837ed3535d | ||
|
|
bcb332e88f | ||
|
|
f4be7a8034 | ||
|
|
e69413f1e8 | ||
|
|
ee6dcfc678 | ||
|
|
d4370a1811 | ||
|
|
babf4ca06a | ||
|
|
ccf0905469 | ||
|
|
970130e02b | ||
|
|
6088fa5134 | ||
|
|
33bc484d69 | ||
|
|
6bf113d0ff | ||
|
|
630d910a9e | ||
|
|
3c70963f56 | ||
|
|
4c4f6f6d80 | ||
|
|
f949fa54af | ||
|
|
17a5c6ed06 | ||
|
|
e6359663b1 | ||
|
|
405cef6a01 | ||
|
|
d4886f8923 | ||
|
|
c5ec61baa5 | ||
|
|
7a9ffa7ee8 | ||
|
|
5ff665a073 | ||
|
|
3d4e078a90 | ||
|
|
8ef613ef9b | ||
|
|
988a672dea | ||
|
|
cca9c51315 | ||
|
|
18aa3689d9 | ||
|
|
59ab6572b1 | ||
|
|
b6cf933159 | ||
|
|
48f36ca8f3 | ||
|
|
fea89de037 | ||
|
|
e2f1dd1ce8 | ||
|
|
48ac3353cb | ||
|
|
63015c3a93 | ||
|
|
c7bd402e54 | ||
|
|
0c6f9b6cc1 | ||
|
|
b5d7b84c1e | ||
|
|
cbbde8dea5 | ||
|
|
58dd0b7591 | ||
|
|
d9f2535402 | ||
|
|
66eb201466 | ||
|
|
edbf20d975 | ||
|
|
711d7dcfcc | ||
|
|
219979e20b | ||
|
|
27917a0e85 | ||
|
|
4b4b2d5cbc | ||
|
|
8d968d7f89 | ||
|
|
9090a5cd73 | ||
|
|
59a50994b8 | ||
|
|
ac99a6ac3c | ||
|
|
fa2257ad3b | ||
|
|
66ce0871bc | ||
|
|
c59564723c | ||
|
|
606717d253 | ||
|
|
f73e84e0ad | ||
|
|
fc01453544 | ||
|
|
d37a1c799f | ||
|
|
3456ef96a7 | ||
|
|
40143375fc | ||
|
|
7f34a1d83e | ||
|
|
2316c117b1 | ||
|
|
31b7482c3a | ||
|
|
0974625769 | ||
|
|
266f5149b5 | ||
|
|
008a9b9b3f | ||
|
|
ec2fd5b38f | ||
|
|
d449a1b714 | ||
|
|
0bd5ca5e3f | ||
|
|
06248e5388 | ||
|
|
9c5a0ed7ee | ||
|
|
b199354167 | ||
|
|
74ce725e3d | ||
|
|
3d5e033158 | ||
|
|
ca58c1dee2 | ||
|
|
d51a69b052 | ||
|
|
1a96d96837 | ||
|
|
2e7cd51ff8 | ||
|
|
112716dae5 | ||
|
|
c13e780f29 | ||
|
|
c35887f5ee | ||
|
|
2f55c10ce3 | ||
|
|
0068312ce3 | ||
|
|
ea49d92932 | ||
|
|
efe7dd23b6 | ||
|
|
3a1a58bcfc | ||
|
|
953862f133 | ||
|
|
41eb2ee969 | ||
|
|
225ecce676 | ||
|
|
335b10a694 | ||
|
|
967220178c | ||
|
|
be7461ad51 | ||
|
|
5af7cf850a | ||
|
|
86395d4d8b | ||
|
|
3412bb5380 | ||
|
|
d66e7e660d | ||
|
|
07d631e320 | ||
|
|
6ffb50530d | ||
|
|
bd7103d109 | ||
|
|
4abc2ab5bd | ||
|
|
f8a8b8ac6e | ||
|
|
cfe6e08168 | ||
|
|
5139259037 | ||
|
|
1503daf02b | ||
|
|
4246e42948 | ||
|
|
9b3eaa6fe8 | ||
|
|
716685d809 | ||
|
|
dd72871ba6 | ||
|
|
ea510f95b8 | ||
|
|
9de3db7c97 | ||
|
|
0e927ce4bd | ||
|
|
1747ebf481 | ||
|
|
da9d57a624 | ||
|
|
086d0113c5 | ||
|
|
8cf6050d10 | ||
|
|
b310168c12 |
No files matched your search
Executable
+346
@@ -0,0 +1,346 @@
|
||||
#!/bin/bash
|
||||
set -e # Enable auto-exit for debugging :))
|
||||
|
||||
# Make Linux AppImage program data
|
||||
# https://docs.appimage.org/reference/appdir.html
|
||||
|
||||
# PWD: {repo_root}/build
|
||||
# See deployer.sh for usage
|
||||
|
||||
# Terminal stuff
|
||||
RESET="$(tput sgr0)" #"\e[0m" # Resets terminal colors
|
||||
|
||||
# Colors for various information types
|
||||
FAILURE="$(tput setaf 1)" #"\e[91m"
|
||||
SUCCESS="$(tput setaf 2)" #"\e[92m"
|
||||
NOTICE="$(tput setaf 3)" #"\e[93m"
|
||||
VERBOSE="$(tput setaf 4)" #"\e[94m"
|
||||
|
||||
verbosity=0 # By default don't print anything unless it's *ultra* important.
|
||||
quiet=0 # Also don't print anything if they supplied the quiet argument
|
||||
|
||||
# URL from which to download appimagetool if there isn't one available in your $PATH
|
||||
# at time of writing only aarch64, armhf, i686, and x86_64 versions are available via this method
|
||||
# in those cases, and honestly even outside of those cases, it's better to just put a working one in your $PATH yourself..
|
||||
url="https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$(uname -m).AppImage"
|
||||
|
||||
# A whitelist of libraries to include into SRB2's AppImage if SRB2 is dynamically linked.
|
||||
# please don't add a newline at the end of this or i will cry :(
|
||||
libraryWhitelist="
|
||||
libbacktrace
|
||||
libnsl
|
||||
libSDL2
|
||||
libSDL2_mixer
|
||||
libgme
|
||||
libopenmpt
|
||||
libpng
|
||||
libfluidsynth
|
||||
libpulse
|
||||
libmodplug
|
||||
libvorbisfile
|
||||
libopusfile
|
||||
libFLAC
|
||||
libmad
|
||||
libmpg123
|
||||
libvorbis
|
||||
libpulsecommon
|
||||
libsndfile
|
||||
libsndio
|
||||
libogg
|
||||
libvorbisenc
|
||||
libjson
|
||||
libreadline
|
||||
libwrap
|
||||
libtinfo
|
||||
libtirpc
|
||||
libpng16"
|
||||
|
||||
# these kinda look like macros don't they
|
||||
function print { (( "$quiet" == 0 )) && echo "$@" || :; } # echo if not quiet
|
||||
function coloredText { printf "$1"; print "${@:2}"; printf "$RESET"; } # use print to inherit quiet
|
||||
function success { coloredText "$SUCCESS" "$@"; } # use coloredText to inherit quiet
|
||||
function important { coloredText "$NOTICE" "$@"; } # use coloredText to inherit quiet
|
||||
function verboseOnly { (( "$verbosity" >= $1 )) && (coloredText "$VERBOSE" "${@:2}") || :; } # use coloredText to inherit quiet
|
||||
|
||||
# Parses an argument with a single dash
|
||||
function parseSingleDashArg() {
|
||||
while read -n 1 char; do
|
||||
if [[ "$char" == '-' || "$char" == '' ]]; then
|
||||
:
|
||||
elif [[ "$char" == 'h' ]]; then
|
||||
helppassed=1
|
||||
elif [[ "$char" == 'q' ]]; then
|
||||
quiet=1
|
||||
elif [[ "$char" == 'v' ]]; then
|
||||
verbosity="$((verbosity + 1))"
|
||||
elif [[ "$char" == 'd' ]]; then
|
||||
dry=1
|
||||
elif [[ "$char" == 's' ]]; then
|
||||
small=1
|
||||
else
|
||||
echo "$0: invalid option -- '$1'"
|
||||
echo "Try '$0 --help' for more information."
|
||||
return 1
|
||||
fi
|
||||
done <<<"$1"
|
||||
}
|
||||
|
||||
# Simple help argument checker.
|
||||
currentarg=1; # Which argument is --help...
|
||||
|
||||
# For $arg in the argument array...
|
||||
for arg in "$@"; do
|
||||
# Is it a help argument?
|
||||
if [[ "$arg" == "--help" ]]; then
|
||||
helppassed=1; # Help is passed, set $helppassed!
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}" # Remove argument from list
|
||||
elif [[ "$arg" == "--quiet" ]]; then
|
||||
quiet=1
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
|
||||
elif [[ "$arg" == "--verbose" ]]; then
|
||||
verbosity="$((verbosity + 1))" # Increase verbosity!
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
|
||||
elif [[ "$arg" == "--dry" ]]; then
|
||||
dry=1; # Show parameters instead of using them.
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
|
||||
elif [[ "$arg" == "--small" ]]; then
|
||||
small=1; # Don't copy assets to save on bandwidth.
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}"
|
||||
elif [[ ! "$arg" == *'--'* && "$arg" == *'-'* ]]; then
|
||||
parseSingleDashArg "$arg"
|
||||
|
||||
if [[ "$?" == 0 ]]; then
|
||||
set -- "${@:1:$currentarg-1}" "${@:$currentarg+1}" # Remove argument from list
|
||||
fi
|
||||
elif [[ $arg == *'--'* ]]; then
|
||||
print "$0: invalid option -- '$1'"
|
||||
print "Try '$0 --help' for more information."
|
||||
return 1
|
||||
else
|
||||
currentarg="$((currentarg+1))" # Increment current argument number otherwise...
|
||||
fi
|
||||
done
|
||||
|
||||
important "SRB2Kart AppImage Packager v1.0 modified for kart by NepDisk."
|
||||
important "Orignal for SRB2 my mazmazz and Golden."
|
||||
|
||||
# Get root directory from the full path of this script.
|
||||
__ROOT_DIR="$3"
|
||||
|
||||
if [[ -z "$3" ]]; then
|
||||
# finds out where this script is and goes to that directory and goes up one for the root
|
||||
|
||||
scriptdir="$(dirname "${BASH_SOURCE[0]}")"
|
||||
scriptbase="$(basename "${BASH_SOURCE[0]}")"
|
||||
|
||||
__ROOT_DIR="$(cd "$scriptdir" && pwd -P)"
|
||||
fi
|
||||
|
||||
# If it starts with '.', put the current working directory behind it so things work.
|
||||
if [[ "$__ROOT_DIR" == '.' || "$__ROOT_DIR" == '..' ]]; then
|
||||
__ROOT_DIR="$PWD/$__ROOT_DIR"
|
||||
fi
|
||||
|
||||
# Set up defaults
|
||||
__PROGRAM_NAME="${PROGRAM_NAME:-"SRB2Kart Saturn"}"
|
||||
__PROGRAM_DESCRIPTION="${PROGRAM_DESCRIPTION:-"Modded version of SRB2kart with more features."}"
|
||||
__PROGRAM_FILENAME="${PROGRAM_FILENAME:-"lsdl2srb2kart"}"
|
||||
__PROGRAM_ASSETS="${PROGRAM_ASSETS:-"$__ROOT_DIR/assets/installer"}"
|
||||
|
||||
__BUILD_DIR="${1:-"$__ROOT_DIR/bin"}"
|
||||
__OUTPUT_FILENAME="${2:-"$__PROGRAM_FILENAME.AppImage"}"
|
||||
|
||||
__APPIMAGETOOL="${4:-"appimagetool"}"
|
||||
|
||||
if (! command -v "$__APPIMAGETOOL" &> /dev/null); then
|
||||
__APPIMAGETOOL=
|
||||
fi
|
||||
|
||||
# Stuff that prints and exits.
|
||||
|
||||
# Prints setup text using method given by arguments.
|
||||
# Example: printSetup "print" # print "Setup for AppImage...
|
||||
function printSetup {
|
||||
$@ "Setup for AppImage in BUILD_DIR: '$__BUILD_DIR'..."
|
||||
$@ "With the OUTPUT_FILENAME: '$__OUTPUT_FILENAME'"
|
||||
$@ "And SRB2 Repository Root ROOT_DIR: '$__ROOT_DIR'"
|
||||
$@ "Using APPIMAGETOOL: '$([ -z "$__APPIMAGETOOL" ] && echo '(download)' || echo $__APPIMAGETOOL)'"
|
||||
$@ ""
|
||||
$@ "This should be run from a Makefile or from the directory of the build. If it is not, then change to that directory or specify that directory as an argument."
|
||||
$@ "If ROOT_DIR isn't SRB2's repository root, specify that as an argument too."
|
||||
$@ "Make must have built the program before you run this script."
|
||||
$@ ""
|
||||
$@ "Make sure these Environment Variables are correct."
|
||||
$@ "If not, then enter: export PROGRAM_VARIABLE=value"
|
||||
$@ "PROGRAM_NAME: $__PROGRAM_NAME"
|
||||
$@ "PROGRAM_DESCRIPTION: $__PROGRAM_DESCRIPTION"
|
||||
$@ "PROGRAM_FILENAME: $__PROGRAM_FILENAME"
|
||||
$@ "PROGRAM_ASSETS: $__PROGRAM_ASSETS"
|
||||
}
|
||||
|
||||
if [[ "$helppassed" ]]; then
|
||||
print "Usage: $(basename "$0") [OPTION]... [BUILD_DIR] [OUTPUT_NAME] [ROOT_DIR] [APPIMAGETOOL]"
|
||||
print "Packages a SRB2 binary into an AppImage."
|
||||
print "OPTIONs may be included anywhere within the arguments."
|
||||
print ""
|
||||
print "Arguments:"
|
||||
print " -h, --help display this help and exit."
|
||||
print " -q, --quiet don't display any text."
|
||||
print " -v, --verbose make commands more verbose, will always print."
|
||||
print " -s, --small don't copy SRB2 assets to save on bandwidth."
|
||||
print " parameters regardless of --dry."
|
||||
print " -d, --dry print parameters and exit."
|
||||
print ""
|
||||
if (( "$verbosity" > 0 )) || [[ "$dry" ]]; then
|
||||
printSetup "print"
|
||||
else
|
||||
print "This should be run from a Makefile or from the directory of the build."
|
||||
print "Make must have built the program before you run this script."
|
||||
fi
|
||||
exit;
|
||||
fi
|
||||
|
||||
if (( "$verbosity" > 0 )) || [[ "$dry" ]]; then
|
||||
printSetup "verboseOnly" "0"
|
||||
verboseOnly 0 ""
|
||||
|
||||
if [[ "$dry" ]]; then
|
||||
set -n # Enable debug mode and verbose for dry run.
|
||||
fi
|
||||
fi
|
||||
|
||||
# End stuff that prints and exits.
|
||||
|
||||
if (( "$verbosity" >= 4 )); then
|
||||
set -v # Really verbose? Print *everything*!
|
||||
fi
|
||||
|
||||
# Define AppDir structure
|
||||
mkdir -p "$__BUILD_DIR/AppDir/usr/bin"
|
||||
mkdir -p "$__BUILD_DIR/AppDir/lib"
|
||||
mkdir -p "$__BUILD_DIR/AppDir/usr/share/applications"
|
||||
mkdir -p "$__BUILD_DIR/AppDir/usr/share/icons/hicolor/256x256/apps"
|
||||
|
||||
# Copy program data
|
||||
if [[ ! $small ]]; then
|
||||
verboseOnly 1 "Packaging program assets..."
|
||||
cp -r "$__PROGRAM_ASSETS"/* "$__BUILD_DIR/AppDir/usr/bin/"
|
||||
cp -r "$__BUILD_DIR/$__PROGRAM_FILENAME" "$__BUILD_DIR/AppDir/usr/bin"
|
||||
else
|
||||
verboseOnly 1 "Skipping program asset packing, --small or -s passed..."
|
||||
fi
|
||||
|
||||
verboseOnly 1 "Packaging SRB2..."
|
||||
verboseOnly 1 "Assuming executable name $__PROGRAM_FILENAME"
|
||||
cp -r "$__BUILD_DIR/$__PROGRAM_FILENAME" "$__BUILD_DIR/AppDir/usr/bin"
|
||||
|
||||
# Copy required dependencies, but only if the program is dynamically linked.
|
||||
verboseOnly 1 "Testing if this build is dynamically linked..."
|
||||
|
||||
set +e # Disable auto-exit for ldd.
|
||||
|
||||
srb2Libraries="$(ldd "$__BUILD_DIR/$__PROGRAM_FILENAME")"
|
||||
exitcode="$?"
|
||||
|
||||
set -e # Enable it again!
|
||||
|
||||
if (( $exitcode == 0 )); then
|
||||
verboseOnly 1 "This build *is* dynamically linked! Packaging dependencies."
|
||||
|
||||
# read the dynamic libraries of srb2, trim off beginning whitespace, and get the third field seperated by spaces
|
||||
# this gives us a newline-seperated list of libraries with their full paths.
|
||||
srb2Libraries="$(echo "$srb2Libraries" | cut -f 2 | cut -d ' ' -f 3)"
|
||||
|
||||
# remove any extraneous newlines around the string
|
||||
libraryWhitelist="$(echo $libraryWhitelist | head -c -1 | tr ' ' '\n')"
|
||||
|
||||
# replace e.g. 'abc' with '(/abc\b)', and replace newlines with '|'.
|
||||
# this converts it into a grep regular expression to check for any whitelisted library names.
|
||||
libraryWhitelist="$(printf "%s" "$libraryWhitelist" | sed 's|.*|(/\0\\b)|' | tr '\n' '|')"
|
||||
|
||||
# grab only the entries that match the regex
|
||||
__LDD_LIST="$(printf "%s" "$srb2Libraries" | grep -E "$libraryWhitelist")"
|
||||
|
||||
# use echo to convert the newline-seperated list into an argument list
|
||||
__LDD_LIST="$(echo $__LDD_LIST)"
|
||||
|
||||
# read into an array because i can't be bothered iterating the lines of a string today
|
||||
# there's so many other things in this file that'd need to be adjusted to be POSIX-compliant anyway
|
||||
IFS=' ' read -r -a paths <<< "$__LDD_LIST"
|
||||
|
||||
for path in "${paths[@]}"; do
|
||||
if [ -f "$path" ]; then
|
||||
verboseOnly 2 "Packaging dependency $(basename "$path")..."
|
||||
cp "$path" $__BUILD_DIR/AppDir/lib/
|
||||
else
|
||||
verboseOnly 2 "Dependency $(basename "$path") not found"
|
||||
fi
|
||||
done
|
||||
else
|
||||
verboseOnly 1 "This SRB2 build is statically linked, skipping dependency packing."
|
||||
fi
|
||||
|
||||
cd "$__BUILD_DIR/AppDir"
|
||||
|
||||
# Copy icons
|
||||
verboseOnly 1 "Packaging resources..."
|
||||
cp "$__ROOT_DIR/srb2.png" "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png"
|
||||
ln -sf "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png" "./.DirIcon"
|
||||
ln -sf "./usr/share/icons/hicolor/256x256/apps/$__PROGRAM_FILENAME.png" "./$__PROGRAM_FILENAME.png"
|
||||
|
||||
# Make desktop descriptor
|
||||
cat > "./usr/share/applications/$__PROGRAM_FILENAME.desktop" <<EOF
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=$__PROGRAM_NAME
|
||||
Comment=$__PROGRAM_DESCRIPTION
|
||||
Icon=$__PROGRAM_FILENAME
|
||||
Exec=AppRun %F
|
||||
Categories=Game;
|
||||
EOF
|
||||
|
||||
ln -sf "./usr/share/applications/$__PROGRAM_FILENAME.desktop" "./$__PROGRAM_FILENAME.desktop"
|
||||
|
||||
# Make entry point
|
||||
echo -e '#!'"$(dirname "$SHELL")/sh" > ./AppRun
|
||||
echo -e 'HERE="$(dirname "$(readlink -f "${0}")")"' >> ./AppRun
|
||||
echo -e 'SRB2WADDIR=$HERE/usr/bin LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HERE/lib exec $HERE/usr/bin/'"$__PROGRAM_FILENAME"' "$@"' >> ./AppRun
|
||||
chmod +x ./AppRun
|
||||
|
||||
cd .. # now in $__BUILD_DIR
|
||||
|
||||
# Package AppImage
|
||||
if [ -z "$__APPIMAGETOOL" ]; then
|
||||
verboseOnly 1 "No valid appimagetool path given or detected, downloading appimagetool..."
|
||||
|
||||
# Print notice for internet connection.
|
||||
important "If the command hangs here, check your internet connection, or download appimagetool and add it to your \$PATH and try compiling again."
|
||||
|
||||
(( "$verbosity" >= 3 )) && wget "$url" || wget -q "$url"
|
||||
|
||||
APPIMAGETOOL="./$(basename "$url")"
|
||||
chmod a+x "$APPIMAGETOOL"
|
||||
else
|
||||
verboseOnly 1 "appimagetool path given or detected, no download required."
|
||||
APPIMAGETOOL="$__APPIMAGETOOL"
|
||||
fi
|
||||
|
||||
verboseOnly 1 "Packing AppImage $__OUTPUT_FILENAME"
|
||||
|
||||
if (( verbosity >= 3 )); then
|
||||
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME"
|
||||
elif (( verbosity >= 2 )); then
|
||||
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME" >/dev/null
|
||||
else
|
||||
"$APPIMAGETOOL" ./AppDir "$__OUTPUT_FILENAME" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
success "AppImage ready!"
|
||||
verboseOnly 1 "Cleaning up files..."
|
||||
rm -r ./AppDir
|
||||
|
||||
if [ -z "$__APPIMAGETOOL" ]; then
|
||||
rm "$APPIMAGETOOL"
|
||||
fi
|
||||
|
||||
cd "$__ROOT_DIR" # snap back to reality
|
||||
+33
@@ -130,3 +130,36 @@ if rawget(_G, "S_StopSoundByNum") ~= nil then
|
||||
... -- Can use it
|
||||
end
|
||||
```
|
||||
## addHook("ServerJoin", function())
|
||||
|
||||
ServerJoin hook called when client joins server (starting a listen server also calls it for host).
|
||||
Generally it was made to make loading custom config files less hacky, but can be used for anything else too.
|
||||
|
||||
## player.viewrollangle field
|
||||
|
||||
Returns player's current view roll angle for the Screen Tilting feature, useful for HUD elements.
|
||||
|
||||
## G_SetPlayerGamepadIndicatorColor(player, skincolor)
|
||||
|
||||
Set a custom color for Supported Gamepads with RGB LED functionality.
|
||||
To be used with Displayplayers.
|
||||
Only takes Skincolors.
|
||||
Best to be used in a Loop to ensure the color wont get overwritten by the game.
|
||||
|
||||
## G_PlayerDeviceRumble(player, low_strength, high_strength, -optional- duration)
|
||||
|
||||
Add Gamepad Rumble support for things.
|
||||
To be used with Displayplayers.
|
||||
Duration is in milliseconds and is optional to set, default value is 84ms.
|
||||
|
||||
# Other changes
|
||||
|
||||
## P_PlayRinglossSound(source, damager)
|
||||
|
||||
Add optional `damager` argument (should be `mobj_t`), which causes hurt sound also play for damager
|
||||
if `karthitemdialog` option is enabled
|
||||
|
||||
## K_PlayHitEmSound(mobj, victim)
|
||||
|
||||
Add optional `victim` argument (should be a player's `mobj_t`), which causes "hit em" sound to be
|
||||
delayed and played for victim too if `karthitemdialog` option is enabled
|
||||
@@ -1 +1 @@
|
||||
/lsdlsrb2
|
||||
/lsdl2srb2kart
|
||||
+2
-2
@@ -167,6 +167,7 @@ set(SRB2_CORE_GAME_SOURCES
|
||||
p_telept.c
|
||||
p_tick.c
|
||||
p_user.c
|
||||
k_director.c
|
||||
k_kart.c
|
||||
i_time.c
|
||||
|
||||
@@ -180,6 +181,7 @@ set(SRB2_CORE_GAME_SOURCES
|
||||
p_slopes.h
|
||||
p_spec.h
|
||||
p_tick.h
|
||||
k_director.h
|
||||
k_kart.h
|
||||
)
|
||||
|
||||
@@ -465,7 +467,6 @@ if(${SRB2_CONFIG_HWRENDER})
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c
|
||||
@@ -483,7 +484,6 @@ if(${SRB2_CONFIG_HWRENDER})
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.h
|
||||
|
||||
+40
-2
@@ -106,6 +106,8 @@ ifeq ($(OS),Windows_NT) # all windows are Windows_NT...
|
||||
|
||||
else # if you on the *nix
|
||||
|
||||
NOUPX=1
|
||||
|
||||
system:=$(shell uname -s)
|
||||
|
||||
ifeq ($(system),Linux)
|
||||
@@ -205,6 +207,18 @@ USE_FBO_OGL=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NONET
|
||||
ifndef NOSATURNSYNCH
|
||||
DOSATURNSYNCH=1
|
||||
ifndef NOSATURNJOIN
|
||||
DOSATURNJOIN=1
|
||||
endif
|
||||
#ifndef NOSATURNPAK
|
||||
#DOSATURNPAK=1
|
||||
#endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MINGW
|
||||
include win32/Makefile.cfg
|
||||
endif #ifdef MINGW
|
||||
@@ -278,12 +292,12 @@ ifdef NOHW
|
||||
OPTS+=-DNOHW
|
||||
else
|
||||
OPTS+=-DHWRENDER
|
||||
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
|
||||
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o \
|
||||
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \
|
||||
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o $(OBJDIR)/hw_shaders.o
|
||||
endif
|
||||
|
||||
OPTS += -DCOMPVERSION
|
||||
OPTS += -DCOMPVERSION -fwrapv
|
||||
|
||||
ifndef NONX86
|
||||
ifndef GCC29
|
||||
@@ -384,6 +398,18 @@ OPTS+=-DUSE_FBO_OGL
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NONET
|
||||
ifndef NOSATURNSYNCH
|
||||
OPTS+=-DDOSATURNSYNCH
|
||||
ifndef NOSATURNJOIN
|
||||
OPTS+=-DDOSATURNJOIN
|
||||
endif
|
||||
#ifndef NOSATURNPAK
|
||||
#OPTS+=-DDOSATURNPAK
|
||||
#endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef HAVE_MINIUPNPC
|
||||
ifdef NONET
|
||||
HAVE_MINIUPNPC=''
|
||||
@@ -492,6 +518,7 @@ OBJS:=$(i_main_o) \
|
||||
$(OBJDIR)/hu_stuff.o \
|
||||
$(OBJDIR)/y_inter.o \
|
||||
$(OBJDIR)/st_stuff.o \
|
||||
$(OBJDIR)/k_director.o \
|
||||
$(OBJDIR)/k_kart.o \
|
||||
$(OBJDIR)/m_aatree.o \
|
||||
$(OBJDIR)/m_anigif.o \
|
||||
@@ -630,6 +657,17 @@ ifndef NOUPX
|
||||
-$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef APPIMAGE
|
||||
@echo Building AppImage...
|
||||
ifdef APPIMAGE_NOASSETS
|
||||
$(.)../AppImage_build.sh --small --quiet $(BIN)/
|
||||
else
|
||||
$(.)../AppImage_build.sh -q $(BIN)/
|
||||
endif
|
||||
@echo AppImage build complete, please look for $(EXENAME).AppImage in $(BIN)
|
||||
endif
|
||||
|
||||
@echo Build is done, please look for $(EXENAME) in $(BIN), \(checking for post steps\)
|
||||
|
||||
reobjdump:
|
||||
|
||||
+12
-7
@@ -12,7 +12,7 @@
|
||||
# to avoid a false positive with the version detection...
|
||||
|
||||
SUPPORTED_GCC_VERSIONS:=\
|
||||
141 14\
|
||||
142 141 140 14\
|
||||
132 131 130 13\
|
||||
123 122 121 120 12\
|
||||
114 113 112 111 110 11\
|
||||
@@ -24,7 +24,7 @@ SUPPORTED_GCC_VERSIONS:=\
|
||||
55 54 53 52 51 50\
|
||||
49 48 47 46 45 44 43 42 41 40
|
||||
|
||||
LATEST_GCC_VERSION=14.1
|
||||
LATEST_GCC_VERSION=14.2.1
|
||||
|
||||
# gcc or g++
|
||||
ifdef PREFIX
|
||||
@@ -78,12 +78,20 @@ ifeq (,$(filter GCC%,$(.VARIABLES)))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef GCC141
|
||||
ifdef GCC142
|
||||
GCC141=1
|
||||
endif
|
||||
|
||||
ifdef GCC141
|
||||
GCC140=1
|
||||
endif
|
||||
|
||||
ifdef GCC14
|
||||
GCC14=1
|
||||
GCC140=1
|
||||
endif
|
||||
|
||||
ifdef GCC140
|
||||
GCC132=1
|
||||
endif
|
||||
|
||||
ifdef GCC132
|
||||
@@ -437,9 +445,6 @@ endif
|
||||
ifdef GCC44
|
||||
WFLAGS+=-Wno-error=array-bounds
|
||||
endif
|
||||
ifdef GCC45
|
||||
opts+=-fwrapv
|
||||
endif
|
||||
ifdef GCC46
|
||||
WFLAGS+=-Wno-error=suggest-attribute=noreturn
|
||||
endif
|
||||
|
||||
@@ -1015,6 +1015,9 @@ static inline void AM_drawPlayers(void)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
if (!players[i].mo)
|
||||
continue;
|
||||
|
||||
p = &players[i];
|
||||
if (p->skincolor > 0)
|
||||
|
||||
+109
-8
@@ -43,8 +43,12 @@
|
||||
#ifdef HAVE_THREADS
|
||||
I_mutex con_mutex;
|
||||
|
||||
# define Lock_state() I_lock_mutex(&con_mutex)
|
||||
# define Unlock_state() I_unlock_mutex(con_mutex)
|
||||
// g_in_exiting_signal_handler is an evil hack
|
||||
// to avoid infinite SIGABRT recursion in the signal handler
|
||||
// due to poisoned locks or mach-o kernel not supporting locks in signals
|
||||
// or something like that. idk
|
||||
# define Lock_state() if (!g_in_exiting_signal_handler) { I_lock_mutex(&con_mutex); }
|
||||
# define Unlock_state() if (!g_in_exiting_signal_handler) { I_unlock_mutex(con_mutex); }
|
||||
#else/*HAVE_THREADS*/
|
||||
# define Lock_state()
|
||||
# define Unlock_state()
|
||||
@@ -846,9 +850,36 @@ static void CON_InputAddString(const char *c)
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_InputDel(size_t start, size_t end)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
Lock_state();
|
||||
|
||||
len = (end - start);
|
||||
|
||||
if (end != input_len)
|
||||
memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-end);
|
||||
memset(&inputlines[inputline][input_len - len], 0, len);
|
||||
|
||||
input_len -= len;
|
||||
|
||||
if (input_sel >= end)
|
||||
input_sel -= len;
|
||||
else if (input_sel > start)
|
||||
input_sel = start;
|
||||
|
||||
if (input_cur >= end)
|
||||
input_cur -= len;
|
||||
else if (input_cur > start)
|
||||
input_cur = start;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_InputDelSelection(void)
|
||||
{
|
||||
size_t start, end, len;
|
||||
size_t start, end;
|
||||
|
||||
Lock_state();
|
||||
|
||||
@@ -862,18 +893,56 @@ static void CON_InputDelSelection(void)
|
||||
start = input_cur;
|
||||
end = input_sel;
|
||||
}
|
||||
len = (end - start);
|
||||
|
||||
if (end != input_len)
|
||||
memmove(&inputlines[inputline][start], &inputlines[inputline][end], input_len-end);
|
||||
memset(&inputlines[inputline][input_len - len], 0, len);
|
||||
CON_InputDel(start, end);
|
||||
|
||||
input_len -= len;
|
||||
input_sel = input_cur = start;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_ToWordEnd(boolean move_sel)
|
||||
{
|
||||
Lock_state();
|
||||
|
||||
// Skip spaces
|
||||
while (input_cur < input_len && isspace(inputlines[inputline][input_cur]))
|
||||
++input_cur;
|
||||
|
||||
// Skip word
|
||||
while (input_cur < input_len && !isspace(inputlines[inputline][input_cur]))
|
||||
++input_cur;
|
||||
|
||||
if (move_sel) input_sel = input_cur;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_ToWordBegin(boolean move_sel)
|
||||
{
|
||||
Lock_state();
|
||||
|
||||
// Hack, always move back 1 character if possible so if we press ctrl-left at a word beginning
|
||||
// we move to previous word
|
||||
if (input_cur) --input_cur;
|
||||
|
||||
// Skip spaces
|
||||
while (input_cur && isspace(inputlines[inputline][input_cur]))
|
||||
--input_cur;
|
||||
|
||||
// Skip word
|
||||
while (input_cur && !isspace(inputlines[inputline][input_cur]))
|
||||
--input_cur;
|
||||
|
||||
// Unless we reached beginning of line, we're pointing at a space before word, so move cursor
|
||||
// forward to fix that
|
||||
if (input_cur) ++input_cur;
|
||||
|
||||
if (move_sel) input_sel = input_cur;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
static void CON_InputAddChar(char c)
|
||||
{
|
||||
if (input_len >= CON_MAXPROMPTCHARS-1)
|
||||
@@ -1051,6 +1120,38 @@ boolean CON_Responder(event_t *ev)
|
||||
completion[0] = 0;
|
||||
return true;
|
||||
}
|
||||
else if (key == 'w' || key == 'W')
|
||||
{
|
||||
size_t word_start, word_end, i;
|
||||
word_end = i = input_cur;
|
||||
|
||||
// Unless we're pointing at the beginning of line, decrement i so we only start
|
||||
// removing symbols that come before the cursor
|
||||
if (i) --i;
|
||||
|
||||
// We might be pointing to spaces, skip them first
|
||||
while (i && isspace(inputlines[inputline][i]))
|
||||
--i;
|
||||
|
||||
// Now skip the "word"
|
||||
while (i && !isspace(inputlines[inputline][i]))
|
||||
--i;
|
||||
|
||||
// Unless we reached beginning of line, i is pointing at first space that was found
|
||||
// before word start, and we don't want to remove it
|
||||
if (i) ++i;
|
||||
|
||||
word_start = i;
|
||||
|
||||
if (word_start != word_end)
|
||||
CON_InputDel(word_start, word_end);
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_RIGHTARROW)
|
||||
CON_ToWordEnd(!shiftdown);
|
||||
else if (key == KEY_LEFTARROW)
|
||||
CON_ToWordBegin(!shiftdown);
|
||||
|
||||
// Select all
|
||||
if (key == 'a' || key == 'A')
|
||||
|
||||
+388
-69
@@ -10,6 +10,7 @@
|
||||
/// \file d_clisrv.c
|
||||
/// \brief SRB2 Network game communication and protocol, all OS independent parts.
|
||||
|
||||
#include "doomdef.h"
|
||||
#include <time.h>
|
||||
#ifdef __GNUC__
|
||||
#include <unistd.h> //for unlink
|
||||
@@ -23,6 +24,7 @@
|
||||
#include "d_netfil.h" // fileneedednum
|
||||
#include "d_main.h"
|
||||
#include "g_game.h"
|
||||
#include "m_menu.h" // M_ClearMenus
|
||||
#include "hu_stuff.h"
|
||||
#include "keys.h"
|
||||
#include "g_input.h" // JOY1
|
||||
@@ -75,6 +77,8 @@
|
||||
#define MAX_REASONLENGTH 30
|
||||
#define FORCECLOSE 0x8000
|
||||
|
||||
static long long unsigned packetstat[NUMPACKETTYPE+1] = {0};
|
||||
|
||||
boolean server = true; // true or false but !server == client
|
||||
#define client (!server)
|
||||
boolean nodownload = false;
|
||||
@@ -89,6 +93,10 @@ UINT8 playernode[MAXPLAYERS];
|
||||
// The actual timeout will be longer depending on the savegame length
|
||||
tic_t jointimeout = (3*TICRATE);
|
||||
static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame?
|
||||
#ifdef SATURNSYNCH
|
||||
static boolean resendingsavegame[MAXNETNODES]; // Are we resending the savegame?
|
||||
static tic_t savegameresendcooldown[MAXNETNODES]; // How long before we can resend again?
|
||||
#endif
|
||||
static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout?
|
||||
|
||||
UINT16 pingmeasurecount = 1;
|
||||
@@ -121,6 +129,12 @@ static UINT8 resynch_local_inprogress = false; // WE are desynched and getting p
|
||||
static UINT8 player_joining = false;
|
||||
UINT8 hu_resynching = 0;
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
UINT8 hu_redownloadinggamestate = 0;
|
||||
static boolean can_receive_gamestate[MAXNETNODES];
|
||||
static UINT8 gamestate_resend_counter[MAXNETNODES];
|
||||
#endif
|
||||
|
||||
// kart, true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks
|
||||
UINT8 hu_stopped = 0;
|
||||
|
||||
@@ -133,6 +147,18 @@ static boolean cl_packetmissed;
|
||||
// here it is for the secondary local player (splitscreen)
|
||||
static UINT8 mynode; // my address pointofview server
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
static boolean cl_redownloadinggamestate = false;
|
||||
#endif
|
||||
|
||||
#ifdef SATURNPAK
|
||||
boolean is_client_saturn[MAXNETNODES];
|
||||
#endif
|
||||
|
||||
#ifdef SATURNJOIN
|
||||
#define ISSATURN 69
|
||||
#endif
|
||||
|
||||
static UINT8 localtextcmd[MAXTEXTCMD];
|
||||
static UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen
|
||||
static UINT8 localtextcmd3[MAXTEXTCMD]; // splitscreen == 2
|
||||
@@ -169,7 +195,6 @@ typedef struct textcmdtic_s
|
||||
ticcmd_t netcmds[TICQUEUE][MAXPLAYERS];
|
||||
static textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL};
|
||||
|
||||
|
||||
consvar_t cv_showjoinaddress = {"showjoinaddress", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_shownodeip = {"showipinnodelist", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -220,7 +245,7 @@ UINT16 software_MAXPACKETLENGTH;
|
||||
* \return The full tic value
|
||||
*
|
||||
*/
|
||||
tic_t ExpandTics(INT32 low, tic_t basetic)
|
||||
static inline tic_t ExpandTics(INT32 low, tic_t basetic)
|
||||
{
|
||||
INT32 delta;
|
||||
|
||||
@@ -1333,9 +1358,13 @@ static inline void CL_DrawConnectionStatus(void)
|
||||
{
|
||||
strncpy(tempname, filename, sizeof(tempname)-1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-30, 0,
|
||||
va(M_GetText("%s downloading"), ((cl_mode == CL_DOWNLOADHTTPFILES) ? "\x82""HTTP" : "\x85""Direct")));
|
||||
#else
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-30, 0,
|
||||
va(M_GetText("%s downloading"),("\x85""Direct")));
|
||||
#endif
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-22, V_YELLOWMAP,
|
||||
va(M_GetText("\"%s\""), tempname));
|
||||
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-58, V_20TRANS|V_MONOSPACE,
|
||||
@@ -1423,6 +1452,9 @@ static boolean CL_SendJoin(void)
|
||||
netbuffer->u.clientcfg.subversion = SUBVERSION;
|
||||
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
|
||||
sizeof netbuffer->u.clientcfg.application);
|
||||
#ifdef SATURNJOIN
|
||||
netbuffer->u.clientcfg.issaturn = ISSATURN;
|
||||
#endif
|
||||
|
||||
return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak));
|
||||
}
|
||||
@@ -1720,23 +1752,23 @@ static boolean SV_SendServerConfig(INT32 node)
|
||||
netbuffer->u.servercfg.discordinvites = (boolean)cv_discordinvites.value;
|
||||
|
||||
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
||||
|
||||
op = p = netbuffer->u.servercfg.varlengthinputs;
|
||||
|
||||
CV_SavePlayerNames(&p);
|
||||
CV_SaveNetVars(&p, false);
|
||||
{
|
||||
const size_t len = sizeof (serverconfig_pak) + (size_t)(p - op);
|
||||
|
||||
const size_t len = sizeof (serverconfig_pak) + (size_t)(p - op);
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (debugfile)
|
||||
{
|
||||
fprintf(debugfile, "ServerConfig Packet about to be sent, size of packet:%s to node:%d\n",
|
||||
sizeu1(len), node);
|
||||
}
|
||||
if (debugfile)
|
||||
{
|
||||
fprintf(debugfile, "ServerConfig Packet about to be sent, size of packet:%s to node:%d\n",
|
||||
sizeu1(len), node);
|
||||
}
|
||||
#endif
|
||||
|
||||
waspacketsent = HSendPacket(node, true, 0, len);
|
||||
}
|
||||
waspacketsent = HSendPacket(node, true, 0, len);
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (debugfile)
|
||||
@@ -1758,7 +1790,7 @@ static boolean SV_SendServerConfig(INT32 node)
|
||||
#ifdef JOININGAME
|
||||
#define SAVEGAMESIZE (768*1024)
|
||||
|
||||
static void SV_SendSaveGame(INT32 node)
|
||||
static void SV_SendSaveGame(INT32 node, boolean resending)
|
||||
{
|
||||
size_t length, compressedlen;
|
||||
UINT8 *savebuffer;
|
||||
@@ -1776,7 +1808,7 @@ static void SV_SendSaveGame(INT32 node)
|
||||
// Leave room for the uncompressed length.
|
||||
save_p = savebuffer + sizeof(UINT32);
|
||||
|
||||
P_SaveNetGame();
|
||||
P_SaveNetGame(resending);
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
@@ -1849,7 +1881,7 @@ static void SV_SavedGame(void)
|
||||
return;
|
||||
}
|
||||
|
||||
P_SaveNetGame();
|
||||
P_SaveNetGame(false);
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
@@ -1871,8 +1903,7 @@ static void SV_SavedGame(void)
|
||||
#endif
|
||||
#define TMPSAVENAME "$$$.sav"
|
||||
|
||||
|
||||
static void CL_LoadReceivedSavegame(void)
|
||||
static void CL_LoadReceivedSavegame(boolean reloading)
|
||||
{
|
||||
UINT8 *savebuffer = NULL;
|
||||
size_t length, decompressedlen;
|
||||
@@ -1906,39 +1937,24 @@ static void CL_LoadReceivedSavegame(void)
|
||||
demo.title = false;
|
||||
automapactive = false;
|
||||
|
||||
if (!postautoloaded)
|
||||
{
|
||||
CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfilespost) == 0)
|
||||
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfilespost);
|
||||
postautoloaded = true;
|
||||
}
|
||||
|
||||
// load a base level
|
||||
if (P_LoadNetGame())
|
||||
if (P_LoadNetGame(reloading))
|
||||
{
|
||||
CON_LogMessage(va(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)));
|
||||
if (strlen(mapheaderinfo[gamemap-1]->lvlttl) > 0)
|
||||
if (!reloading)
|
||||
{
|
||||
CON_LogMessage(va(": %s", mapheaderinfo[gamemap-1]->lvlttl));
|
||||
if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0)
|
||||
CON_LogMessage(va(" %s", mapheaderinfo[gamemap-1]->zonttl));
|
||||
else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
CON_LogMessage(M_GetText(" Zone"));
|
||||
if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0)
|
||||
CON_LogMessage(va(" %s", mapheaderinfo[gamemap-1]->actnum));
|
||||
CON_LogMessage(va(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)));
|
||||
if (strlen(mapheaderinfo[gamemap-1]->lvlttl) > 0)
|
||||
{
|
||||
CON_LogMessage(va(": %s", mapheaderinfo[gamemap-1]->lvlttl));
|
||||
if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0)
|
||||
CON_LogMessage(va(" %s", mapheaderinfo[gamemap-1]->zonttl));
|
||||
else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
CON_LogMessage(M_GetText(" Zone"));
|
||||
if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0)
|
||||
CON_LogMessage(va(" %s", mapheaderinfo[gamemap-1]->actnum));
|
||||
}
|
||||
CON_LogMessage("\"\n");
|
||||
}
|
||||
CON_LogMessage("\"\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n"));
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
if (unlink(tmpsave) == -1)
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
|
||||
return;
|
||||
}
|
||||
|
||||
// done
|
||||
@@ -1948,20 +1964,61 @@ static void CL_LoadReceivedSavegame(void)
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
|
||||
consistancy[gametic%TICQUEUE] = Consistancy();
|
||||
CON_ToggleOff();
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
// Tell the server we have received and reloaded the gamestate
|
||||
// so they know they can resume the game
|
||||
if (reloading)
|
||||
{
|
||||
netbuffer->packettype = PT_RECEIVEDGAMESTATE;
|
||||
HSendPacket(servernode, true, 0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
static void CL_ReloadReceivedSavegame(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
LUA_InvalidatePlayer(&players[i]);
|
||||
sprintf(player_names[i], "Player %d", i + 1);
|
||||
}
|
||||
|
||||
CL_LoadReceivedSavegame(true);
|
||||
|
||||
if (neededtic < gametic)
|
||||
neededtic = gametic;
|
||||
maketic = neededtic;
|
||||
|
||||
// set camera angle to somewhat match where your player is turning
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
localangle[i] = players[displayplayers[i]].cmd.angleturn<<16;
|
||||
}
|
||||
|
||||
camera->subsector = R_PointInSubsector(camera->x, camera->y);
|
||||
|
||||
cl_redownloadinggamestate = false;
|
||||
|
||||
CONS_Printf(M_GetText("Game state reloaded\n"));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NONET
|
||||
static void SendAskInfo(INT32 node)
|
||||
{
|
||||
tic_t asktime;
|
||||
#ifdef HOLEPUNCH
|
||||
#ifdef HOLEPUNCH
|
||||
if (node != 0 && node != BROADCASTADDR &&
|
||||
cv_rendezvousserver.string[0])
|
||||
{
|
||||
I_NetRequestHolePunch(node);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
asktime = I_GetTime();
|
||||
|
||||
@@ -2170,7 +2227,9 @@ static void M_ConfirmConnect(event_t *ev)
|
||||
|
||||
static void AbortConnection(void)
|
||||
{
|
||||
#ifdef HAVE_CURL
|
||||
CURLAbortFile();
|
||||
#endif
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
@@ -2559,7 +2618,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||
if (fileneeded[0].status == FS_FOUND)
|
||||
{
|
||||
// Gamestate is now handled within CL_LoadReceivedSavegame()
|
||||
CL_LoadReceivedSavegame();
|
||||
CL_LoadReceivedSavegame(false);
|
||||
cl_mode = CL_CONNECTED;
|
||||
break;
|
||||
} // don't break case continue to CL_CONNECTED
|
||||
@@ -2584,7 +2643,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||
// Call it only once by tic
|
||||
if (*oldtic != I_GetTime())
|
||||
{
|
||||
|
||||
INT32 key;
|
||||
|
||||
I_OsPolling();
|
||||
@@ -3040,8 +3098,17 @@ static void Command_connect(void)
|
||||
|
||||
if (Playing() || demo.title)
|
||||
{
|
||||
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
|
||||
return;
|
||||
M_ClearMenus(true);
|
||||
if (demo.title)
|
||||
G_CheckDemoStatus();
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
}
|
||||
|
||||
D_StartTitle();
|
||||
}
|
||||
|
||||
// modified game check: no longer handled
|
||||
@@ -3100,6 +3167,17 @@ static void Command_connect(void)
|
||||
botskin = 0;
|
||||
CL_ConnectToServer();
|
||||
}
|
||||
|
||||
static void Command_Packetstat(void)
|
||||
{
|
||||
CONS_Printf("Number of packets handled:\n");
|
||||
|
||||
for (UINT8 i = 0; i <= NUMPACKETTYPE; ++i)
|
||||
{
|
||||
CONS_Printf("%16s: %llu%s", Net_GetPacketName(i), packetstat[i], (i % 2 == 1) ? "\n" : "\t|\t");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void ResetNode(INT32 node);
|
||||
@@ -3142,10 +3220,15 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||
playerpernode[node]--;
|
||||
if (playerpernode[node] <= 0)
|
||||
{
|
||||
// If a resynch was in progress, well, it no longer needs to be.
|
||||
SV_InitResynchVars(node);
|
||||
SV_InitResynchVars(node); // If a resynch was in progress, well, it no longer needs to be.
|
||||
|
||||
nodeingame[node] = false;
|
||||
#ifdef SATURNPAK
|
||||
is_client_saturn[node] = false;
|
||||
#endif
|
||||
#ifdef SATURNSYNCH
|
||||
can_receive_gamestate[node] = false;
|
||||
#endif
|
||||
Net_CloseConnection(node);
|
||||
ResetNode(node);
|
||||
}
|
||||
@@ -3251,6 +3334,9 @@ void CL_Reset(void)
|
||||
if (servernode > 0 && servernode < MAXNETNODES)
|
||||
{
|
||||
nodeingame[(UINT8)servernode] = false;
|
||||
#ifdef SATURNPAK
|
||||
is_client_saturn[(UINT8)servernode] = false;
|
||||
#endif
|
||||
Net_CloseConnection(servernode);
|
||||
}
|
||||
D_CloseConnection(); // netgame = false
|
||||
@@ -3265,6 +3351,7 @@ void CL_Reset(void)
|
||||
// make sure we don't leave any fileneeded gunk over from a failed join
|
||||
fileneedednum = 0;
|
||||
memset(fileneeded, 0, sizeof(fileneeded));
|
||||
memset(packetstat, 0, sizeof(packetstat));
|
||||
|
||||
#ifndef NONET
|
||||
totalfilesrequestednum = 0;
|
||||
@@ -3945,6 +4032,36 @@ static void Command_list_http_logins (void)
|
||||
}
|
||||
#endif/*HAVE_CURL*/
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
static void Command_ResendGamestate(void)
|
||||
{
|
||||
SINT8 playernum;
|
||||
|
||||
if (COM_Argc() == 1)
|
||||
{
|
||||
CONS_Printf(M_GetText("resendgamestate <playername/playernum>: resend the game state to a player\n"));
|
||||
return;
|
||||
}
|
||||
else if (client)
|
||||
{
|
||||
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
playernum = nametonum(COM_Argv(1));
|
||||
if (playernum == -1 || playernum == 0)
|
||||
return;
|
||||
|
||||
// Send a PT_WILLRESENDGAMESTATE packet to the client so they know what's going on
|
||||
netbuffer->packettype = PT_WILLRESENDGAMESTATE;
|
||||
if (!HSendPacket(playernode[playernum], true, 0, 0))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("A problem occured, please try again.\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_netticbuffer = {"netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -3954,6 +4071,10 @@ consvar_t cv_joinrefusemessage = {"joinrefusemessage", "The server is not accept
|
||||
|
||||
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_CALL, CV_OnOff, Joinable_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#ifdef SATURNJOIN
|
||||
consvar_t cv_allownewsaturnplayer = {"allowsaturnjoin", "On", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif
|
||||
|
||||
#ifdef VANILLAJOINNEXTROUND
|
||||
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
|
||||
#endif
|
||||
@@ -3966,7 +4087,16 @@ static CV_PossibleValue_t discordinvites_cons_t[] = {{0, "Admins Only"}, {1, "Ev
|
||||
consvar_t cv_discordinvites = {"discordinvites", "Everyone", CV_SAVE|CV_CALL, discordinvites_cons_t, Joinable_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t resynchattempts_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_resynchattempts = {"resynchattempts", "2", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
consvar_t cv_resynchattempts = {"resynchattempts", "2", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
static CV_PossibleValue_t gamestateattempts_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_gamestateattempts = {"gamestateresendattempts", "10", CV_SAVE, gamestateattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t resynchcooldown_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_resynchcooldown = {"gamestatecooldown", "5", CV_SAVE, resynchcooldown_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
#endif
|
||||
|
||||
consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
|
||||
// max file size to send to a player (in kilobytes)
|
||||
@@ -3993,6 +4123,11 @@ static void Joinable_OnChange(void)
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
#ifdef SATURNJOIN
|
||||
// disabling joins should also disable saturn joins unless its called with CV_StealthSet and vice versa to make life a bit easier
|
||||
CV_SetValue(&cv_allownewsaturnplayer, cv_allownewplayer.value);
|
||||
#endif
|
||||
|
||||
maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
|
||||
|
||||
WRITEUINT8(p, maxplayer);
|
||||
@@ -4018,7 +4153,11 @@ void D_ClientServerInit(void)
|
||||
COM_AddCommand("reloadbans", Command_ReloadBan);
|
||||
COM_AddCommand("connect", Command_connect);
|
||||
COM_AddCommand("nodes", Command_Nodes);
|
||||
#ifdef SATURNSYNCH
|
||||
COM_AddCommand("resendgamestate", Command_ResendGamestate);
|
||||
#endif
|
||||
COM_AddCommand("listplayers", Command_Listplayers);
|
||||
COM_AddCommand("packetstat", Command_Packetstat);
|
||||
#ifdef HAVE_CURL
|
||||
COM_AddCommand("set_http_login", Command_set_http_login);
|
||||
COM_AddCommand("list_http_logins", Command_list_http_logins);
|
||||
@@ -4055,17 +4194,33 @@ void D_ClientServerInit(void)
|
||||
static void ResetNode(INT32 node)
|
||||
{
|
||||
nodeingame[node] = false;
|
||||
nodewaiting[node] = 0;
|
||||
|
||||
nodetoplayer[node] = -1;
|
||||
nodetoplayer2[node] = -1;
|
||||
nodetoplayer3[node] = -1;
|
||||
nodetoplayer4[node] = -1;
|
||||
playerpernode[node] = 0;
|
||||
|
||||
nettics[node] = gametic;
|
||||
supposedtics[node] = gametic;
|
||||
nodewaiting[node] = 0;
|
||||
playerpernode[node] = 0;
|
||||
|
||||
sendingsavegame[node] = false;
|
||||
|
||||
bannednode[node].banid = SIZE_MAX;
|
||||
bannednode[node].timeleft = NO_BAN_TIME;
|
||||
|
||||
// SATURN
|
||||
#ifdef SATURNPAK
|
||||
is_client_saturn[node] = false;
|
||||
#endif
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
resendingsavegame[node] = false;
|
||||
can_receive_gamestate[node] = false;
|
||||
savegameresendcooldown[node] = 0;
|
||||
#endif
|
||||
//
|
||||
}
|
||||
|
||||
void SV_ResetServer(void)
|
||||
@@ -4101,6 +4256,9 @@ void SV_ResetServer(void)
|
||||
|
||||
mynode = 0;
|
||||
cl_packetmissed = false;
|
||||
#ifdef SATURNSYNCH
|
||||
cl_redownloadinggamestate = false;
|
||||
#endif
|
||||
|
||||
if (dedicated)
|
||||
{
|
||||
@@ -4117,6 +4275,7 @@ void SV_ResetServer(void)
|
||||
|
||||
// clear server_context
|
||||
memset(server_context, '-', 8);
|
||||
memset(packetstat, 0, sizeof(packetstat));
|
||||
|
||||
DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n");
|
||||
}
|
||||
@@ -4276,8 +4435,13 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||
if (server && multiplayer && motd[0] != '\0')
|
||||
COM_BufAddText(va("sayto %d %s\n", newplayernum, motd));
|
||||
|
||||
D_AddAutoloadFiles();
|
||||
|
||||
LUAh_PlayerJoin(newplayernum);
|
||||
|
||||
if (newplayernum == consoleplayer)
|
||||
LUAh_ServerJoin();
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
DRPC_UpdatePresence();
|
||||
#endif
|
||||
@@ -4309,7 +4473,6 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum)
|
||||
if (pnum == serverplayer)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Attempt to remove server player\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4388,6 +4551,14 @@ static boolean SV_AddWaitingPlayers(void)
|
||||
return newplayer;
|
||||
}
|
||||
|
||||
#ifdef SATURNPAK
|
||||
static inline void SendSaturnInfo(INT32 node)
|
||||
{
|
||||
netbuffer->packettype = PT_ISSATURN;
|
||||
HSendPacket(node, true, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CL_AddSplitscreenPlayer(void)
|
||||
{
|
||||
if (cl_mode == CL_CONNECTED)
|
||||
@@ -4573,7 +4744,11 @@ static void HandleConnect(SINT8 node)
|
||||
{
|
||||
SV_SendRefuse(node, va(M_GetText("Different SRB2Kart versions cannot\nplay a netgame!\n(server version %d.%d)"), VERSION, SUBVERSION));
|
||||
}
|
||||
#ifdef SATURNJOIN
|
||||
else if ((!cv_allownewplayer.value && node && netbuffer->u.clientcfg.issaturn != ISSATURN) || (!cv_allownewsaturnplayer.value && node && netbuffer->u.clientcfg.issaturn == ISSATURN))
|
||||
#else
|
||||
else if (!cv_allownewplayer.value && node)
|
||||
#endif
|
||||
{
|
||||
SV_SendRefuse(node, M_GetText(cv_joinrefusemessage.string));
|
||||
}
|
||||
@@ -4629,6 +4804,7 @@ static void HandleConnect(SINT8 node)
|
||||
/// \todo fix this !!!
|
||||
return; // restart the while
|
||||
}
|
||||
SV_SendServerInfo(node, 0); // Dunno if 0 time is good idea
|
||||
//if (gamestate != GS_LEVEL) // GS_INTERMISSION, etc?
|
||||
// SV_SendPlayerConfigs(node); // send bare minimum player info
|
||||
G_SetGamestate(backupstate);
|
||||
@@ -4639,7 +4815,7 @@ static void HandleConnect(SINT8 node)
|
||||
{
|
||||
if (node && newnode)
|
||||
{
|
||||
SV_SendSaveGame(node); // send a complete game state
|
||||
SV_SendSaveGame(node, false); // send a complete game state
|
||||
DEBFILE("send savegame\n");
|
||||
}
|
||||
SV_AddWaitingPlayers();
|
||||
@@ -4705,6 +4881,47 @@ static void HandleServerInfo(SINT8 node)
|
||||
netbuffer->u.serverinfo.gametype = (UINT8)((netbuffer->u.serverinfo.gametype == VANILLA_GT_MATCH) ? GT_MATCH : GT_RACE);
|
||||
|
||||
SL_InsertServer(&netbuffer->u.serverinfo, node);
|
||||
|
||||
if (client && cl_mode > CL_SEARCHING && node == servernode)
|
||||
memcpy(connectedservername, netbuffer->u.serverinfo.servername, MAXSERVERNAME);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
static void PT_WillResendGamestate(void)
|
||||
{
|
||||
char tmpsave[264];
|
||||
|
||||
if (server || cl_redownloadinggamestate)
|
||||
return;
|
||||
|
||||
// Send back a PT_CANRECEIVEGAMESTATE packet to the server
|
||||
// so they know they can start sending the game state
|
||||
netbuffer->packettype = PT_CANRECEIVEGAMESTATE;
|
||||
if (!HSendPacket(servernode, true, 0, 0))
|
||||
return;
|
||||
|
||||
CONS_Printf(M_GetText("Reloading game state...\n"));
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
// Don't get a corrupt savegame error because tmpsave already exists
|
||||
if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1)
|
||||
I_Error("Can't delete %s\n", tmpsave);
|
||||
|
||||
CL_PrepareDownloadSaveGame(tmpsave);
|
||||
cl_redownloadinggamestate = true;
|
||||
}
|
||||
|
||||
static void PT_CanReceiveGamestate(SINT8 node)
|
||||
{
|
||||
if (client || sendingsavegame[node])
|
||||
return;
|
||||
|
||||
CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[nodetoplayer[node]]);
|
||||
|
||||
SV_SendSaveGame(node, true); // Resend a complete game state
|
||||
resendingsavegame[node] = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4896,6 +5113,9 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||
#endif
|
||||
DEBFILE(va("Server accept join gametic=%u mynode=%d\n", gametic, mynode));
|
||||
|
||||
#ifdef SATURNPAK
|
||||
SendSaturnInfo(node);
|
||||
#endif
|
||||
memset(playeringame, 0, sizeof(playeringame));
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
{
|
||||
@@ -5009,7 +5229,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||
tic_t realend, realstart;
|
||||
UINT8 *pak, *txtpak, numtxtpak;
|
||||
|
||||
|
||||
txtpak = NULL;
|
||||
|
||||
if (dedicated && node == 0)
|
||||
@@ -5133,11 +5352,69 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||
--resynch_delay[node];
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
if ((gamestate_resend_counter[node] != 0) && (I_GetTime() % ((max(cv_resynchcooldown.value, 1) * TICRATE) *2) == 0))
|
||||
gamestate_resend_counter[node]--;
|
||||
|
||||
// Check player consistancy during the level
|
||||
if (((!can_receive_gamestate[node]) && realstart <= gametic && realstart > gametic - TICQUEUE+1 && gamestate == GS_LEVEL
|
||||
&& consistancy[realstart%TICQUEUE] != SHORT(netbuffer->u.clientpak.consistancy)) || (can_receive_gamestate[node] && realstart <= gametic && realstart + TICQUEUE - 1 > gametic && gamestate == GS_LEVEL
|
||||
&& consistancy[realstart%TICQUEUE] != SHORT(netbuffer->u.clientpak.consistancy)
|
||||
&& !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime()))
|
||||
{
|
||||
// we need to send this so the client can tell us if it can receive the savegame
|
||||
netbuffer->packettype = PT_WILLRESENDGAMESTATE;
|
||||
HSendPacket(node, true, 0, 0);
|
||||
|
||||
if (can_receive_gamestate[node])
|
||||
resendingsavegame[node] = true;
|
||||
else
|
||||
{
|
||||
SV_RequireResynch(node);
|
||||
resendingsavegame[node] = false;
|
||||
}
|
||||
|
||||
if ((!can_receive_gamestate[node] && cv_resynchattempts.value && resynch_score[node] <= (unsigned)cv_resynchattempts.value*250) || (can_receive_gamestate[node] && (gamestate_resend_counter[node] < cv_gamestateattempts.value)))
|
||||
{
|
||||
if (can_receive_gamestate[node] && resendingsavegame[node])
|
||||
{
|
||||
gamestate_resend_counter[node]++;
|
||||
DEBFILE(va("gamestate counter %d for player %d\n", gamestate_resend_counter[node], netconsole));
|
||||
}
|
||||
|
||||
if (cv_blamecfail.value)
|
||||
CONS_Printf(M_GetText("Synch failure for player %d (%s); expected %hd, got %hd\n"),
|
||||
netconsole+1, player_names[netconsole],
|
||||
consistancy[realstart%TICQUEUE],
|
||||
SHORT(netbuffer->u.clientpak.consistancy));
|
||||
DEBFILE(va("Restoring player %d (synch failure) [%update] %d!=%d\n",
|
||||
netconsole, realstart, consistancy[realstart%TICQUEUE],
|
||||
SHORT(netbuffer->u.clientpak.consistancy)));
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 buf[3];
|
||||
|
||||
buf[0] = (UINT8)netconsole;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n",
|
||||
netconsole, realstart, consistancy[realstart%TICQUEUE],
|
||||
SHORT(netbuffer->u.clientpak.consistancy)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (resynch_score[node])
|
||||
--resynch_score[node];
|
||||
break;
|
||||
#else
|
||||
// Check player consistancy during the level
|
||||
if (realstart <= gametic && realstart > gametic - TICQUEUE+1 && gamestate == GS_LEVEL
|
||||
&& consistancy[realstart%TICQUEUE] != SHORT(netbuffer->u.clientpak.consistancy))
|
||||
{
|
||||
SV_RequireResynch(node);
|
||||
SV_RequireResynch(node);
|
||||
|
||||
if (cv_resynchattempts.value && resynch_score[node] <= (unsigned)cv_resynchattempts.value*250)
|
||||
{
|
||||
@@ -5167,6 +5444,8 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||
else if (resynch_score[node])
|
||||
--resynch_score[node];
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PT_BASICKEEPALIVE:
|
||||
if (client)
|
||||
break;
|
||||
@@ -5301,6 +5580,12 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||
}
|
||||
Net_CloseConnection(node);
|
||||
nodeingame[node] = false;
|
||||
#ifdef SATURNPAK
|
||||
is_client_saturn[node] = false;
|
||||
#endif
|
||||
#ifdef SATURNSYNCH
|
||||
can_receive_gamestate[node] = false;
|
||||
#endif
|
||||
break;
|
||||
// -------------------------------------------- CLIENT RECEIVE ----------
|
||||
case PT_RESYNCHEND:
|
||||
@@ -5464,6 +5749,26 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||
if (client)
|
||||
Got_Filetxpak();
|
||||
break;
|
||||
#ifdef SATURNSYNCH
|
||||
case PT_CANRECEIVEGAMESTATE:
|
||||
can_receive_gamestate[node] = true;
|
||||
PT_CanReceiveGamestate(node);
|
||||
break;
|
||||
case PT_RECEIVEDGAMESTATE:
|
||||
sendingsavegame[node] = false;
|
||||
resendingsavegame[node] = false;
|
||||
savegameresendcooldown[node] = I_GetTime() + cv_resynchcooldown.value * TICRATE; // I_GetTime() + 5 * TICRATE;
|
||||
break;
|
||||
case PT_WILLRESENDGAMESTATE:
|
||||
PT_WillResendGamestate();
|
||||
break;
|
||||
#endif
|
||||
#ifdef SATURNPAK
|
||||
case PT_ISSATURN:
|
||||
//CONS_Printf("hi im on saturn%d\n", node);
|
||||
is_client_saturn[node] = true;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DEBFILE(va("UNKNOWN PACKET TYPE RECEIVED %d from host %d\n",
|
||||
netbuffer->packettype, node));
|
||||
@@ -5479,7 +5784,6 @@ static void GetPackets(void)
|
||||
{
|
||||
SINT8 node; // The packet sender
|
||||
|
||||
|
||||
player_joining = false;
|
||||
|
||||
while (HGetPacket())
|
||||
@@ -5516,6 +5820,10 @@ static void GetPackets(void)
|
||||
if (netbuffer->packettype == PT_PLAYERINFO)
|
||||
continue; // We do nothing with PLAYERINFO, that's for the MS browser.
|
||||
|
||||
// We also count unknown packets, hence "<="
|
||||
if (netbuffer->packettype <= NUMPACKETTYPE)
|
||||
++packetstat[netbuffer->packettype];
|
||||
|
||||
// Packet received from someone already playing
|
||||
if (nodeingame[node])
|
||||
HandlePacketFromPlayer(node);
|
||||
@@ -6292,13 +6600,12 @@ void NetKeepAlive(void)
|
||||
MasterClient_Ticker();
|
||||
#endif
|
||||
|
||||
#ifdef HOLEPUNCH
|
||||
#ifdef HOLEPUNCH
|
||||
if (netgame && serverrunning)
|
||||
{
|
||||
RenewHolePunch();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if (client)
|
||||
{
|
||||
@@ -6411,18 +6718,27 @@ void NetUpdate(void)
|
||||
MasterClient_Ticker(); // Acking the Master Server
|
||||
#endif
|
||||
|
||||
#ifdef HOLEPUNCH
|
||||
#ifdef HOLEPUNCH
|
||||
if (netgame && serverrunning)
|
||||
{
|
||||
RenewHolePunch();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (client)
|
||||
{
|
||||
#ifdef SATURNSYNCH
|
||||
// If the client just finished redownloading the game state, load it
|
||||
if (cl_redownloadinggamestate && fileneeded[0].status == FS_FOUND)
|
||||
CL_ReloadReceivedSavegame();
|
||||
#endif
|
||||
if (!resynch_local_inprogress)
|
||||
CL_SendClientCmd(); // Send tic cmd
|
||||
|
||||
hu_resynching = resynch_local_inprogress;
|
||||
#ifdef SATURNSYNCH
|
||||
hu_redownloadinggamestate = cl_redownloadinggamestate;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6431,6 +6747,9 @@ void NetUpdate(void)
|
||||
INT32 counts;
|
||||
|
||||
hu_resynching = false;
|
||||
#ifdef SATURNSYNCH
|
||||
hu_redownloadinggamestate = false;
|
||||
#endif
|
||||
|
||||
firstticstosend = gametic;
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
@@ -6532,7 +6851,7 @@ rewind_t *CL_SaveRewindPoint(size_t demopos)
|
||||
return NULL;
|
||||
|
||||
save_p = rewind->savebuffer;
|
||||
P_SaveNetGame();
|
||||
P_SaveNetGame(false);
|
||||
rewind->leveltime = leveltime;
|
||||
rewind->next = rewindhead;
|
||||
rewind->demopos = demopos;
|
||||
@@ -6556,7 +6875,7 @@ rewind_t *CL_RewindToTime(tic_t time)
|
||||
return NULL;
|
||||
|
||||
save_p = rewindhead->savebuffer;
|
||||
P_LoadNetGame();
|
||||
P_LoadNetGame(false);
|
||||
wipegamestate = gamestate; // No fading back in!
|
||||
timeinmap = leveltime;
|
||||
|
||||
|
||||
+26
-2
@@ -98,6 +98,16 @@ typedef enum
|
||||
PT_MOREFILESNEEDED, // Server, to client: "you need these (+ more on top of those)"
|
||||
|
||||
PT_PING, // Packet sent to tell clients the other client's latency to server.
|
||||
|
||||
#ifdef SATURNSYNCH
|
||||
PT_WILLRESENDGAMESTATE, // Hey Client, I am about to resend you the gamestate!
|
||||
PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead.
|
||||
PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again!
|
||||
|
||||
// we will reserve this for now even if unused, so order wont get mangled
|
||||
PT_ISSATURN, // Saturn specific identifier packet
|
||||
#endif
|
||||
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
@@ -363,6 +373,9 @@ typedef struct
|
||||
UINT8 subversion; // Contains build version
|
||||
UINT8 localplayers; // number of splitscreen players
|
||||
UINT8 mode;
|
||||
#ifdef SATURNJOIN
|
||||
UINT8 issaturn;
|
||||
#endif
|
||||
} ATTRPACK clientconfig_pak;
|
||||
|
||||
#define SV_SPEEDMASK 0x03 // used to send kartspeed
|
||||
@@ -567,14 +580,22 @@ extern consvar_t
|
||||
#ifdef VANILLAJOINNEXTROUND
|
||||
cv_joinnextround,
|
||||
#endif
|
||||
cv_netticbuffer, cv_allownewplayer, cv_joinrefusemessage, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
cv_netticbuffer, cv_allownewplayer,
|
||||
#ifdef SATURNJOIN
|
||||
cv_allownewsaturnplayer,
|
||||
#endif
|
||||
cv_joinrefusemessage, cv_maxplayers, cv_resynchattempts,
|
||||
#ifdef SATURNSYNCH
|
||||
cv_resynchcooldown, cv_gamestateattempts,
|
||||
#endif
|
||||
cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
|
||||
extern consvar_t cv_connectawaittime;
|
||||
|
||||
extern consvar_t cv_discordinvites;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
tic_t ExpandTics(INT32 low, tic_t basetic);
|
||||
//tic_t ExpandTics(INT32 low, tic_t basetic);
|
||||
void D_ClientServerInit(void);
|
||||
|
||||
// Initialise the other field
|
||||
@@ -632,6 +653,9 @@ tic_t GetLag(INT32 node);
|
||||
UINT8 GetFreeXCmdSize(void);
|
||||
|
||||
extern UINT8 hu_resynching;
|
||||
#ifdef SATURNSYNCH
|
||||
extern UINT8 hu_redownloadinggamestate;
|
||||
#endif
|
||||
extern UINT8 hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
|
||||
|
||||
typedef struct rewind_s {
|
||||
|
||||
+139
-39
@@ -37,6 +37,7 @@
|
||||
#include "d_net.h"
|
||||
#include "f_finale.h"
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "i_sound.h"
|
||||
#include "i_system.h"
|
||||
@@ -103,11 +104,12 @@ static char *startupwadfiles[MAX_WADFILES];
|
||||
static char *startuppwads[MAX_WADFILES];
|
||||
|
||||
// autoloading
|
||||
static char *autoloadwadfiles[MAX_WADFILES];
|
||||
char *autoloadwadfiles[MAX_WADFILES];
|
||||
char *autoloadwadfilespost[MAX_WADFILES];
|
||||
boolean autoloading;
|
||||
boolean autoloaded;
|
||||
boolean postautoloaded;
|
||||
boolean postautoloaded = false;
|
||||
boolean wasautoloaded = false;
|
||||
|
||||
boolean devparm = false; // started game with -devparm
|
||||
|
||||
@@ -149,6 +151,8 @@ INT32 eventhead, eventtail;
|
||||
|
||||
boolean dedicated = false;
|
||||
|
||||
boolean loaded_config = false;
|
||||
|
||||
//
|
||||
// D_PostEvent
|
||||
// Called by the I/O functions when input is detected
|
||||
@@ -166,6 +170,32 @@ UINT8 ctrldown = 0; // 0x1 left, 0x2 right
|
||||
UINT8 altdown = 0; // 0x1 left, 0x2 right
|
||||
boolean capslock = 0; // gee i wonder what this does.
|
||||
|
||||
static inline void D_DeviceLEDTick(void)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT16 color[MAXSPLITSCREENPLAYERS];
|
||||
UINT16 curcolor[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
if (I_NumJoys() == 0 || (cv_gamepadled[0].value == 0 && cv_gamepadled[1].value == 0 && cv_gamepadled[2].value == 0 && cv_gamepadled[3].value == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (G_GetDeviceForPlayer(i) == 0)
|
||||
continue;
|
||||
|
||||
color[i] = G_GetSkinColor(i);
|
||||
|
||||
if (curcolor[i] == color[i]) // dont update if same colour
|
||||
continue;
|
||||
|
||||
G_SetPlayerGamepadIndicatorColor(i, color[i]);
|
||||
curcolor[i] = color[i];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// D_ProcessEvents
|
||||
// Send all the events of the given timestamp down the responder chain
|
||||
@@ -242,8 +272,9 @@ void D_ProcessEvents(void)
|
||||
// added comment : there is a wipe eatch change of the gamestate
|
||||
gamestate_t wipegamestate = GS_LEVEL;
|
||||
|
||||
static void D_Display(void)
|
||||
static boolean D_Display(void)
|
||||
{
|
||||
boolean ranwipe = false;
|
||||
boolean forcerefresh = false;
|
||||
static boolean wipe = false;
|
||||
INT32 wipedefindex = 0;
|
||||
@@ -252,7 +283,7 @@ static void D_Display(void)
|
||||
if (!dedicated)
|
||||
{
|
||||
if (nodrawers)
|
||||
return; // for comparative timing/profiling
|
||||
return false; // for comparative timing/profiling
|
||||
|
||||
// check for change of screen size (video mode)
|
||||
if (setmodeneeded && !wipe)
|
||||
@@ -262,7 +293,10 @@ static void D_Display(void)
|
||||
SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()
|
||||
|
||||
if (rendermode == render_soft && !splitscreen)
|
||||
{
|
||||
R_InterpolateViewRollAngle(rendertimefrac);
|
||||
R_CheckViewMorph();
|
||||
}
|
||||
|
||||
// change the view size if needed
|
||||
if (setsizeneeded)
|
||||
@@ -302,6 +336,7 @@ static void D_Display(void)
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
|
||||
ranwipe = true;
|
||||
}
|
||||
|
||||
if (gamestate != GS_LEVEL && rendermode != render_none)
|
||||
@@ -315,12 +350,13 @@ static void D_Display(void)
|
||||
else //dedicated servers
|
||||
{
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
|
||||
ranwipe = true;
|
||||
wipegamestate = gamestate;
|
||||
}
|
||||
}
|
||||
|
||||
if (dedicated) //bail out after wipe logic
|
||||
return;
|
||||
return false;
|
||||
|
||||
// do buffered drawing
|
||||
switch (gamestate)
|
||||
@@ -427,7 +463,7 @@ static void D_Display(void)
|
||||
viewssnum = i;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
if (rendermode == render_opengl)
|
||||
HWR_RenderPlayerView(i, &players[displayplayers[i]]);
|
||||
else
|
||||
#endif
|
||||
@@ -482,8 +518,10 @@ static void D_Display(void)
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (postimgtype[i])
|
||||
V_DoPostProcessor(i, postimgtype[i], postimgparam[i]);
|
||||
if (!postimgtype[i])
|
||||
continue;
|
||||
|
||||
V_DoPostProcessor(i, postimgtype[i], postimgparam[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,7 +535,6 @@ static void D_Display(void)
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
|
||||
usebuffer = true;
|
||||
}
|
||||
lastdraw = false;
|
||||
}
|
||||
@@ -561,11 +598,10 @@ static void D_Display(void)
|
||||
{
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
|
||||
ranwipe = true;
|
||||
}
|
||||
}
|
||||
|
||||
NetUpdate(); // send out any new accumulation
|
||||
|
||||
// It's safe to end the game now.
|
||||
if (G_GetExitGameFlag())
|
||||
{
|
||||
@@ -610,6 +646,7 @@ static void D_Display(void)
|
||||
PS_STOP_TIMING(ps_swaptime);
|
||||
}
|
||||
|
||||
return ranwipe;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
@@ -627,6 +664,7 @@ void D_SRB2Loop(void)
|
||||
|
||||
boolean interp = false;
|
||||
boolean doDisplay = false;
|
||||
int frameskip = 0;
|
||||
|
||||
if (dedicated)
|
||||
server = true;
|
||||
@@ -671,6 +709,8 @@ void D_SRB2Loop(void)
|
||||
capbudget = (precise_t) budget;
|
||||
}
|
||||
|
||||
boolean ranwipe = false;
|
||||
|
||||
I_UpdateTime(cv_timescale.value);
|
||||
|
||||
if (lastwipetic)
|
||||
@@ -703,9 +743,11 @@ void D_SRB2Loop(void)
|
||||
HW3S_BeginFrameUpdate();
|
||||
#endif
|
||||
|
||||
renderisnewtic = (realtics > 0 || singletics);
|
||||
|
||||
refreshdirmenu = 0; // not sure where to put this, here as good as any?
|
||||
|
||||
if (realtics > 0 || singletics)
|
||||
if (renderisnewtic)
|
||||
{
|
||||
// don't skip more than 10 frames at a time
|
||||
// (fadein / fadeout cause massive frame skip!)
|
||||
@@ -724,14 +766,20 @@ void D_SRB2Loop(void)
|
||||
}
|
||||
else if (rendertimeout < entertic) // in case the server hang or netsplit
|
||||
{
|
||||
// Lagless camera! Yay!
|
||||
if (cv_laglesscam.value && gamestate == GS_LEVEL && netgame)
|
||||
{
|
||||
// Evaluate the chase cam once for every local realtic
|
||||
// This might actually be better suited inside G_Ticker or TryRunTics
|
||||
for (tic_t chasecamtics = 0; chasecamtics < realtics; chasecamtics++)
|
||||
{
|
||||
P_RunChaseCameras();
|
||||
}
|
||||
R_UpdateViewInterpolation();
|
||||
}
|
||||
|
||||
doDisplay = true;
|
||||
}
|
||||
|
||||
renderisnewtic = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderisnewtic = false;
|
||||
}
|
||||
|
||||
if (interp)
|
||||
@@ -753,9 +801,9 @@ void D_SRB2Loop(void)
|
||||
rendertimefrac = FRACUNIT;
|
||||
}
|
||||
|
||||
if (interp || doDisplay)
|
||||
if ((interp || doDisplay) && !frameskip)
|
||||
{
|
||||
D_Display();
|
||||
ranwipe = D_Display();
|
||||
}
|
||||
|
||||
// Only take screenshots after drawing.
|
||||
@@ -818,8 +866,34 @@ void D_SRB2Loop(void)
|
||||
else
|
||||
menuInputDelayTimer = 0;
|
||||
|
||||
if (!dedicated && renderisnewtic) // idk does this need dedi check??
|
||||
D_DeviceLEDTick();
|
||||
|
||||
// Fully completed frame made.
|
||||
finishprecise = I_GetPreciseTime();
|
||||
|
||||
// Use the time before sleep for frameskip calculations:
|
||||
// post-sleep time is literally being intentionally wasted
|
||||
deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision();
|
||||
deltatics = deltasecs * NEWTICRATE;
|
||||
|
||||
// If time spent this game loop exceeds a single tic,
|
||||
// it's probably because of rendering.
|
||||
//
|
||||
// Skip rendering the next frame, up to a limit of 3
|
||||
// frames before a frame is rendered no matter what.
|
||||
//
|
||||
// Wipes run an inner loop and artificially increase
|
||||
// the measured time.
|
||||
if (!ranwipe && frameskip < 3 && deltatics > 1.0)
|
||||
{
|
||||
frameskip++;
|
||||
}
|
||||
else
|
||||
{
|
||||
frameskip = 0;
|
||||
}
|
||||
|
||||
if (!singletics)
|
||||
{
|
||||
INT64 elapsed = (INT64)(finishprecise - enterprecise);
|
||||
@@ -945,7 +1019,7 @@ static INT32 D_DetectFileType(const char* filename)
|
||||
return 5;
|
||||
else if (!stricmp(&filename[strlen(filename) - 4], ".soc"))
|
||||
return 6;
|
||||
|
||||
|
||||
else if (!stricmp(&filename[strlen(filename) - 4], ".cfg"))
|
||||
return 7;
|
||||
else if (!stricmp(&filename[strlen(filename) - 4], ".txt"))
|
||||
@@ -969,12 +1043,12 @@ static void D_AutoloadFile(const char *file, char **filearray)
|
||||
if (!newfile)
|
||||
I_Error("No more free memory to AutoloadFile %s",file);
|
||||
|
||||
if (!fileType)
|
||||
if (!fileType)
|
||||
{
|
||||
CONS_Printf("D_AutoloadFile: File %s is unknown or invalid\n", file);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
strcpy(newfile, file);
|
||||
|
||||
if (fileType <= 6)
|
||||
@@ -1014,7 +1088,10 @@ static void D_FindAddonsToAutoload(void)
|
||||
|
||||
// If the file is found, run our shit
|
||||
if (!autoloadconfigfile) // nope outta here
|
||||
{
|
||||
wasautoloaded = postautoloaded = true; // so D_AddAutoloadFiles can skip everything since nothings there to autoload
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(wadsToAutoload, sizeof wadsToAutoload, autoloadconfigfile) != NULL)
|
||||
{
|
||||
@@ -1081,6 +1158,32 @@ static void D_FindAddonsToAutoload(void)
|
||||
fclose(autoloadconfigfile);
|
||||
}
|
||||
|
||||
void D_AddAutoloadFiles(void)
|
||||
{
|
||||
if (wasautoloaded && postautoloaded)
|
||||
return;
|
||||
|
||||
if (!wasautoloaded && !modeattacking)
|
||||
{
|
||||
CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0)
|
||||
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfiles);
|
||||
|
||||
wasautoloaded = true;
|
||||
}
|
||||
|
||||
if ((!postautoloaded) && netgame)
|
||||
{
|
||||
CONS_Printf("D_AutoloadFile(): Loading postloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfilespost) == 0)
|
||||
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfilespost);
|
||||
|
||||
postautoloaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
void D_CleanFile(char **filearray)
|
||||
{
|
||||
size_t pnumwadfiles;
|
||||
@@ -1186,13 +1289,13 @@ static void IdentifyVersion(void)
|
||||
D_AddFile(va(pandf,srb2waddir,"extra.kart"), startupwadfiles);
|
||||
found_extra_kart = true;
|
||||
}
|
||||
|
||||
|
||||
// completely optional 2: Back with a vengence
|
||||
if (FIL_ReadFileOK(va(pandf,srb2waddir,"extra2.kart"))) {
|
||||
D_AddFile(va(pandf,srb2waddir,"extra2.kart"), startupwadfiles);
|
||||
found_extra2_kart = true;
|
||||
}
|
||||
|
||||
|
||||
if (FIL_ReadFileOK(va(pandf,srb2waddir,"extra3.kart"))) {
|
||||
D_AddFile(va(pandf,srb2waddir,"extra3.kart"), startupwadfiles);
|
||||
found_extra3_kart = true;
|
||||
@@ -1495,7 +1598,7 @@ void D_SRB2Main(void)
|
||||
if (found_extra_kart || found_extra2_kart || found_extra3_kart) // found the funny, add it in!
|
||||
{
|
||||
// HAYA: These are seperated for a reason lmao
|
||||
if (found_extra_kart)
|
||||
if (found_extra_kart)
|
||||
mainwads++;
|
||||
if (found_extra2_kart)
|
||||
mainwads++;
|
||||
@@ -1523,7 +1626,7 @@ void D_SRB2Main(void)
|
||||
achi_speedo_clr = true;
|
||||
|
||||
// check for bigger lap count
|
||||
if (W_CheckMultipleLumps("K_STLAPB", "K_STLA2B", NULL))
|
||||
if (W_CheckMultipleLumps("K_STLAPB", "K_STLA2B", NULL))
|
||||
big_lap = true;
|
||||
|
||||
// now check for colour hud stuff
|
||||
@@ -1532,7 +1635,7 @@ void D_SRB2Main(void)
|
||||
clr_hud = true;
|
||||
|
||||
// check for bigger lap count but color** its color bitch
|
||||
if (W_CheckMultipleLumps("K_SCLAPB", "K_SCLA2B", NULL))
|
||||
if (W_CheckMultipleLumps("K_SCLAPB", "K_SCLA2B", NULL))
|
||||
big_lap_color = true;
|
||||
|
||||
// kartzspeedo
|
||||
@@ -1547,16 +1650,16 @@ void D_SRB2Main(void)
|
||||
|
||||
// stat display for extended player setup
|
||||
if (W_CheckMultipleLumps("K_STATNB", "K_STATN1", "K_STATN2", "K_STATN3", "K_STATN4", \
|
||||
"K_STATN5", "K_STATN6", NULL))
|
||||
"K_STATN5", "K_STATN6", NULL))
|
||||
statdp = true;
|
||||
|
||||
// Nametag stuffs
|
||||
if (W_CheckMultipleLumps("NTLINE", "NTLINEV", "NTSP", "NTWH", NULL))
|
||||
if (W_CheckMultipleLumps("NTLINE", "NTLINEV", "NTSP", "NTWH", NULL))
|
||||
nametaggfx = true;
|
||||
|
||||
if (W_CheckMultipleLumps("K_DGAU","K_DCAU","K_DGSU","K_DCSU", NULL))
|
||||
if (W_CheckMultipleLumps("K_DGAU","K_DCAU","K_DGSU","K_DCSU", NULL))
|
||||
driftgaugegfx = true;
|
||||
|
||||
|
||||
if (found_extra3_kart)
|
||||
{
|
||||
// 80x11 speedometer crap
|
||||
@@ -1569,7 +1672,7 @@ void D_SRB2Main(void)
|
||||
if (W_LumpExists("SC_SM3TC"))
|
||||
xtra_speedo_clr3 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef PUSHSPEEDO
|
||||
memcpy(speedo_cons_t, speedo_cons_temp, sizeof(speedo_cons_t));
|
||||
@@ -1683,6 +1786,8 @@ void D_SRB2Main(void)
|
||||
|
||||
savedata.lives = 0; // flag this as not-used
|
||||
|
||||
loaded_config = true; // so pallettechange doesent get called 500 times at startup lol
|
||||
|
||||
//------------------------------------------------ COMMAND LINE PARAMS
|
||||
|
||||
// this must be done after loading gamedata,
|
||||
@@ -1767,11 +1872,6 @@ void D_SRB2Main(void)
|
||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||
ST_Init();
|
||||
|
||||
CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0)
|
||||
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfiles);
|
||||
|
||||
// Set up splitscreen players before joining!
|
||||
if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm()))
|
||||
{
|
||||
@@ -1976,7 +2076,7 @@ void D_SRB2Main(void)
|
||||
pagename = "TITLESKY";
|
||||
levelstarttic = gametic;
|
||||
G_SetGamestate(GS_LEVEL);
|
||||
if (!P_SetupLevel(false))
|
||||
if (!P_SetupLevel(false, false))
|
||||
I_Quit(); // fail so reset game stuff
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
// make sure not to write back the config until it's been correctly loaded
|
||||
extern tic_t rendergametic;
|
||||
|
||||
extern boolean loaded_config;
|
||||
|
||||
extern char srb2home[256]; //Alam: My Home
|
||||
extern boolean usehome; //Alam: which path?
|
||||
extern const char *pandf; //Alam: how to path?
|
||||
@@ -43,12 +45,15 @@ extern boolean statdp; // stat display for extended player setup
|
||||
extern boolean nametaggfx; // Nametag stuffs
|
||||
extern boolean driftgaugegfx;
|
||||
|
||||
void D_AddAutoloadFiles(void);
|
||||
|
||||
extern boolean autoloading;
|
||||
extern boolean autoloaded;
|
||||
extern boolean postautoloaded;
|
||||
extern boolean wasautoloaded;
|
||||
|
||||
extern char *autoloadwadfilespost[MAX_WADFILES];
|
||||
extern char *autoloadwadfiles[MAX_WADFILES];
|
||||
|
||||
// the infinite loop of D_SRB2Loop() called from win_main for windows version
|
||||
void D_SRB2Loop(void) FUNCNORETURN;
|
||||
|
||||
+22
-29
@@ -64,9 +64,6 @@ static doomdata_t reboundstore[MAXREBOUND];
|
||||
static INT16 reboundsize[MAXREBOUND];
|
||||
static INT32 rebound_head, rebound_tail;
|
||||
|
||||
/// \brief bandwith of netgame
|
||||
INT32 net_bandwidth;
|
||||
|
||||
/// \brief max length per packet
|
||||
INT16 hardware_MAXPACKETLENGTH;
|
||||
|
||||
@@ -793,7 +790,7 @@ static void fprintfstringnewline(char *s, size_t len)
|
||||
}
|
||||
|
||||
/// \warning Keep this up-to-date if you add/remove/rename packet types
|
||||
static const char *packettypename[NUMPACKETTYPE] =
|
||||
const char *packettypename[NUMPACKETTYPE] =
|
||||
{
|
||||
"NOTHING",
|
||||
"SERVERCFG",
|
||||
@@ -836,13 +833,31 @@ static const char *packettypename[NUMPACKETTYPE] =
|
||||
"MOREFILESNEEDED",
|
||||
|
||||
"PING"
|
||||
#ifdef SATURNSYNCH
|
||||
,
|
||||
|
||||
"WILLRESENDGAMESTATE",
|
||||
"CANRECEIVEGAMESTATE",
|
||||
"RECEIVEDGAMESTATE",
|
||||
|
||||
// we will reserve this for now even if unused, so order wont get mangled
|
||||
"ISSATURN"
|
||||
#endif
|
||||
};
|
||||
|
||||
const char *Net_GetPacketName(UINT8 packettype)
|
||||
{
|
||||
if (packettype >= NUMPACKETTYPE)
|
||||
return "UNKNOWN";
|
||||
|
||||
return packettypename[packettype];
|
||||
}
|
||||
|
||||
static void DebugPrintpacket(const char *header)
|
||||
{
|
||||
fprintf(debugfile, "%-12s (node %d,ack %d,ackret %d,size %d) type(%d) : %s\n",
|
||||
header, doomcom->remotenode, netbuffer->ack, netbuffer->ackreturn, doomcom->datalength,
|
||||
netbuffer->packettype, packettypename[netbuffer->packettype]);
|
||||
netbuffer->packettype, Net_GetPacketName(netbuffer->packettype));
|
||||
|
||||
switch (netbuffer->packettype)
|
||||
{
|
||||
@@ -1208,7 +1223,7 @@ boolean HGetPacket(void)
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif // ndef NONET
|
||||
#endif // ifndef NONET
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1258,10 +1273,7 @@ void D_SetDoomcom(void)
|
||||
{
|
||||
if (doomcom) return;
|
||||
doomcom = Z_Calloc(sizeof (doomcom_t), PU_STATIC, NULL);
|
||||
doomcom->id = DOOMCOM_ID;
|
||||
doomcom->numslots = doomcom->numnodes = 1;
|
||||
doomcom->gametype = 0;
|
||||
doomcom->consoleplayer = 0;
|
||||
doomcom->extratics = 0;
|
||||
}
|
||||
|
||||
@@ -1286,7 +1298,6 @@ boolean D_CheckNetGame(void)
|
||||
I_NetMakeNodewPort = NULL;
|
||||
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
net_bandwidth = 30000;
|
||||
// I_InitNetwork sets doomcom and netgame
|
||||
// check and initialize the network driver
|
||||
multiplayer = false;
|
||||
@@ -1306,7 +1317,6 @@ boolean D_CheckNetGame(void)
|
||||
server = true; // WTF? server always true???
|
||||
// no! The deault mode is server. Client is set elsewhere
|
||||
// when the client executes connect command.
|
||||
doomcom->ticdup = 1;
|
||||
|
||||
if (M_CheckParm("-extratic"))
|
||||
{
|
||||
@@ -1317,21 +1327,6 @@ boolean D_CheckNetGame(void)
|
||||
CONS_Printf(M_GetText("Set extratics to %d\n"), doomcom->extratics);
|
||||
}
|
||||
|
||||
if (M_CheckParm("-bandwidth"))
|
||||
{
|
||||
if (M_IsNextParm())
|
||||
{
|
||||
net_bandwidth = atoi(M_GetNextParm());
|
||||
if (net_bandwidth < 1000)
|
||||
net_bandwidth = 1000;
|
||||
if (net_bandwidth > 100000)
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
CONS_Printf(M_GetText("Network bandwidth set to %d\n"), net_bandwidth);
|
||||
}
|
||||
else
|
||||
I_Error("usage: -bandwidth <byte_per_sec>");
|
||||
}
|
||||
|
||||
software_MAXPACKETLENGTH = hardware_MAXPACKETLENGTH;
|
||||
if (M_CheckParm("-packetsize"))
|
||||
{
|
||||
@@ -1351,8 +1346,6 @@ boolean D_CheckNetGame(void)
|
||||
if (netgame)
|
||||
multiplayer = true;
|
||||
|
||||
if (doomcom->id != DOOMCOM_ID)
|
||||
I_Error("Doomcom buffer invalid!");
|
||||
if (doomcom->numnodes > MAXNETNODES)
|
||||
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
|
||||
|
||||
@@ -1365,7 +1358,7 @@ boolean D_CheckNetGame(void)
|
||||
if (M_CheckParm("-debugfile"))
|
||||
{
|
||||
char filename[21];
|
||||
INT32 k = doomcom->consoleplayer - 1;
|
||||
INT32 k = consoleplayer - 1;
|
||||
if (M_IsNextParm())
|
||||
k = atoi(M_GetNextParm()) - 1;
|
||||
while (!debugfile && k < MAXPLAYERS)
|
||||
|
||||
@@ -65,5 +65,6 @@ void Net_ConnectionTimeout(INT32 node);
|
||||
void Net_AbortPacketType(UINT8 packettype);
|
||||
void Net_SendAcks(INT32 node);
|
||||
void Net_WaitAllAckReceived(UINT32 timeout);
|
||||
const char *Net_GetPacketName(UINT8 packettype);
|
||||
|
||||
#endif
|
||||
+65
-11
@@ -299,6 +299,9 @@ consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t,
|
||||
//WTF
|
||||
consvar_t cv_mouseturn = {"mouseturn", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Lagless camera! Yay!
|
||||
consvar_t cv_laglesscam = {"laglesscamera", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#if defined(HAVE_SDL) || defined(_WINDOWS) //joystick 1 and 2
|
||||
consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t,
|
||||
I_InitJoystick, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -394,6 +397,7 @@ static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometer
|
||||
consvar_t cv_kartspeedometer = {"kartdisplayspeed", "Off", CV_SAVE, kartspeedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display
|
||||
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};
|
||||
consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_karthitemdialog = {"karthitemdialog", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -561,6 +565,10 @@ static CV_PossibleValue_t ps_descriptor_cons_t[] = {
|
||||
{1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}};
|
||||
consvar_t cv_ps_descriptor = {"ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_director = {"director", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartdebugdirector = {"debugdirector", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_showdirectorhud = {"showdirectorhud", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_showtrackaddon = {"showtrackaddon", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t skinselectmenu_t[] = {{SKINMENUTYPE_SCROLL, "Scroll"}, {SKINMENUTYPE_2D, "2d"}, {SKINMENUTYPE_GRID, "Grid"}, {SKINMENUTYPE_EXTENDED, "Extended"}, {0, NULL}};
|
||||
@@ -577,7 +585,8 @@ static CV_PossibleValue_t skinselectgridsort_t[] ={
|
||||
};
|
||||
consvar_t cv_skinselectgridsort ={ "skinselectgridsort", "Real name", CV_SAVE|CV_CALL|CV_NOINIT, skinselectgridsort_t, sortSkinGrid, 0, NULL, NULL, 0, 0, NULL };
|
||||
|
||||
consvar_t cv_betainterscreen = {"betaintermissionscreen", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t betainterscreen_t[] = {{0, "Off"}, {1, "On"}, {2, "NoBG"}, {0, NULL}};
|
||||
consvar_t cv_betainterscreen = {"betaintermissionscreen", "Off", CV_SAVE, betainterscreen_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
INT16 gametype = GT_RACE; // SRB2kart
|
||||
boolean forceresetplayers = false;
|
||||
@@ -779,6 +788,10 @@ void D_RegisterServerCommands(void)
|
||||
// d_clisrv
|
||||
CV_RegisterVar(&cv_maxplayers);
|
||||
CV_RegisterVar(&cv_resynchattempts);
|
||||
#ifdef SATURNSYNCH
|
||||
CV_RegisterVar(&cv_gamestateattempts);
|
||||
CV_RegisterVar(&cv_resynchcooldown);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_maxsend);
|
||||
CV_RegisterVar(&cv_noticedownload);
|
||||
CV_RegisterVar(&cv_downloadspeed);
|
||||
@@ -786,6 +799,9 @@ void D_RegisterServerCommands(void)
|
||||
CV_RegisterVar(&cv_httpsource);
|
||||
#ifndef NONET
|
||||
CV_RegisterVar(&cv_allownewplayer);
|
||||
#ifdef SATURNJOIN
|
||||
CV_RegisterVar(&cv_allownewsaturnplayer);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_joinrefusemessage);
|
||||
CV_RegisterVar(&cv_chatlogsize);
|
||||
#ifdef VANILLAJOINNEXTROUND
|
||||
@@ -823,9 +839,9 @@ void D_RegisterServerCommands(void)
|
||||
CV_RegisterVar(&cv_recordmultiplayerdemos);
|
||||
CV_RegisterVar(&cv_netdemosyncquality);
|
||||
CV_RegisterVar(&cv_maxdemosize);
|
||||
CV_RegisterVar(&cv_demochangemap);
|
||||
|
||||
CV_RegisterVar(&cv_keyboardlayout);
|
||||
|
||||
CV_RegisterVar(&cv_betainterscreen);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
@@ -979,6 +995,10 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_showtrackaddon);
|
||||
CV_RegisterVar(&cv_showviewpointtext);
|
||||
|
||||
CV_RegisterVar(&cv_director);
|
||||
CV_RegisterVar(&cv_kartdebugdirector);
|
||||
CV_RegisterVar(&cv_showdirectorhud);
|
||||
|
||||
CV_RegisterVar(&cv_luaimmersion);
|
||||
CV_RegisterVar(&cv_fakelocalskin);
|
||||
|
||||
@@ -992,6 +1012,7 @@ void D_RegisterClientCommands(void)
|
||||
//CV_RegisterVar(&cv_alwaysfreelook2);
|
||||
//CV_RegisterVar(&cv_chasefreelook);
|
||||
//CV_RegisterVar(&cv_chasefreelook2);
|
||||
CV_RegisterVar(&cv_replaysearchrate);
|
||||
CV_RegisterVar(&cv_showfocuslost);
|
||||
CV_RegisterVar(&cv_pauseifunfocused);
|
||||
|
||||
@@ -1066,6 +1087,21 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_controlperkey);
|
||||
CV_RegisterVar(&cv_turnsmooth);
|
||||
|
||||
CV_RegisterVar(&cv_rumble[0]);
|
||||
CV_RegisterVar(&cv_rumble[1]);
|
||||
CV_RegisterVar(&cv_rumble[2]);
|
||||
CV_RegisterVar(&cv_rumble[3]);
|
||||
|
||||
CV_RegisterVar(&cv_gamepadled[0]);
|
||||
CV_RegisterVar(&cv_gamepadled[1]);
|
||||
CV_RegisterVar(&cv_gamepadled[2]);
|
||||
CV_RegisterVar(&cv_gamepadled[3]);
|
||||
|
||||
CV_RegisterVar(&cv_ledpowerup[0]);
|
||||
CV_RegisterVar(&cv_ledpowerup[1]);
|
||||
CV_RegisterVar(&cv_ledpowerup[2]);
|
||||
CV_RegisterVar(&cv_ledpowerup[3]);
|
||||
|
||||
CV_RegisterVar(&cv_usemouse);
|
||||
CV_RegisterVar(&cv_usemouse2);
|
||||
CV_RegisterVar(&cv_invertmouse);
|
||||
@@ -1158,6 +1194,10 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
CV_RegisterVar(&cv_showmusicfilename);
|
||||
|
||||
CV_RegisterVar(&cv_betainterscreen);
|
||||
|
||||
CV_RegisterVar(&cv_laglesscam);
|
||||
|
||||
// ingame object placing
|
||||
COM_AddCommand("objectplace", Command_ObjectPlace_f);
|
||||
COM_AddCommand("writethings", Command_Writethings_f);
|
||||
@@ -1654,8 +1694,9 @@ static void SendNameAndColor(void)
|
||||
cv_skin.value = R_SkinAvailable(cv_skin.string);
|
||||
if (cv_skin.value < 0)
|
||||
{
|
||||
CV_StealthSet(&cv_skin, DEFAULTSKIN);
|
||||
cv_skin.value = 0;
|
||||
INT32 skinnum = players[consoleplayer].skin;
|
||||
CV_StealthSet(&cv_skin, skins[skinnum].name);
|
||||
cv_skin.value = skinnum;
|
||||
}
|
||||
|
||||
// Finally write out the complete packet and send it off.
|
||||
@@ -1783,8 +1824,9 @@ static void SendNameAndColor2(void)
|
||||
cv_skin2.value = R_SkinAvailable(cv_skin2.string);
|
||||
if (cv_skin2.value < 0)
|
||||
{
|
||||
CV_StealthSet(&cv_skin2, DEFAULTSKIN);
|
||||
cv_skin2.value = 0;
|
||||
INT32 skinnum = players[displayplayers[1]].skin;
|
||||
CV_StealthSet(&cv_skin2, skins[skinnum].name);
|
||||
cv_skin2.value = skinnum;
|
||||
}
|
||||
|
||||
// Finally write out the complete packet and send it off.
|
||||
@@ -1903,8 +1945,9 @@ static void SendNameAndColor3(void)
|
||||
cv_skin3.value = R_SkinAvailable(cv_skin3.string);
|
||||
if (cv_skin3.value < 0)
|
||||
{
|
||||
CV_StealthSet(&cv_skin3, DEFAULTSKIN);
|
||||
cv_skin3.value = 0;
|
||||
INT32 skinnum = players[displayplayers[2]].skin;
|
||||
CV_StealthSet(&cv_skin3, skins[skinnum].name);
|
||||
cv_skin3.value = skinnum;
|
||||
}
|
||||
|
||||
// Finally write out the complete packet and send it off.
|
||||
@@ -2031,8 +2074,9 @@ static void SendNameAndColor4(void)
|
||||
cv_skin4.value = R_SkinAvailable(cv_skin4.string);
|
||||
if (cv_skin4.value < 0)
|
||||
{
|
||||
CV_StealthSet(&cv_skin4, DEFAULTSKIN);
|
||||
cv_skin4.value = 0;
|
||||
INT32 skinnum = players[displayplayers[3]].skin;
|
||||
CV_StealthSet(&cv_skin4, skins[skinnum].name);
|
||||
cv_skin4.value = skinnum;
|
||||
}
|
||||
|
||||
// Finally write out the complete packet and send it off.
|
||||
@@ -2937,6 +2981,10 @@ static void Command_Map_f(void)
|
||||
}
|
||||
}
|
||||
|
||||
// spend atleast 35 seconds in one map
|
||||
if (cv_demochangemap.value && demo.recording && demo.savemode != DSM_NOTSAVING && (timeinmap > 1463) && ((cv_demochangemap.value == 2 && newmapnum == gamemap) || newmapnum != gamemap))
|
||||
G_SaveDemo();
|
||||
|
||||
fromlevelselect = false;
|
||||
D_MapChange(newmapnum, newgametype, newencoremode, newresetplayers, 0, false, false);
|
||||
|
||||
@@ -5665,6 +5713,12 @@ void Command_ExitGame_f(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
if (dedicated)
|
||||
{
|
||||
CONS_Printf("This command cannot be used on dedicated server\n");
|
||||
return;
|
||||
}
|
||||
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
CV_ClearChangedFlags();
|
||||
|
||||
@@ -128,6 +128,7 @@ extern consvar_t cv_kartvoterulechanges;
|
||||
extern consvar_t cv_kartgametypepreference;
|
||||
extern consvar_t cv_kartspeedometer;
|
||||
extern consvar_t cv_kartvoices;
|
||||
extern consvar_t cv_karthitemdialog;
|
||||
|
||||
extern consvar_t cv_karteliminatelast;
|
||||
|
||||
@@ -201,12 +202,16 @@ extern consvar_t cv_ps_thinkframe_page;
|
||||
extern consvar_t cv_ps_samplesize;
|
||||
extern consvar_t cv_ps_descriptor;
|
||||
|
||||
extern consvar_t cv_director, cv_kartdebugdirector, cv_showdirectorhud;
|
||||
|
||||
extern consvar_t cv_showtrackaddon;
|
||||
|
||||
extern consvar_t cv_showspecstuff;
|
||||
|
||||
extern consvar_t cv_betainterscreen;
|
||||
|
||||
extern consvar_t cv_laglesscam;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SKINMENUTYPE_SCROLL = 0,
|
||||
|
||||
+2
-2
@@ -833,7 +833,6 @@ void SV_FileSendTicker(void)
|
||||
|
||||
netbuffer->packettype = PT_FILEFRAGMENT;
|
||||
|
||||
// (((sendbytes-nowsentbyte)*TICRATE)/(I_GetTime()-starttime)<(UINT32)net_bandwidth)
|
||||
while (packetsent-- && filestosend != 0)
|
||||
{
|
||||
for (i = currentnode, j = 0; j < MAXNETNODES;
|
||||
@@ -1300,8 +1299,9 @@ void CURLPrepareFile(const char* url, int dfilenum)
|
||||
curl_starttime = time(NULL);
|
||||
|
||||
curl_running = true;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-5
@@ -347,6 +347,14 @@ typedef enum
|
||||
RW_RAIL = 32
|
||||
} ringweapons_t;
|
||||
|
||||
// enum for saved lap times
|
||||
typedef enum
|
||||
{
|
||||
LAP_CUR,
|
||||
LAP_LAST,
|
||||
LAP__MAX
|
||||
} laptime_e;
|
||||
|
||||
// ========================================================================
|
||||
// PLAYER STRUCTURE
|
||||
// ========================================================================
|
||||
@@ -465,6 +473,7 @@ typedef struct player_s
|
||||
INT16 numboxes; // Number of item boxes obtained for Race Mode
|
||||
INT16 totalring; // Total number of rings obtained for Race Mode
|
||||
tic_t realtime; // integer replacement for leveltime
|
||||
tic_t laptime[LAP__MAX];
|
||||
UINT8 laps; // Number of laps (optional)
|
||||
|
||||
////////////////////
|
||||
@@ -537,15 +546,13 @@ typedef struct player_s
|
||||
tic_t grieftime;
|
||||
UINT8 griefstrikes;
|
||||
|
||||
tic_t hitemtimer;
|
||||
UINT8 hitemvictim;
|
||||
|
||||
UINT8 splitscreenindex;
|
||||
#ifdef HWRENDER
|
||||
fixed_t fovadd; // adjust FOV for hw rendering
|
||||
#endif
|
||||
|
||||
struct {
|
||||
angle_t aiming, awayviewaiming, frameangle;
|
||||
angle_t viewrollangle;
|
||||
} lerp;
|
||||
} player_t;
|
||||
|
||||
#endif
|
||||
+23
-163
@@ -291,8 +291,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
INT32 i;
|
||||
boolean slotfound = false;
|
||||
|
||||
DEH_WriteUndoline("PLAYERTEXT", description[num].notes, UNDO_ENDTEXT);
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
@@ -362,7 +360,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
{
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE);
|
||||
PlayerMenu[num].status = IT_CALL;
|
||||
strncpy(description[num].picname, word2, 8);
|
||||
}
|
||||
@@ -386,7 +383,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
*/
|
||||
if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, va("%d", PlayerMenu[num].status), UNDO_NONE);
|
||||
PlayerMenu[num].status = (INT16)i;
|
||||
}
|
||||
else if (fastcmp(word, "SKINNAME"))
|
||||
@@ -394,7 +390,6 @@ static void readPlayer(MYFILE *f, INT32 num)
|
||||
// Send to free slot.
|
||||
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
|
||||
goto done;
|
||||
DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE);
|
||||
PlayerMenu[num].status = IT_CALL;
|
||||
|
||||
strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
|
||||
@@ -557,122 +552,98 @@ static void readthing(MYFILE *f, INT32 num)
|
||||
|
||||
if (fastcmp(word, "MAPTHINGNUM") || fastcmp(word, "DOOMEDNUM"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].doomednum), UNDO_NONE);
|
||||
mobjinfo[num].doomednum = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SPAWNSTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].spawnstate), UNDO_NONE);
|
||||
mobjinfo[num].spawnstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SPAWNHEALTH"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].spawnhealth), UNDO_NONE);
|
||||
mobjinfo[num].spawnhealth = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SEESTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].seestate), UNDO_NONE);
|
||||
mobjinfo[num].seestate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SEESOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].seesound), UNDO_NONE);
|
||||
mobjinfo[num].seesound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "REACTIONTIME"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].reactiontime), UNDO_NONE);
|
||||
mobjinfo[num].reactiontime = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ATTACKSOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].attacksound), UNDO_NONE);
|
||||
mobjinfo[num].attacksound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "PAINSTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].painstate), UNDO_NONE);
|
||||
mobjinfo[num].painstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "PAINCHANCE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].painchance), UNDO_NONE);
|
||||
mobjinfo[num].painchance = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "PAINSOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].painsound), UNDO_NONE);
|
||||
mobjinfo[num].painsound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MELEESTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].meleestate), UNDO_NONE);
|
||||
mobjinfo[num].meleestate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MISSILESTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].missilestate), UNDO_NONE);
|
||||
mobjinfo[num].missilestate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DEATHSTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].deathstate), UNDO_NONE);
|
||||
mobjinfo[num].deathstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DEATHSOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].deathsound), UNDO_NONE);
|
||||
mobjinfo[num].deathsound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "XDEATHSTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].xdeathstate), UNDO_NONE);
|
||||
mobjinfo[num].xdeathstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SPEED"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].speed), UNDO_NONE);
|
||||
mobjinfo[num].speed = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "RADIUS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].radius), UNDO_NONE);
|
||||
mobjinfo[num].radius = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "HEIGHT"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].height), UNDO_NONE);
|
||||
mobjinfo[num].height = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DISPOFFSET"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].dispoffset), UNDO_NONE);
|
||||
mobjinfo[num].dispoffset = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MASS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].mass), UNDO_NONE);
|
||||
mobjinfo[num].mass = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DAMAGE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].damage), UNDO_NONE);
|
||||
mobjinfo[num].damage = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ACTIVESOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].activesound), UNDO_NONE);
|
||||
mobjinfo[num].activesound = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "FLAGS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].flags), UNDO_NONE);
|
||||
mobjinfo[num].flags = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "RAISESTATE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", mobjinfo[num].raisestate), UNDO_NONE);
|
||||
mobjinfo[num].raisestate = get_number(word2);
|
||||
}
|
||||
else
|
||||
@@ -1110,8 +1081,6 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
UINT16 usi;
|
||||
UINT8 picid;
|
||||
|
||||
DEH_WriteUndoline("SCENETEXT", cutscenes[num]->scene[scenenum].text, UNDO_ENDTEXT);
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
@@ -1188,7 +1157,6 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
|
||||
if (fastcmp(word, "NUMBEROFPICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", cutscenes[num]->scene[scenenum].numpics), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].numpics = (UINT8)i;
|
||||
}
|
||||
else if (fastncmp(word, "PIC", 3))
|
||||
@@ -1203,27 +1171,22 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
|
||||
if (fastcmp(word+4, "NAME"))
|
||||
{
|
||||
DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].picname[picid], UNDO_NONE);
|
||||
strncpy(cutscenes[num]->scene[scenenum].picname[picid], word2, 8);
|
||||
}
|
||||
else if (fastcmp(word+4, "HIRES"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", cutscenes[num]->scene[scenenum].pichires[picid]), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].pichires[picid] = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word+4, "DURATION"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].picduration[picid]), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].picduration[picid] = usi;
|
||||
}
|
||||
else if (fastcmp(word+4, "XCOORD"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].xcoord[picid]), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].xcoord[picid] = usi;
|
||||
}
|
||||
else if (fastcmp(word+4, "YCOORD"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].ycoord[picid]), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].ycoord[picid] = usi;
|
||||
}
|
||||
else
|
||||
@@ -1231,14 +1194,12 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
}
|
||||
else if (fastcmp(word, "MUSIC"))
|
||||
{
|
||||
DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE);
|
||||
strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7);
|
||||
cutscenes[num]->scene[scenenum].musswitch[6] = 0;
|
||||
}
|
||||
#ifdef MUSICSLOT_COMPATIBILITY
|
||||
else if (fastcmp(word, "MUSICSLOT"))
|
||||
{
|
||||
DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE);
|
||||
i = get_mus(word2, true);
|
||||
if (i && i <= 1035)
|
||||
snprintf(cutscenes[num]->scene[scenenum].musswitch, 7, "%sM", G_BuildMapName(i));
|
||||
@@ -1251,42 +1212,34 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||
#endif
|
||||
else if (fastcmp(word, "MUSICTRACK"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchflags), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK;
|
||||
}
|
||||
else if (fastcmp(word, "MUSICPOS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchposition), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].musswitchposition = (UINT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MUSICLOOP"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musicloop), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].musicloop = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "TEXTXPOS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].textxpos), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].textxpos = usi;
|
||||
}
|
||||
else if (fastcmp(word, "TEXTYPOS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].textypos), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].textypos = usi;
|
||||
}
|
||||
else if (fastcmp(word, "FADEINID"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].fadenum), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].fadeinid = (UINT8)i;
|
||||
}
|
||||
else if (fastcmp(word, "FADEOUTID"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].fadenum), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].fadeoutid = (UINT8)i;
|
||||
}
|
||||
else if (fastcmp(word, "FADECOLOR"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].fadenum), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].fadecolor = (UINT8)i;
|
||||
}
|
||||
else
|
||||
@@ -1346,8 +1299,6 @@ static void readcutscene(MYFILE *f, INT32 num)
|
||||
if (1 <= value && value <= 128)
|
||||
{
|
||||
readcutscenescene(f, num, value - 1);
|
||||
DEH_WriteUndoline(word, word2, UNDO_SPACE|UNDO_CUTLINE);
|
||||
DEH_WriteUndoline("NUMSCENES", va("%d", oldnumscenes), UNDO_SPACE);
|
||||
}
|
||||
else
|
||||
deh_warning("Scene number %d out of range (1 - 128)", value);
|
||||
@@ -1403,12 +1354,10 @@ static void readhuditem(MYFILE *f, INT32 num)
|
||||
|
||||
if (fastcmp(word, "X"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", hudinfo[num].x), UNDO_NONE);
|
||||
hudinfo[num].x = i;
|
||||
}
|
||||
else if (fastcmp(word, "Y"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", hudinfo[num].y), UNDO_NONE);
|
||||
hudinfo[num].y = i;
|
||||
}
|
||||
else
|
||||
@@ -1419,25 +1368,10 @@ static void readhuditem(MYFILE *f, INT32 num)
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
/*
|
||||
Sprite number = 10
|
||||
Sprite subnumber = 32968
|
||||
Duration = 200
|
||||
Next frame = 200
|
||||
*/
|
||||
|
||||
/** Action pointer for reading actions from Dehacked lumps.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
actionf_t action; ///< Function pointer corresponding to the actual action.
|
||||
const char *name; ///< Name of the action in ALL CAPS.
|
||||
} actionpointer_t;
|
||||
|
||||
/** Array mapping action names to action functions.
|
||||
* Names must be in ALL CAPS for case insensitive comparisons.
|
||||
*/
|
||||
static actionpointer_t actionpointers[] =
|
||||
// IMPORTANT!
|
||||
// DO NOT FORGET TO SYNC THIS LIST WITH THE ACTIONNUM ENUM IN INFO.H
|
||||
actionpointer_t actionpointers[] =
|
||||
{
|
||||
{{A_Explode}, "A_EXPLODE"},
|
||||
{{A_Pain}, "A_PAIN"},
|
||||
@@ -1592,6 +1526,7 @@ static actionpointer_t actionpointers[] =
|
||||
{{A_FZBoomSmoke}, "A_FZBOOMSMOKE"}, //SRB2kart
|
||||
{{A_RandomShadowFrame}, "A_RANDOMSHADOWFRAME"}, //SRB2kart
|
||||
{{A_RoamingShadowThinker}, "A_ROAMINGSHADOWTHINKER"}, //SRB2kart
|
||||
{{A_MayonakaArrow}, "A_MAYONAKAARROW"}, //SRB2kart
|
||||
{{A_ReaperThinker}, "A_REAPERTHINKER"}, //SRB2kart
|
||||
{{A_MementosTPParticles}, "A_MEMENTOSTPPARTICLES"}, //SRB2kart
|
||||
{{A_FlameParticle}, "A_FLAMEPARTICLE"}, // SRB2kart
|
||||
@@ -1684,32 +1619,26 @@ static void readframe(MYFILE *f, INT32 num)
|
||||
|
||||
if (fastcmp(word1, "SPRITENUMBER") || fastcmp(word1, "SPRITENAME"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%u", states[num].sprite), UNDO_NONE);
|
||||
states[num].sprite = get_sprite(word2);
|
||||
}
|
||||
else if (fastcmp(word1, "SPRITESUBNUMBER") || fastcmp(word1, "SPRITEFRAME"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%d", states[num].frame), UNDO_NONE);
|
||||
states[num].frame = (INT32)get_number(word2); // So the FF_ flags get calculated
|
||||
}
|
||||
else if (fastcmp(word1, "DURATION"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%u", states[num].tics), UNDO_NONE);
|
||||
states[num].tics = (INT32)get_number(word2); // So TICRATE can be used
|
||||
}
|
||||
else if (fastcmp(word1, "NEXT"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%d", states[num].nextstate), UNDO_NONE);
|
||||
states[num].nextstate = get_state(word2);
|
||||
}
|
||||
else if (fastcmp(word1, "VAR1"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%d", states[num].var1), UNDO_NONE);
|
||||
states[num].var1 = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word1, "VAR2"))
|
||||
{
|
||||
DEH_WriteUndoline(word1, va("%d", states[num].var2), UNDO_NONE);
|
||||
states[num].var2 = (INT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word1, "ACTION"))
|
||||
@@ -1735,7 +1664,6 @@ static void readframe(MYFILE *f, INT32 num)
|
||||
{
|
||||
if (actionpointers[z].action.acv == states[num].action.acv)
|
||||
{
|
||||
DEH_WriteUndoline(word1, actionpointers[z].name, UNDO_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1795,17 +1723,14 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
||||
|
||||
if (fastcmp(word, "SINGULAR"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE);
|
||||
S_sfx[num].singularity = value;
|
||||
}
|
||||
else if (fastcmp(word, "PRIORITY"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].priority), UNDO_NONE);
|
||||
S_sfx[num].priority = value;
|
||||
}
|
||||
else if (fastcmp(word, "FLAGS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].pitch), UNDO_NONE);
|
||||
S_sfx[num].pitch = value;
|
||||
}
|
||||
else
|
||||
@@ -1865,16 +1790,6 @@ static void reademblemdata(MYFILE *f, INT32 num)
|
||||
INT32 value;
|
||||
|
||||
// Reset all data initially
|
||||
DEH_WriteUndoline("TYPE", va("%d", emblemlocations[num-1].type), UNDO_NONE);
|
||||
DEH_WriteUndoline("X", va("%d", emblemlocations[num-1].x), UNDO_NONE);
|
||||
DEH_WriteUndoline("Y", va("%d", emblemlocations[num-1].y), UNDO_NONE);
|
||||
DEH_WriteUndoline("Z", va("%d", emblemlocations[num-1].z), UNDO_NONE);
|
||||
DEH_WriteUndoline("MAPNUM", va("%d", emblemlocations[num-1].level), UNDO_NONE);
|
||||
DEH_WriteUndoline("VAR", va("%d", emblemlocations[num-1].var), UNDO_NONE);
|
||||
DEH_WriteUndoline("SPRITE", va("%d", emblemlocations[num-1].sprite), UNDO_NONE);
|
||||
DEH_WriteUndoline("COLOR", va("%d", emblemlocations[num-1].color), UNDO_NONE);
|
||||
DEH_WriteUndoline("HINT", extraemblems[num-1].hint, UNDO_NONE);
|
||||
|
||||
memset(&emblemlocations[num-1], 0, sizeof(emblem_t));
|
||||
|
||||
do
|
||||
@@ -2002,12 +1917,6 @@ static void readextraemblemdata(MYFILE *f, INT32 num)
|
||||
INT32 value;
|
||||
|
||||
// Reset all data initially
|
||||
DEH_WriteUndoline("NAME", extraemblems[num-1].name, UNDO_NONE);
|
||||
DEH_WriteUndoline("OBJECTIVE", extraemblems[num-1].description, UNDO_NONE);
|
||||
DEH_WriteUndoline("CONDITIONSET", va("%d", extraemblems[num-1].conditionset), UNDO_NONE);
|
||||
DEH_WriteUndoline("SPRITE", va("%d", extraemblems[num-1].sprite), UNDO_NONE);
|
||||
DEH_WriteUndoline("COLOR", va("%d", extraemblems[num-1].color), UNDO_NONE);
|
||||
|
||||
memset(&extraemblems[num-1], 0, sizeof(extraemblem_t));
|
||||
|
||||
do
|
||||
@@ -2086,15 +1995,6 @@ static void readunlockable(MYFILE *f, INT32 num)
|
||||
INT32 i;
|
||||
|
||||
// Same deal with unlockables, clear all first
|
||||
DEH_WriteUndoline("NAME", unlockables[num].name, UNDO_NONE);
|
||||
DEH_WriteUndoline("OBJECTIVE", unlockables[num].objective, UNDO_NONE);
|
||||
DEH_WriteUndoline("HEIGHT", va("%d", unlockables[num].height), UNDO_NONE);
|
||||
DEH_WriteUndoline("CONDITIONSET", va("%d", unlockables[num].conditionset), UNDO_NONE);
|
||||
DEH_WriteUndoline("TYPE", va("%d", unlockables[num].type), UNDO_NONE);
|
||||
DEH_WriteUndoline("NOCECHO", va("%d", unlockables[num].nocecho), UNDO_NONE);
|
||||
DEH_WriteUndoline("NOCHECKLIST", va("%d", unlockables[num].nochecklist), UNDO_NONE);
|
||||
DEH_WriteUndoline("VAR", va("%d", unlockables[num].variable), UNDO_NONE);
|
||||
|
||||
memset(&unlockables[num], 0, sizeof(unlockable_t));
|
||||
|
||||
do
|
||||
@@ -2473,13 +2373,11 @@ static void readpatch(MYFILE *f, const char *name, UINT16 wad)
|
||||
// X position of the patch in the texture.
|
||||
if (fastcmp(word, "X"))
|
||||
{
|
||||
//DEH_WriteUndoline(word, va("%d", patch->originx), UNDO_NONE);
|
||||
patch.originx = (INT16)value;
|
||||
}
|
||||
// Y position of the patch in the texture.
|
||||
else if (fastcmp(word, "Y"))
|
||||
{
|
||||
//DEH_WriteUndoline(word, va("%d", patch->originy), UNDO_NONE);
|
||||
patch.originy = (INT16)value;
|
||||
}
|
||||
else
|
||||
@@ -2548,7 +2446,6 @@ static void readmaincfg(MYFILE *f)
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
DEH_WriteUndoline(word, va("%d", spstage_start), UNDO_NONE);
|
||||
spstage_start = (INT16)value;
|
||||
}
|
||||
else if (fastcmp(word, "SSTAGE_START"))
|
||||
@@ -2562,79 +2459,64 @@ static void readmaincfg(MYFILE *f)
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
DEH_WriteUndoline(word, va("%d", sstage_start), UNDO_NONE);
|
||||
sstage_start = (INT16)value;
|
||||
sstage_end = (INT16)(sstage_start+6); // 7 special stages total
|
||||
}
|
||||
else if (fastcmp(word, "USENIGHTSSS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", useNightsSS), UNDO_NONE);
|
||||
useNightsSS = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "REDTEAM"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", skincolor_redteam), UNDO_NONE);
|
||||
skincolor_redteam = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "BLUETEAM"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", skincolor_blueteam), UNDO_NONE);
|
||||
skincolor_blueteam = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "REDRING"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", skincolor_redring), UNDO_NONE);
|
||||
skincolor_redring = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "BLUERING"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", skincolor_bluering), UNDO_NONE);
|
||||
skincolor_bluering = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "INVULNTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", invulntics), UNDO_NONE);
|
||||
invulntics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SNEAKERTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", sneakertics), UNDO_NONE);
|
||||
sneakertics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "FLASHINGTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", flashingtics), UNDO_NONE);
|
||||
flashingtics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "TAILSFLYTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", tailsflytics), UNDO_NONE);
|
||||
tailsflytics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "UNDERWATERTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", underwatertics), UNDO_NONE);
|
||||
underwatertics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SPACETIMETICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", spacetimetics), UNDO_NONE);
|
||||
spacetimetics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "EXTRALIFETICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", extralifetics), UNDO_NONE);
|
||||
extralifetics = (UINT16)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "GAMEOVERTICS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", gameovertics), UNDO_NONE);
|
||||
gameovertics = get_number(word2);
|
||||
}
|
||||
|
||||
else if (fastcmp(word, "INTROTOPLAY"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", introtoplay), UNDO_NONE);
|
||||
introtoplay = (UINT8)get_number(word2);
|
||||
// range check, you morons.
|
||||
if (introtoplay > 128)
|
||||
@@ -2642,17 +2524,14 @@ static void readmaincfg(MYFILE *f)
|
||||
}
|
||||
else if (fastcmp(word, "LOOPTITLE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", looptitle), UNDO_NONE);
|
||||
looptitle = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "TITLESCROLLSPEED"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", titlescrollspeed), UNDO_NONE);
|
||||
titlescrollspeed = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "CREDITSCUTSCENE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", creditscutscene), UNDO_NONE);
|
||||
creditscutscene = (UINT8)get_number(word2);
|
||||
// range check, you morons.
|
||||
if (creditscutscene > 128)
|
||||
@@ -2660,27 +2539,22 @@ static void readmaincfg(MYFILE *f)
|
||||
}
|
||||
else if (fastcmp(word, "NUMDEMOS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", numDemos), UNDO_NONE);
|
||||
numDemos = (UINT8)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DEMODELAYTIME"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", demoDelayTime), UNDO_NONE);
|
||||
demoDelayTime = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DEMOIDLETIME"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", demoIdleTime), UNDO_NONE);
|
||||
demoIdleTime = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "USE1UPSOUND"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", use1upSound), UNDO_NONE);
|
||||
use1upSound = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word, "MAXXTRALIFE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", maxXtraLife), UNDO_NONE);
|
||||
maxXtraLife = (UINT8)get_number(word2);
|
||||
}
|
||||
|
||||
@@ -2694,7 +2568,6 @@ static void readmaincfg(MYFILE *f)
|
||||
I_Error("Maincfg: bad data file name '%s'\n", word2);
|
||||
|
||||
G_SaveGameData(false);
|
||||
DEH_WriteUndoline(word, gamedatafilename, UNDO_NONE);
|
||||
strlcpy(gamedatafilename, word2, sizeof (gamedatafilename));
|
||||
strlwr(gamedatafilename);
|
||||
savemoddata = true;
|
||||
@@ -2715,12 +2588,10 @@ static void readmaincfg(MYFILE *f)
|
||||
}
|
||||
else if (fastcmp(word, "RESETDATA"))
|
||||
{
|
||||
DEH_WriteUndoline(word, "0", UNDO_TODO); /// \todo
|
||||
P_ResetData(value);
|
||||
}
|
||||
else if (fastcmp(word, "CUSTOMVERSION"))
|
||||
{
|
||||
DEH_WriteUndoline(word, customversionstring, UNDO_NONE);
|
||||
strlcpy(customversionstring, word2, sizeof (customversionstring));
|
||||
}
|
||||
else
|
||||
@@ -2980,13 +2851,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
{
|
||||
G_SetGameModified(multiplayer, true);
|
||||
readmaincfg(f);
|
||||
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
||||
continue;
|
||||
}
|
||||
else if (fastcmp(word, "WIPES"))
|
||||
{
|
||||
readwipes(f);
|
||||
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
continue;
|
||||
}
|
||||
@@ -3007,7 +2876,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Character %d out of range (0 - 31)", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
continue;
|
||||
}
|
||||
@@ -3021,7 +2889,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
{
|
||||
// Read patch from spec file.
|
||||
readpatch(f, word2, wad);
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
||||
@@ -3039,13 +2906,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Thing %d out of range (0 - %d)", i, NUMMOBJTYPES-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
/* else if (fastcmp(word, "ANIMTEX"))
|
||||
{
|
||||
readAnimTex(f, i);
|
||||
// This is not a major mod.
|
||||
}*/
|
||||
else if (fastcmp(word, "LEVEL"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
@@ -3066,7 +2927,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Level number %d out of range (1 - %d)", i, NUMMAPS);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "CUTSCENE"))
|
||||
{
|
||||
@@ -3077,8 +2937,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Cutscene number %d out of range (1 - 128)", i);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
//G_SetGameModified(multiplayer, true); -- might have to reconsider in a future update
|
||||
}
|
||||
else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE"))
|
||||
{
|
||||
@@ -3095,7 +2953,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Frame %d out of range (0 - %d)", i, NUMSTATES-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "SOUND"))
|
||||
{
|
||||
@@ -3108,7 +2965,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Sound %d out of range (0 - %d)", i, NUMSFX-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
else if (fastcmp(word, "HUDITEM"))
|
||||
@@ -3122,7 +2978,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("HUD item number %d out of range (0 - %d)", i, NUMHUDITEMS-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
// This is not a major mod.
|
||||
}
|
||||
else if (fastcmp(word, "EMBLEM"))
|
||||
@@ -3143,7 +2998,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Emblem number %d out of range (1 - %d)", i, MAXEMBLEMS);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "EXTRAEMBLEM"))
|
||||
{
|
||||
@@ -3163,7 +3017,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Extra emblem number %d out of range (1 - %d)", i, MAXEXTRAEMBLEMS);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "UNLOCKABLE"))
|
||||
{
|
||||
@@ -3179,7 +3032,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Unlockable number %d out of range (1 - %d)", i, MAXUNLOCKABLES);
|
||||
ignorelines(f);
|
||||
}
|
||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "CONDITIONSET"))
|
||||
{
|
||||
@@ -3195,15 +3047,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||
deh_warning("Condition set number %d out of range (1 - %d)", i, MAXCONDITIONSETS);
|
||||
ignorelines(f);
|
||||
}
|
||||
// no undo support for this insanity yet
|
||||
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||
}
|
||||
else if (fastcmp(word, "SRB2KART"))
|
||||
{
|
||||
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
||||
if (ver != PATCHVERSION)
|
||||
deh_warning("Patch is for SRB2Kart version %d,\nonly version %d is supported", ver, PATCHVERSION);
|
||||
//DEH_WriteUndoline(word, va("%d", ver), UNDO_NONE);
|
||||
}
|
||||
else if (fastcmp(word, "SRB2"))
|
||||
{
|
||||
@@ -3282,7 +3131,6 @@ void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump)
|
||||
f.curpos = f.data;
|
||||
f.data[f.size] = 0;
|
||||
DEH_LoadDehackedFile(&f, wad);
|
||||
DEH_WriteUndoline(va("# uload for wad: %u, lump: %u", wad, lump), NULL, UNDO_DONE);
|
||||
Z_Free(f.data);
|
||||
}
|
||||
|
||||
@@ -9130,12 +8978,15 @@ int LUA_EnumLib(lua_State *L)
|
||||
char *str = NULL;
|
||||
int size = 0;
|
||||
|
||||
// Sound enum tables preallocated for sfx_freeslot0 elements because using NUMSFX may be too
|
||||
// much if number of skins increased a lot (because of skinsound freeslots)
|
||||
|
||||
/* SFX (SFX_) */
|
||||
lua_pushcfunction(L, lua_glib_new_enum);
|
||||
lua_createtable(L, 0, NUMSFX);
|
||||
lua_createtable(L, 0, sfx_freeslot0);
|
||||
for (int i = 0; i < NUMSFX; i++)
|
||||
{
|
||||
if (!S_sfx[i].name) continue;
|
||||
if (!S_sfx[i].name || !S_sfx[i].priority) continue;
|
||||
|
||||
if (lua_enumlib_sprintf_upper(&str, &size, "SFX_%s", S_sfx[i].name) == NULL)
|
||||
return luaL_error(L, "Ran out of memory.");
|
||||
@@ -9150,10 +9001,10 @@ int LUA_EnumLib(lua_State *L)
|
||||
|
||||
/* SFX (DS) */
|
||||
lua_pushcfunction(L, lua_glib_new_enum);
|
||||
lua_createtable(L, 0, NUMSFX);
|
||||
lua_createtable(L, 0, sfx_freeslot0);
|
||||
for (int i = 0; i < NUMSFX; i++)
|
||||
{
|
||||
if (!S_sfx[i].name) continue;
|
||||
if (!S_sfx[i].name || !S_sfx[i].priority) continue;
|
||||
|
||||
if (lua_enumlib_sprintf_upper(&str, &size, "DS%s", S_sfx[i].name) == NULL)
|
||||
return luaL_error(L, "Ran out of memory.");
|
||||
@@ -9188,10 +9039,10 @@ int LUA_EnumLib(lua_State *L)
|
||||
{
|
||||
/* SFX (sfx_) */
|
||||
lua_pushcfunction(L, lua_glib_new_enum);
|
||||
lua_createtable(L, 0, NUMSFX);
|
||||
lua_createtable(L, 0, sfx_freeslot0);
|
||||
for (int i = 0; i < NUMSFX; i++)
|
||||
{
|
||||
if (!S_sfx[i].name) continue;
|
||||
if (!S_sfx[i].name || !S_sfx[i].priority) continue;
|
||||
|
||||
lua_pushfstring(L, "sfx_%s", S_sfx[i].name);
|
||||
lua_pushinteger(L, i);
|
||||
@@ -9422,4 +9273,13 @@ void LUA_SetActionByName(void *state, const char *actiontocompare)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum actionnum LUA_GetActionNumByName(const char *actiontocompare)
|
||||
{
|
||||
size_t z;
|
||||
for (z = 0; actionpointers[z].name; z++)
|
||||
if (fasticmp(actiontocompare, actionpointers[z].name))
|
||||
return z;
|
||||
return z;
|
||||
}
|
||||
+1
-14
@@ -15,20 +15,6 @@
|
||||
|
||||
#include "m_fixed.h" // for get_number
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNDO_NONE = 0x00,
|
||||
UNDO_NEWLINE = 0x01,
|
||||
UNDO_SPACE = 0x02,
|
||||
UNDO_CUTLINE = 0x04,
|
||||
UNDO_HEADER = 0x07,
|
||||
UNDO_ENDTEXT = 0x08,
|
||||
UNDO_TODO = 0,
|
||||
UNDO_DONE = 0,
|
||||
} undotype_f;
|
||||
|
||||
#define DEH_WriteUndoline(a,b,c)
|
||||
|
||||
void DEH_LoadDehackedLump(lumpnum_t lumpnum);
|
||||
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump);
|
||||
|
||||
@@ -41,6 +27,7 @@ fixed_t get_number(const char *word);
|
||||
boolean LUA_SetLuaAction(void *state, const char *actiontocompare);
|
||||
const char *LUA_GetActionName(void *action);
|
||||
void LUA_SetActionByName(void *state, const char *actiontocompare);
|
||||
enum actionnum LUA_GetActionNumByName(const char *actiontocompare);
|
||||
|
||||
extern boolean deh_loaded;
|
||||
|
||||
|
||||
+32
-4
@@ -128,11 +128,11 @@ extern char logfilename[1024];
|
||||
#define VERSION 1 // Game version
|
||||
#define SUBVERSION 6 // more precise version number
|
||||
#ifndef USE_FBO_OGL
|
||||
#define VERSIONSTRING "Saturn v6.2 "
|
||||
#define VERSIONSTRINGW L"Saturn v6.2"
|
||||
#define VERSIONSTRING "Saturn v7"
|
||||
#define VERSIONSTRINGW L"Saturn v7"
|
||||
#else
|
||||
#define VERSIONSTRING "Saturn v6.2 - FBO "
|
||||
#define VERSIONSTRINGW L"Saturn v6.2 - FBO"
|
||||
#define VERSIONSTRING "Saturn v7 - FBO "
|
||||
#define VERSIONSTRINGW L"Saturn v7 - FBO"
|
||||
#endif
|
||||
// Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates!
|
||||
// And change CMakeLists.txt (not src/, but in root), for CMake users!
|
||||
@@ -211,6 +211,7 @@ extern char logfilename[1024];
|
||||
|
||||
#define MAXPLAYERS 16
|
||||
#define MAXSKINS 255
|
||||
#define MAXLOCALSKINS 32
|
||||
#define PLAYERSMASK (MAXPLAYERS-1)
|
||||
#define MAXPLAYERNAME 21
|
||||
|
||||
@@ -528,6 +529,10 @@ INT32 I_GetKey(void);
|
||||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef CLAMP
|
||||
#define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x)))
|
||||
#endif
|
||||
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
@@ -563,6 +568,29 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
// None of these that are disabled in the normal build are guaranteed to work perfectly
|
||||
// Compile them at your own risk!
|
||||
|
||||
#ifndef NONET
|
||||
//-- SATURN __
|
||||
/// Enable gamestate resynching between Saturn servers and clients
|
||||
/// Like SRB2 and RR does
|
||||
/// Still highly experimental
|
||||
#ifdef DOSATURNSYNCH
|
||||
#define SATURNSYNCH
|
||||
|
||||
/// Detect if a client is on Saturn in the clientconfig.
|
||||
/// To seperately allow them to join or block joining from vanilla clients.
|
||||
#ifdef DOSATURNJOIN
|
||||
#define SATURNJOIN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// Server detection for if a connecting client is on Saturn.
|
||||
/// For stuff like extra synching, etc.
|
||||
//#ifdef DOSATURNPAK
|
||||
//#define SATURNPAK
|
||||
//#endif
|
||||
//-- <( ̄︶ ̄)> __
|
||||
#endif
|
||||
|
||||
/// Undefine to use the new method of Gamma correction see colour cube in v_video.c
|
||||
#define BACKWARDSCOMPATCORRECTION
|
||||
|
||||
|
||||
@@ -510,6 +510,18 @@ extern mapthing_t *playerstarts[MAXPLAYERS]; // Cooperative
|
||||
extern mapthing_t *bluectfstarts[MAXPLAYERS]; // CTF
|
||||
extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
|
||||
|
||||
#define WAYPOINTSEQUENCESIZE 256
|
||||
#define NUMWAYPOINTSEQUENCES 256
|
||||
extern mobj_t *waypoints[NUMWAYPOINTSEQUENCES][WAYPOINTSEQUENCESIZE];
|
||||
extern UINT16 numwaypoints[NUMWAYPOINTSEQUENCES];
|
||||
|
||||
void P_AddWaypoint(UINT8 sequence, UINT8 id, mobj_t *waypoint);
|
||||
mobj_t *P_GetFirstWaypoint(UINT8 sequence);
|
||||
mobj_t *P_GetLastWaypoint(UINT8 sequence);
|
||||
mobj_t *P_GetPreviousWaypoint(mobj_t *current, boolean wrap);
|
||||
mobj_t *P_GetNextWaypoint(mobj_t *current, boolean wrap);
|
||||
mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo);
|
||||
|
||||
// =====================================
|
||||
// Internal parameters, used for engine.
|
||||
// =====================================
|
||||
|
||||
+9
-11
@@ -37,7 +37,6 @@
|
||||
#include <tchar.h>
|
||||
|
||||
#define SUFFIX "*"
|
||||
#define SLASH "\\"
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
|
||||
#ifndef INVALID_FILE_ATTRIBUTES
|
||||
@@ -135,7 +134,7 @@ opendir (const CHAR *szPath)
|
||||
/* Allocate enough space to store DIR structure and the complete
|
||||
* directory path given. */
|
||||
nd = (DIR *) malloc (sizeof (DIR) + (strlen(szFullPath) + strlen (SLASH) +
|
||||
strlen(SUFFIX) + 1) * sizeof (CHAR));
|
||||
strlen(PATHSEP) + 1) * sizeof (CHAR));
|
||||
|
||||
if (!nd)
|
||||
{
|
||||
@@ -149,10 +148,9 @@ opendir (const CHAR *szPath)
|
||||
|
||||
/* Add on a slash if the path does not end with one. */
|
||||
if (nd->dd_name[0] != '\0' &&
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != '\\')
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != PATHSEP[0])
|
||||
{
|
||||
strcat (nd->dd_name, SLASH);
|
||||
strcat (nd->dd_name, PATHSEP);
|
||||
}
|
||||
|
||||
/* Add on the search pattern */
|
||||
@@ -382,9 +380,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
return FS_NOTFOUND;
|
||||
}
|
||||
|
||||
if (searchpath[searchpathindex[depthleft]-2] != '/')
|
||||
if (searchpath[searchpathindex[depthleft]-2] != PATHSEP[0])
|
||||
{
|
||||
searchpath[searchpathindex[depthleft]-1] = '/';
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
}
|
||||
else
|
||||
@@ -392,7 +390,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
|
||||
while ((!found) && (depthleft < maxsearchdepth))
|
||||
{
|
||||
searchpath[searchpathindex[depthleft]]=0;
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
dent = readdir(dirhandle[depthleft]);
|
||||
|
||||
if (!dent)
|
||||
@@ -419,7 +417,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
if (S_ISDIR(fsstat.st_mode))
|
||||
dent->d_type = DT_DIR;
|
||||
else if (S_ISLNK(fsstat.st_mode))
|
||||
dent->d_type = DT_LNK;
|
||||
dent->d_type = DT_LNK;
|
||||
}
|
||||
|
||||
// Symlinks aren't always directory symlinks. Dunno if this would resolve recursive
|
||||
@@ -447,8 +445,8 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
depthleft++;
|
||||
}
|
||||
|
||||
searchpath[searchpathindex[depthleft]-1]='/';
|
||||
searchpath[searchpathindex[depthleft]]=0;
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
}
|
||||
else if (!strcasecmp(searchname, dent->d_name))
|
||||
{
|
||||
|
||||
+129
-81
@@ -50,6 +50,7 @@
|
||||
#include "b_bot.h"
|
||||
#include "m_cond.h" // condition sets
|
||||
#include "md5.h" // demo checksums
|
||||
#include "k_director.h" // SRB2kart
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "r_fps.h" // frame interpolation/uncapped
|
||||
|
||||
@@ -335,6 +336,11 @@ boolean precache = true; // if true, load all graphics at start
|
||||
|
||||
INT16 prevmap, nextmap;
|
||||
|
||||
// save if director is enabled
|
||||
// so demos can disable it by default and restore it after
|
||||
static int directorstate = 0;
|
||||
tic_t directortoggletimer = 0;
|
||||
|
||||
static CV_PossibleValue_t recordmultiplayerdemos_cons_t[] = {{0, "Disabled"}, {1, "Manual Save"}, {2, "Auto Save"}, {0, NULL}};
|
||||
consvar_t cv_recordmultiplayerdemos = {"netdemo_record", "Manual Save", CV_SAVE, recordmultiplayerdemos_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -345,6 +351,9 @@ consvar_t cv_netdemosyncquality = {"netdemo_syncquality", "1", CV_SAVE, netdemos
|
||||
static CV_PossibleValue_t maxdemosize_cons_t[] = {{10, "MIN"}, {100, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxdemosize = {"maxdemosize", "10", CV_SAVE, maxdemosize_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t demochangemap_cons_t[] = {{0, "Disabled"}, {1, "Diff Map"}, {2, "Always"}, {0, NULL}};
|
||||
consvar_t cv_demochangemap = {"netdemo_savemapchange", "Disabled", CV_SAVE, demochangemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static UINT8 *savebuffer;
|
||||
|
||||
// Analog Control
|
||||
@@ -417,8 +426,9 @@ consvar_t cv_songcredits = {"songcredits", "On", CV_SAVE, CV_OnOff, NULL, 0, NUL
|
||||
consvar_t cv_showfreeplay = { "showfreeplay", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// We can disable special tunes!
|
||||
consvar_t cv_growmusic = {"growmusic", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_supermusic = {"supermusic", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t powermusic_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "SFX"}, {0, NULL}};
|
||||
consvar_t cv_growmusic = {"growmusic", "On", CV_SAVE, powermusic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_supermusic = {"supermusic", "On", CV_SAVE, powermusic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
/*consvar_t cv_crosshair = {"crosshair", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_crosshair2 = {"crosshair2", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -1187,7 +1197,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||
// why build a ticcmd if we're paused?
|
||||
// Or, for that matter, if we're being reborn.
|
||||
// Kart, don't build a ticcmd if someone is resynching or the server is stopped too so we don't fly off course in bad conditions
|
||||
if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN) || hu_resynching)
|
||||
if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN) || hu_resynching
|
||||
#ifdef SATURNSYNCH
|
||||
|| hu_redownloadinggamestate
|
||||
#endif
|
||||
)
|
||||
{
|
||||
cmd->angleturn = (INT16)(lang >> 16);
|
||||
cmd->aiming = G_ClipAimingPitch(&laim);
|
||||
@@ -1637,7 +1651,7 @@ void G_DoLoadLevel(boolean resetplayer)
|
||||
}
|
||||
|
||||
// Setup the level.
|
||||
if (!P_SetupLevel(false))
|
||||
if (!P_SetupLevel(false,false))
|
||||
{
|
||||
// fail so reset game stuff
|
||||
Command_ExitGame_f();
|
||||
@@ -1934,6 +1948,12 @@ boolean G_Responder(event_t *ev)
|
||||
COM_ImmedExecute("changeteam4 spectator");
|
||||
}
|
||||
}
|
||||
if (ev->data1 == gamecontrol[gc_director][0]
|
||||
|| ev->data1 == gamecontrol[gc_director][1])
|
||||
{
|
||||
K_ToggleDirector();
|
||||
directortoggletimer = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -2108,7 +2128,7 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
|
||||
olddisplayplayer = (*displayplayerp);
|
||||
|
||||
/* Check if anyone is available to view. */
|
||||
if (( playernum = G_FindView(playernum, viewnum, onlyactive, playernum < olddisplayplayer) ) == -1)
|
||||
if ((playernum = G_FindView(playernum, viewnum, onlyactive, playernum < olddisplayplayer)) == -1)
|
||||
return;
|
||||
|
||||
/* Focus our target view first so that we don't take its player. */
|
||||
@@ -2118,6 +2138,8 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
|
||||
camerap = &camera[viewnum-1];
|
||||
P_ResetCamera(&players[(*displayplayerp)], camerap);
|
||||
|
||||
// Make sure the viewport doesn't interpolate at all into
|
||||
// its new position -- just snap instantly into place.
|
||||
R_ResetViewInterpolation(viewnum);
|
||||
}
|
||||
|
||||
@@ -2131,6 +2153,11 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
|
||||
(*displayplayerp) = G_FindView(0, viewd, onlyactive, false);
|
||||
|
||||
P_ResetCamera(&players[(*displayplayerp)], camerap);
|
||||
|
||||
|
||||
// Make sure the viewport doesn't interpolate at all into
|
||||
// its new position -- just snap instantly into place.
|
||||
R_ResetViewInterpolation(viewd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2244,13 +2271,14 @@ void G_Ticker(boolean run)
|
||||
buf = gametic % TICQUEUE;
|
||||
|
||||
if (!demo.playback)
|
||||
// read/write demo and check turbo cheat
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
cmd = &players[i].cmd;
|
||||
|
||||
if (playeringame[i])
|
||||
for (i = 0; i < MAXPLAYERS; i++) // read/write demo and check turbo cheat
|
||||
{
|
||||
cmd = &players[i].cmd;
|
||||
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
//@TODO all this throwdir stuff shouldn't be here! But it stays for now to maintain 1.0.4 compat...
|
||||
// Remove for 1.1!
|
||||
|
||||
@@ -2485,6 +2513,10 @@ void G_PlayerReborn(INT32 player)
|
||||
boolean fade;
|
||||
boolean playing;
|
||||
|
||||
tic_t laptime[LAP__MAX];
|
||||
|
||||
INT32 i;
|
||||
|
||||
score = players[player].score;
|
||||
marescore = players[player].marescore;
|
||||
lives = players[player].lives;
|
||||
@@ -2526,6 +2558,21 @@ void G_PlayerReborn(INT32 player)
|
||||
bot = players[player].bot;
|
||||
pity = players[player].pity;
|
||||
|
||||
if (leveltime <= starttime) // man i really hope this crap works kek but need to reset this somehow at mapstart
|
||||
{
|
||||
for (i = 0; i < LAP__MAX; i++)
|
||||
{
|
||||
laptime[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < LAP__MAX; i++)
|
||||
{
|
||||
laptime[i] = players[player].laptime[i];
|
||||
}
|
||||
}
|
||||
|
||||
// SRB2kart
|
||||
if (leveltime <= starttime || spectator == true)
|
||||
{
|
||||
@@ -2617,6 +2664,11 @@ void G_PlayerReborn(INT32 player)
|
||||
p->laps = laps;
|
||||
p->totalring = totalring;
|
||||
|
||||
for (i = 0; i < LAP__MAX; i++)
|
||||
{
|
||||
p->laptime[i] = laptime[i];
|
||||
}
|
||||
|
||||
p->mare = mare;
|
||||
if (bot)
|
||||
p->bot = 1; // reset to AI-controlled
|
||||
@@ -2666,8 +2718,7 @@ void G_PlayerReborn(INT32 player)
|
||||
}
|
||||
|
||||
/* I'm putting this here because lol */
|
||||
|
||||
fade = (cv_fading.value && cv_birdmusic.value && P_IsLocalPlayer(p));
|
||||
fade = (cv_birdmusic.value && cv_fading.value && P_IsLocalPlayer(p));
|
||||
|
||||
if (fade)
|
||||
{
|
||||
@@ -2677,7 +2728,7 @@ void G_PlayerReborn(INT32 player)
|
||||
Fade it in with the same call to avoid
|
||||
max volume for a few milliseconds (?).
|
||||
*/
|
||||
if (! playing)
|
||||
if (!playing)
|
||||
S_SetRestoreMusicFadeInCvar(&cv_respawnfademusicback);
|
||||
}
|
||||
|
||||
@@ -3033,12 +3084,6 @@ void G_DoReborn(INT32 playernum)
|
||||
player_t *player = &players[playernum];
|
||||
boolean starpost = false;
|
||||
|
||||
/*if (modeattacking) // Not needed for SRB2Kart.
|
||||
{
|
||||
M_EndModeAttackRun();
|
||||
return;
|
||||
}*/
|
||||
|
||||
// Make sure objectplace is OFF when you first start the level!
|
||||
OP_ResetObjectplace();
|
||||
|
||||
@@ -3058,68 +3103,6 @@ void G_DoReborn(INT32 playernum)
|
||||
if (oldmo)
|
||||
G_ChangePlayerReferences(oldmo, players[playernum].mo);
|
||||
}
|
||||
/*else if (countdowntimeup || (!multiplayer && !modeattacking))
|
||||
{
|
||||
// reload the level from scratch
|
||||
if (countdowntimeup)
|
||||
{
|
||||
player->starpostangle = 0;
|
||||
player->starposttime = 0;
|
||||
player->starpostx = 0;
|
||||
player->starposty = 0;
|
||||
player->starpostz = 0;
|
||||
player->starpostnum = 0;
|
||||
}
|
||||
if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD))
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
player->playerstate = PST_REBORN;
|
||||
|
||||
P_LoadThingsOnly();
|
||||
|
||||
// Do a wipe
|
||||
wipegamestate = -1;
|
||||
|
||||
if (player->starpostnum) // SRB2kart
|
||||
starpost = true;
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (camera[i].chase)
|
||||
P_ResetCamera(&players[displayplayers[i]], &camera[i]);
|
||||
}
|
||||
|
||||
// clear cmd building stuff
|
||||
memset(gamekeydown, 0, sizeof (gamekeydown));
|
||||
for (i = 0;i < JOYAXISSET; i++)
|
||||
{
|
||||
joyxmove[i] = joyymove[i] = 0;
|
||||
joy2xmove[i] = joy2ymove[i] = 0;
|
||||
joy3xmove[i] = joy3ymove[i] = 0;
|
||||
joy4xmove[i] = joy4ymove[i] = 0;
|
||||
}
|
||||
mousex = mousey = 0;
|
||||
mouse2x = mouse2y = 0;
|
||||
|
||||
// clear hud messages remains (usually from game startup)
|
||||
CON_ClearHUD();
|
||||
|
||||
// Starpost support
|
||||
G_SpawnPlayer(playernum, starpost);
|
||||
|
||||
if (botingame)
|
||||
{ // Bots respawn next to their master.
|
||||
players[displayplayers[1]].playerstate = PST_REBORN;
|
||||
G_SpawnPlayer(displayplayers[1], false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LUAh_MapChange(gamemap);
|
||||
G_DoLoadLevel(true);
|
||||
}
|
||||
}*/
|
||||
else
|
||||
{
|
||||
// respawn at the start
|
||||
@@ -4446,6 +4429,11 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
|
||||
players[i].starpostx = players[i].starposty = players[i].starpostz = 0;
|
||||
players[i].lives = 1; // SRB2Kart
|
||||
|
||||
// This should be cleared in P_SpawnPlayer but address sanitizer says "use-after-free"
|
||||
// when reloading map sometimes
|
||||
players[i].awayviewtics = 0;
|
||||
players[i].awayviewmobj = NULL;
|
||||
|
||||
// The latter two should clear by themselves, but just in case
|
||||
players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS);
|
||||
|
||||
@@ -7161,6 +7149,57 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
Z_Free(infobuffer);
|
||||
}
|
||||
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo)
|
||||
{
|
||||
UINT8 infobuffer[96], *info_p;
|
||||
UINT16 pdemoversion;
|
||||
size_t count;
|
||||
|
||||
FILE *handle = fopen(pdemo->filepath, "rb");
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), pdemo->filepath);
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
count = fread(infobuffer, 1, 96, handle);
|
||||
fclose(handle);
|
||||
info_p = infobuffer;
|
||||
|
||||
// First check isn't too accurate technically, but well, valid replays should be larger than that anyway
|
||||
if (count < 96 || memcmp(info_p, DEMOHEADER, 12))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemo->filepath);
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
info_p += 12; // DEMOHEADER
|
||||
|
||||
READUINT8(info_p);
|
||||
READUINT8(info_p);
|
||||
pdemoversion = READUINT16(info_p);
|
||||
|
||||
switch(pdemoversion)
|
||||
{
|
||||
case DEMOVERSION: // latest always supported
|
||||
// demo title
|
||||
M_Memcpy(pdemo->title, info_p, 64);
|
||||
break;
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
sprintf(pdemo->title, "Legacy Replay");
|
||||
break;
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// G_PlayDemo
|
||||
//
|
||||
@@ -7690,6 +7729,9 @@ post_compat:
|
||||
players[i].kartweight = kartweight[i];
|
||||
}
|
||||
|
||||
directorstate = cv_director.value;
|
||||
CV_SetValue(&cv_director, 0);
|
||||
|
||||
demo.deferstart = true;
|
||||
}
|
||||
#undef SKIPERRORS
|
||||
@@ -8256,6 +8298,11 @@ void G_StopDemo(void)
|
||||
{
|
||||
Z_Free(demobuffer);
|
||||
demobuffer = NULL;
|
||||
if (demo.playback)
|
||||
{
|
||||
CV_SetValue(&cv_director, directorstate);
|
||||
directorstate = 0;
|
||||
}
|
||||
demo.playback = false;
|
||||
if (demo.title)
|
||||
modeattacking = false;
|
||||
@@ -8493,6 +8540,7 @@ boolean G_DemoTitleResponder(event_t *ev)
|
||||
void G_SetGamestate(gamestate_t newstate)
|
||||
{
|
||||
gamestate = newstate;
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
DRPC_UpdatePresence();
|
||||
#endif
|
||||
|
||||
+4
-1
@@ -39,7 +39,7 @@ extern UINT8 *demo_p;
|
||||
// ======================================
|
||||
|
||||
// demoplaying back and demo recording
|
||||
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality, cv_maxdemosize;
|
||||
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality, cv_maxdemosize, cv_demochangemap;
|
||||
|
||||
// Publicly-accessible demo vars
|
||||
struct demovars_s {
|
||||
@@ -218,6 +218,8 @@ extern angle_t localangle[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but signed
|
||||
extern boolean camspin[MAXSPLITSCREENPLAYERS]; // SRB2Kart
|
||||
|
||||
extern tic_t directortoggletimer;
|
||||
|
||||
//
|
||||
// GAME
|
||||
//
|
||||
@@ -265,6 +267,7 @@ void G_DeferedInitNew(boolean pencoremode, const char *mapname, INT32 pickedchar
|
||||
void G_DoLoadLevel(boolean resetplayer);
|
||||
|
||||
void G_LoadDemoInfo(menudemo_t *pdemo);
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo); // For use in replay search feature
|
||||
void G_DeferedPlayDemo(const char *demo);
|
||||
|
||||
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
|
||||
|
||||
+216
@@ -14,11 +14,17 @@
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "g_input.h"
|
||||
#include "g_game.h"
|
||||
#include "keys.h"
|
||||
#include "hu_stuff.h" // need HUFONT start & end
|
||||
#include "d_net.h"
|
||||
#include "console.h"
|
||||
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
#include "r_draw.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#define MAXMOUSESENSITIVITY 100 // sensitivity steps
|
||||
|
||||
static CV_PossibleValue_t mousesens_cons_t[] = {{1, "MIN"}, {MAXMOUSESENSITIVITY, "MAX"}, {0, NULL}};
|
||||
@@ -33,6 +39,89 @@ consvar_t cv_mouseysens2 = {"mouseysens2", "20", CV_SAVE, mousesens_cons_t, NULL
|
||||
consvar_t cv_controlperkey = {"controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_turnsmooth = {"turnsmoothing", "Slow", CV_SAVE, turnsmooth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static void G_ResetPlayerDeviceRumble(INT32 player);
|
||||
static void rumble_off_handle(void);
|
||||
static void rumble_off_handle2(void);
|
||||
static void rumble_off_handle3(void);
|
||||
static void rumble_off_handle4(void);
|
||||
|
||||
static void G_ResetPlayerGamepadIndicatorColor(INT32 player);
|
||||
static void led_off_handle(void);
|
||||
static void led_off_handle2(void);
|
||||
static void led_off_handle3(void);
|
||||
static void led_off_handle4(void);
|
||||
|
||||
consvar_t cv_rumble[MAXSPLITSCREENPLAYERS] = {
|
||||
{"rumble", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, rumble_off_handle, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"rumble2", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, rumble_off_handle2, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"rumble3", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, rumble_off_handle3, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"rumble4", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, rumble_off_handle4, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS] = {
|
||||
{"gamepadled", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"gamepadled2", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle2, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"gamepadled3", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle3, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"gamepadled4", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle4, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
consvar_t cv_ledpowerup[MAXSPLITSCREENPLAYERS] = {
|
||||
{"ledpowerup", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"ledpowerup2", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle2, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"ledpowerup3", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle3, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"ledpowerup4", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, led_off_handle4, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
static void rumble_off_handle(void)
|
||||
{
|
||||
if (cv_rumble[0].value == 0)
|
||||
G_ResetPlayerDeviceRumble(0);
|
||||
}
|
||||
|
||||
|
||||
static void rumble_off_handle2(void)
|
||||
{
|
||||
if (cv_rumble[1].value == 0)
|
||||
G_ResetPlayerDeviceRumble(1);
|
||||
}
|
||||
|
||||
|
||||
static void rumble_off_handle3(void)
|
||||
{
|
||||
if (cv_rumble[2].value == 0)
|
||||
G_ResetPlayerDeviceRumble(2);
|
||||
}
|
||||
|
||||
|
||||
static void rumble_off_handle4(void)
|
||||
{
|
||||
if (cv_rumble[3].value == 0)
|
||||
G_ResetPlayerDeviceRumble(3);
|
||||
}
|
||||
|
||||
static void led_off_handle(void)
|
||||
{
|
||||
G_ResetPlayerGamepadIndicatorColor(0);
|
||||
}
|
||||
|
||||
|
||||
static void led_off_handle2(void)
|
||||
{
|
||||
G_ResetPlayerGamepadIndicatorColor(1);
|
||||
}
|
||||
|
||||
|
||||
static void led_off_handle3(void)
|
||||
{
|
||||
G_ResetPlayerGamepadIndicatorColor(2);
|
||||
}
|
||||
|
||||
|
||||
static void led_off_handle4(void)
|
||||
{
|
||||
G_ResetPlayerGamepadIndicatorColor(3);
|
||||
}
|
||||
|
||||
INT32 mousex, mousey;
|
||||
INT32 mlooky; // like mousey but with a custom sensitivity for mlook
|
||||
|
||||
@@ -812,10 +901,137 @@ static const char *gamecontrolname[num_gamecontrols] =
|
||||
"custom1",
|
||||
"custom2",
|
||||
"custom3",
|
||||
"director",
|
||||
};
|
||||
|
||||
#define NUMKEYNAMES (sizeof (keynames)/sizeof (keyname_t))
|
||||
|
||||
#include "k_kart.h"
|
||||
|
||||
INT32 G_GetDeviceForPlayer(INT32 player)
|
||||
{
|
||||
switch (player)
|
||||
{
|
||||
case 0:
|
||||
return cv_usejoystick.value;
|
||||
break;
|
||||
case 1:
|
||||
return cv_usejoystick2.value;
|
||||
break;
|
||||
case 2:
|
||||
return cv_usejoystick3.value;
|
||||
break;
|
||||
case 3:
|
||||
return cv_usejoystick4.value;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline UINT16 G_GetSkinColor(INT32 player)
|
||||
{
|
||||
// make rgb rainbow vomit when invul or flash blue when grow
|
||||
if (cv_ledpowerup[player].value && gamestate == GS_LEVEL && players[displayplayers[player]].mo && (players[displayplayers[player]].kartstuff[k_invincibilitytimer] || players[displayplayers[player]].powers[pw_invulnerability] || players[displayplayers[player]].kartstuff[k_growshrinktimer]))
|
||||
return players[displayplayers[player]].mo->color;
|
||||
|
||||
// take actual player skincolour when ingame
|
||||
if (gamestate == GS_LEVEL && players[displayplayers[player]].skincolor)
|
||||
return players[displayplayers[player]].skincolor;
|
||||
|
||||
// otherwise just fallback to whatever the cvar is
|
||||
switch (player)
|
||||
{
|
||||
case 0:
|
||||
return cv_playercolor.value;
|
||||
break;
|
||||
case 1:
|
||||
return cv_playercolor2.value;
|
||||
break;
|
||||
case 2:
|
||||
return cv_playercolor3.value;
|
||||
break;
|
||||
case 3:
|
||||
return cv_playercolor4.value;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void G_SetPlayerGamepadIndicatorColor(INT32 player, UINT16 color)
|
||||
{
|
||||
INT32 device;
|
||||
UINT16 skincolor;
|
||||
byteColor_t byte_color;
|
||||
|
||||
I_Assert(player >= 0 && player < MAXSPLITSCREENPLAYERS);
|
||||
|
||||
if (cv_gamepadled[player].value == 0)
|
||||
return;
|
||||
|
||||
device = G_GetDeviceForPlayer(player);
|
||||
|
||||
if (device <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
skincolor = color ? color : G_GetSkinColor(player);
|
||||
byte_color = V_GetColor(colortranslations[skincolor][8]).s;
|
||||
|
||||
I_SetGamepadIndicatorColor(device, byte_color.red, byte_color.green, byte_color.blue);
|
||||
}
|
||||
|
||||
static void G_ResetPlayerGamepadIndicatorColor(INT32 player)
|
||||
{
|
||||
if (cv_gamepadled[player].value == 0)
|
||||
{
|
||||
INT32 device = G_GetDeviceForPlayer(player);
|
||||
if (device <= 0)
|
||||
return;
|
||||
|
||||
I_SetGamepadIndicatorColor(device, 0, 0, 255);
|
||||
}
|
||||
else
|
||||
G_SetPlayerGamepadIndicatorColor(player, 0);
|
||||
}
|
||||
|
||||
static void G_ResetPlayerDeviceRumble(INT32 player)
|
||||
{
|
||||
INT32 device_id;
|
||||
|
||||
device_id = G_GetDeviceForPlayer(player);
|
||||
|
||||
if (device_id < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
I_GamepadRumble(device_id, 0, 0, 0);
|
||||
}
|
||||
|
||||
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration)
|
||||
{
|
||||
INT32 device_id;
|
||||
|
||||
if (cv_rumble[player].value == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
device_id = G_GetDeviceForPlayer(player);
|
||||
|
||||
if (device_id < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
I_GamepadRumble(device_id, low_strength, high_strength, duration);
|
||||
}
|
||||
|
||||
//
|
||||
// Detach any keys associated to the given game control
|
||||
// - pass the pointer to the gamecontrol table for the player being edited
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define __G_INPUT__
|
||||
|
||||
#include "d_event.h"
|
||||
#include "doomstat.h"
|
||||
#include "keys.h"
|
||||
#include "command.h"
|
||||
|
||||
@@ -98,6 +99,7 @@ typedef enum
|
||||
gc_custom1, // Lua scriptable
|
||||
gc_custom2, // Lua scriptable
|
||||
gc_custom3, // Lua scriptable
|
||||
gc_director,
|
||||
num_gamecontrols
|
||||
} gamecontrols_e;
|
||||
|
||||
@@ -105,6 +107,9 @@ typedef enum
|
||||
extern consvar_t cv_mousesens, cv_mouseysens;
|
||||
extern consvar_t cv_mousesens2, cv_mouseysens2;
|
||||
extern consvar_t cv_controlperkey, cv_turnsmooth;
|
||||
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_ledpowerup[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern INT32 mousex, mousey;
|
||||
extern INT32 mlooky; //mousey with mlookSensitivity
|
||||
@@ -129,6 +134,11 @@ extern INT32 gamecontrol4[num_gamecontrols][2];
|
||||
// peace to my little coder fingers!
|
||||
// check a gamecontrol being active or not
|
||||
|
||||
UINT16 G_GetSkinColor(INT32 player);
|
||||
INT32 G_GetDeviceForPlayer(INT32 player);
|
||||
void G_SetPlayerGamepadIndicatorColor(INT32 player, UINT16 color);
|
||||
void G_PlayerDeviceRumble(INT32 player, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
|
||||
|
||||
// remaps the input event to a game control.
|
||||
void G_MapEventsToControls(event_t *ev);
|
||||
|
||||
|
||||
+57
-57
@@ -35,7 +35,7 @@ int finalVertexArrayAllocSize = 65536;
|
||||
|
||||
PolygonArrayEntry* polygonArray = NULL;// contains the polygon data from DrawPolygon, waiting to be processed
|
||||
int polygonArraySize = 0;
|
||||
UINT32* polygonIndexArray = NULL;// contains sorting pointers for polygonArray
|
||||
PolygonArrayEntry **polygonArraySorted = NULL;// contains sorted pointers to polygonArray
|
||||
int polygonArrayAllocSize = 65536;
|
||||
|
||||
FOutVector* unsortedVertexArray = NULL;// contains unsorted vertices and texture coordinates from DrawPolygon
|
||||
@@ -47,7 +47,9 @@ int unsortedVertexArrayAllocSize = 65536;
|
||||
void HWR_StartBatching(void)
|
||||
{
|
||||
if (currently_batching)
|
||||
{
|
||||
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
|
||||
}
|
||||
|
||||
// init arrays if that has not been done yet
|
||||
if (!finalVertexArray)
|
||||
@@ -55,7 +57,7 @@ void HWR_StartBatching(void)
|
||||
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
|
||||
finalVertexIndexArray = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32));
|
||||
polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry));
|
||||
polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32));
|
||||
polygonArraySorted = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry *));
|
||||
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
|
||||
}
|
||||
|
||||
@@ -96,8 +98,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
||||
free(polygonArray);
|
||||
polygonArray = new_array;
|
||||
// also need to redo the index array, dont need to copy it though
|
||||
free(polygonIndexArray);
|
||||
polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32));
|
||||
free(polygonArraySorted);
|
||||
polygonArraySorted = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry *));
|
||||
}
|
||||
|
||||
while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize)
|
||||
@@ -134,10 +136,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
||||
|
||||
static int comparePolygons(const void *p1, const void *p2)
|
||||
{
|
||||
unsigned int index1 = *(const unsigned int*)p1;
|
||||
unsigned int index2 = *(const unsigned int*)p2;
|
||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
||||
PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
|
||||
PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
UINT32 downloaded1 = 0;
|
||||
@@ -155,7 +155,7 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (shader1 == -1 && shader2 == -1)
|
||||
return index1 - index2;
|
||||
return poly1 - poly2;
|
||||
|
||||
if (poly1->texture)
|
||||
downloaded1 = poly1->texture->downloaded; // there should be a opengl texture name here, usable for comparisons
|
||||
@@ -184,10 +184,8 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||
|
||||
static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
||||
{
|
||||
unsigned int index1 = *(const unsigned int*)p1;
|
||||
unsigned int index2 = *(const unsigned int*)p2;
|
||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
||||
PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
|
||||
PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
|
||||
@@ -205,7 +203,7 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
||||
downloaded2 = texture2->downloaded;
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (!texture1 && !texture2)
|
||||
return index1 - index2;
|
||||
return poly1 - poly2;
|
||||
diff64 = downloaded1 - downloaded2;
|
||||
if (diff64 != 0) return diff64;
|
||||
|
||||
@@ -225,7 +223,7 @@ void HWR_RenderBatches(void)
|
||||
int finalVertexWritePos = 0;// position in finalVertexArray
|
||||
int finalIndexWritePos = 0;// position in finalVertexIndexArray
|
||||
|
||||
int polygonReadPos = 0;// position in polygonIndexArray
|
||||
int polygonReadPos = 0;// position in polygonArraySorted
|
||||
|
||||
int currentShader;
|
||||
int nextShader = 0;
|
||||
@@ -258,18 +256,18 @@ void HWR_RenderBatches(void)
|
||||
ps_hw_numcalls.value.i = ps_hw_numverts.value.i = 0;
|
||||
ps_hw_numshaders.value.i = ps_hw_numtextures.value.i
|
||||
= ps_hw_numpolyflags.value.i = ps_hw_numcolors.value.i = 1;
|
||||
// init polygonIndexArray
|
||||
// init polygonArraySorted
|
||||
for (i = 0; i < polygonArraySize; i++)
|
||||
{
|
||||
polygonIndexArray[i] = i;
|
||||
polygonArraySorted[i] = &polygonArray[i];
|
||||
}
|
||||
|
||||
// sort polygons
|
||||
PS_START_TIMING(ps_hw_batchsorttime);
|
||||
if (cv_grshaders.value && gr_shadersavailable)
|
||||
qs22j(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
|
||||
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygons);
|
||||
else
|
||||
qs22j(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders);
|
||||
qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygonsNoShaders);
|
||||
PS_STOP_TIMING(ps_hw_batchsorttime);
|
||||
// sort order
|
||||
// 1. shader
|
||||
@@ -280,10 +278,10 @@ void HWR_RenderBatches(void)
|
||||
|
||||
PS_START_TIMING(ps_hw_batchdrawtime);
|
||||
|
||||
currentShader = polygonArray[polygonIndexArray[0]].shader;
|
||||
currentTexture = polygonArray[polygonIndexArray[0]].texture;
|
||||
currentPolyFlags = polygonArray[polygonIndexArray[0]].polyFlags;
|
||||
currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf;
|
||||
currentShader = polygonArraySorted[0]->shader;
|
||||
currentTexture = polygonArraySorted[0]->texture;
|
||||
currentPolyFlags = polygonArraySorted[0]->polyFlags;
|
||||
currentSurfaceInfo = polygonArraySorted[0]->surf;
|
||||
// For now, will sort and track the colors. Vertex attributes could be used instead of uniforms
|
||||
// and a color array could replace the color calls.
|
||||
|
||||
@@ -322,8 +320,8 @@ void HWR_RenderBatches(void)
|
||||
// reset write pos
|
||||
// repeat loop
|
||||
|
||||
int index = polygonIndexArray[polygonReadPos++];
|
||||
int numVerts = polygonArray[index].numVerts;
|
||||
PolygonArrayEntry *entry = polygonArraySorted[polygonReadPos++];
|
||||
int numVerts = entry->numVerts;
|
||||
// before writing, check if there is enough room
|
||||
// using 'while' instead of 'if' here makes sure that there will *always* be enough room.
|
||||
// probably never will this loop run more than once though
|
||||
@@ -344,7 +342,7 @@ void HWR_RenderBatches(void)
|
||||
finalVertexIndexArray = new_index_array;
|
||||
}
|
||||
// write the vertices of the polygon
|
||||
memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[polygonArray[index].vertsIndex],
|
||||
memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[entry->vertsIndex],
|
||||
numVerts * sizeof(FOutVector));
|
||||
// write the indexes, pointing to the fan vertexes but in triangles format
|
||||
firstIndex = finalVertexWritePos;
|
||||
@@ -364,11 +362,11 @@ void HWR_RenderBatches(void)
|
||||
else
|
||||
{
|
||||
// check if a state change is required, set the change bools and next vars
|
||||
int nextIndex = polygonIndexArray[polygonReadPos];
|
||||
nextShader = polygonArray[nextIndex].shader;
|
||||
nextTexture = polygonArray[nextIndex].texture;
|
||||
nextPolyFlags = polygonArray[nextIndex].polyFlags;
|
||||
nextSurfaceInfo = polygonArray[nextIndex].surf;
|
||||
PolygonArrayEntry *nextEntry = polygonArraySorted[polygonReadPos];
|
||||
nextShader = nextEntry->shader;
|
||||
nextTexture = nextEntry->texture;
|
||||
nextPolyFlags = nextEntry->polyFlags;
|
||||
nextSurfaceInfo = nextEntry->surf;
|
||||
if (nextPolyFlags & PF_NoTexture)
|
||||
nextTexture = 0;
|
||||
if (currentShader != nextShader && cv_grshaders.value && gr_shadersavailable)
|
||||
@@ -426,38 +424,40 @@ void HWR_RenderBatches(void)
|
||||
if (stopFlag) break;
|
||||
|
||||
// change state according to change bools and next vars, update current vars and reset bools
|
||||
if (changeShader)
|
||||
if (changeState)
|
||||
{
|
||||
HWD.pfnSetShader(nextShader);
|
||||
currentShader = nextShader;
|
||||
changeShader = false;
|
||||
if (changeShader)
|
||||
{
|
||||
HWD.pfnSetShader(nextShader);
|
||||
currentShader = nextShader;
|
||||
changeShader = false;
|
||||
|
||||
ps_hw_numshaders.value.i++;
|
||||
}
|
||||
if (changeTexture)
|
||||
{
|
||||
// texture should be already ready for use from calls to SetTexture during batch collection
|
||||
HWD.pfnSetTexture(nextTexture);
|
||||
currentTexture = nextTexture;
|
||||
changeTexture = false;
|
||||
ps_hw_numshaders.value.i++;
|
||||
}
|
||||
if (changeTexture)
|
||||
{
|
||||
// texture should be already ready for use from calls to SetTexture during batch collection
|
||||
HWD.pfnSetTexture(nextTexture);
|
||||
currentTexture = nextTexture;
|
||||
changeTexture = false;
|
||||
|
||||
ps_hw_numtextures.value.i++;
|
||||
}
|
||||
if (changePolyFlags)
|
||||
{
|
||||
currentPolyFlags = nextPolyFlags;
|
||||
changePolyFlags = false;
|
||||
ps_hw_numtextures.value.i++;
|
||||
}
|
||||
if (changePolyFlags)
|
||||
{
|
||||
currentPolyFlags = nextPolyFlags;
|
||||
changePolyFlags = false;
|
||||
|
||||
ps_hw_numpolyflags.value.i++;
|
||||
}
|
||||
if (changeSurfaceInfo)
|
||||
{
|
||||
currentSurfaceInfo = nextSurfaceInfo;
|
||||
changeSurfaceInfo = false;
|
||||
ps_hw_numpolyflags.value.i++;
|
||||
}
|
||||
if (changeSurfaceInfo)
|
||||
{
|
||||
currentSurfaceInfo = nextSurfaceInfo;
|
||||
changeSurfaceInfo = false;
|
||||
|
||||
ps_hw_numcolors.value.i++;
|
||||
ps_hw_numcolors.value.i++;
|
||||
}
|
||||
}
|
||||
// and that should be it?
|
||||
}
|
||||
// reset the arrays (set sizes to 0)
|
||||
polygonArraySize = 0;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "hw_data.h"
|
||||
#include "hw_drv.h"
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused
|
||||
unsigned int vertsIndex;// location of verts in unsortedVertexArray
|
||||
|
||||
+18
-8
@@ -667,9 +667,15 @@ static boolean PointInSeg(polyvertex_t *a,polyvertex_t *v1,polyvertex_t *v2)
|
||||
// v1 = origine
|
||||
ax= v2->x-v1->x;
|
||||
ay= v2->y-v1->y;
|
||||
norm = (float)hypot(ax, ay);
|
||||
ax /= norm;
|
||||
ay /= norm;
|
||||
norm = hypotf(ax, ay);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
if (norm != 0) // yes, this can be exactly 0
|
||||
#pragma GCC diagnostic pop
|
||||
{
|
||||
ax /= norm;
|
||||
ay /= norm;
|
||||
}
|
||||
bx = a->x-v1->x;
|
||||
by = a->y-v1->y;
|
||||
//d = a.b
|
||||
@@ -772,9 +778,11 @@ static INT32 SolveTProblem(void)
|
||||
for (l = 0; l < addsubsector; l++)
|
||||
{
|
||||
p = extrasubsectors[l].planepoly;
|
||||
if (p)
|
||||
for (i = 0; i < p->numpts; i++)
|
||||
SearchSegInBSP((INT32)numnodes-1, &p->pts[i], p);
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < p->numpts; i++)
|
||||
SearchSegInBSP((INT32)numnodes-1, &p->pts[i], p);
|
||||
}
|
||||
//CONS_Debug(DBG_RENDER, "numsplitpoly %d\n", numsplitpoly);
|
||||
return numsplitpoly;
|
||||
@@ -802,8 +810,10 @@ static void AdjustSegs(void)
|
||||
count = subsectors[i].numlines;
|
||||
lseg = &segs[subsectors[i].firstline];
|
||||
p = extrasubsectors[i].planepoly;
|
||||
//if (!p)
|
||||
//continue;
|
||||
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
for (; count--; lseg++)
|
||||
{
|
||||
float distv1,distv2,tmp;
|
||||
|
||||
+19
-14
@@ -379,18 +379,19 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe
|
||||
blockwidth, blockheight,
|
||||
texture, patch,
|
||||
realpatch);
|
||||
Z_Unlock(realpatch);
|
||||
Z_ChangeTag(realpatch, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
|
||||
if (format2bpp(grtex->mipmap.format)==4)
|
||||
{
|
||||
for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp
|
||||
{
|
||||
if (block[i] == 0)
|
||||
{
|
||||
grtex->mipmap.flags |= TF_TRANSPARENT;
|
||||
break;
|
||||
}
|
||||
if (block[i] != 0)
|
||||
continue;
|
||||
|
||||
grtex->mipmap.flags |= TF_TRANSPARENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +573,6 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore)
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
if (!grtex->mipmap.downloaded)
|
||||
HWD.pfnSetTexture(&grtex->mipmap);
|
||||
|
||||
HWR_SetCurrentTexture(&grtex->mipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
@@ -629,8 +629,12 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
|
||||
#ifdef GLENCORE
|
||||
flat = grMipmap->data;
|
||||
for (steppy = 0; steppy < size; steppy++)
|
||||
if (flat[steppy] != HWR_PATCHES_CHROMAKEY_COLORINDEX)
|
||||
flat[steppy] = grMipmap->colormap[flat[steppy]];
|
||||
{
|
||||
if (flat[steppy] == HWR_PATCHES_CHROMAKEY_COLORINDEX)
|
||||
continue;
|
||||
|
||||
flat[steppy] = grMipmap->colormap[flat[steppy]];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -743,11 +747,12 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap)
|
||||
for (grmip = gpatch->mipmap; grmip->nextcolormap; )
|
||||
{
|
||||
grmip = grmip->nextcolormap;
|
||||
if (grmip->colormap == colormap)
|
||||
{
|
||||
HWR_LoadMappedPatch(grmip, gpatch);
|
||||
return;
|
||||
}
|
||||
|
||||
if (grmip->colormap != colormap)
|
||||
continue;
|
||||
|
||||
HWR_LoadMappedPatch(grmip, gpatch);
|
||||
return;
|
||||
}
|
||||
// not found, create it!
|
||||
// If we are here, the sprite with the current colormap is not already in hardware memory
|
||||
|
||||
@@ -337,16 +337,16 @@ angle_t gld_FrustumAngle(angle_t tiltangle)
|
||||
floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * clipfov / 90.0f;
|
||||
if (floatangle >= 180.0)
|
||||
return 0xffffffff;
|
||||
a1 = ANG1 * (int)floatangle;
|
||||
a1 = (angle_t)(ANG1 * (int)floatangle);
|
||||
return a1;
|
||||
}
|
||||
|
||||
|
||||
// SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either
|
||||
// compiler complains about (p)glGetFloatv anyway, in case anyone wants this
|
||||
// only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks
|
||||
// btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h
|
||||
#ifdef HAVE_SPHEREFRUSTRUM
|
||||
|
||||
//
|
||||
// gld_FrustumSetup
|
||||
//
|
||||
|
||||
@@ -44,7 +44,6 @@ struct GLMipmap_s
|
||||
UINT16 width, height;
|
||||
UINT32 downloaded; // tex_downloaded
|
||||
|
||||
struct GLMipmap_s *nextmipmap;
|
||||
struct GLMipmap_s *nextcolormap;
|
||||
const UINT8 *colormap;
|
||||
};
|
||||
|
||||
@@ -175,8 +175,8 @@ enum
|
||||
SHADER_FLOOR = 0,
|
||||
SHADER_SHADOW,
|
||||
SHADER_WALL,
|
||||
SHADER_MODEL,
|
||||
SHADER_SPRITE,
|
||||
SHADER_MODEL,
|
||||
SHADER_WATER,
|
||||
SHADER_FOG,
|
||||
SHADER_SKY,
|
||||
|
||||
@@ -28,7 +28,7 @@ typedef struct gr_vissprite_s
|
||||
float x1, x2;
|
||||
float z1, z2;
|
||||
float gz, gzt;
|
||||
float tz, ty;
|
||||
float tz;
|
||||
float scale;
|
||||
float spritexscale, spriteyscale;
|
||||
float spritexoffset, spriteyoffset;
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
|
||||
#include "../doomdef.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hw_light.h"
|
||||
#include "hw_drv.h"
|
||||
#include "../i_video.h"
|
||||
#include "../z_zone.h"
|
||||
#include "../m_random.h"
|
||||
#include "../m_bbox.h"
|
||||
#include "../w_wad.h"
|
||||
#include "../r_state.h"
|
||||
#include "../r_main.h"
|
||||
#include "../p_local.h"
|
||||
|
||||
#endif // HWRENDER
|
||||
@@ -1,20 +0,0 @@
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2019 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief Dynamic lighting & coronas add on by Hurdler
|
||||
|
||||
#ifndef _HW_LIGHTS_
|
||||
#define _HW_LIGHTS_
|
||||
|
||||
#include "hw_glob.h"
|
||||
#include "hw_defs.h"
|
||||
|
||||
#endif
|
||||
+667
-1100
File diff suppressed because it is too large.
Load diff
@@ -120,7 +120,6 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc
|
||||
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
|
||||
|
||||
void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
|
||||
void HWR_AddPolyObjectPlanes(void);
|
||||
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
|
||||
|
||||
// hw_main.c: Segs
|
||||
@@ -132,12 +131,10 @@ void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 t
|
||||
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf);
|
||||
void HWR_DrawSkyBackground(float fpov);
|
||||
|
||||
void HWR_AddPolyObjectSegs(void);
|
||||
|
||||
// hw_main.c: Sprites
|
||||
void HWR_AddSprites(sector_t *sec);
|
||||
void HWR_ProjectSprite(mobj_t *thing);
|
||||
void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
|
||||
//void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
|
||||
void HWR_DrawSprites(void);
|
||||
|
||||
// hw_bsp.c
|
||||
@@ -155,10 +152,7 @@ extern consvar_t cv_grshaders;
|
||||
#ifdef USE_FBO_OGL
|
||||
extern consvar_t cv_grframebuffer;
|
||||
#endif
|
||||
extern consvar_t cv_grfofcut;
|
||||
extern consvar_t cv_fofzfightfix;
|
||||
extern consvar_t cv_splitwallfix;
|
||||
extern consvar_t cv_slopepegfix;
|
||||
extern consvar_t cv_grshearing;
|
||||
extern consvar_t cv_grfov;
|
||||
extern consvar_t cv_grmdls;
|
||||
@@ -179,6 +173,7 @@ extern consvar_t cv_grrenderdistance;
|
||||
extern consvar_t cv_grpaletterendering;
|
||||
extern consvar_t cv_grpalettedepth;
|
||||
extern consvar_t cv_grflashpal;
|
||||
extern consvar_t cv_lightdither;
|
||||
extern consvar_t cv_grscreentextures;
|
||||
extern consvar_t cv_grportals;
|
||||
extern consvar_t cv_nostencil;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hw_drv.h"
|
||||
#include "hw_light.h"
|
||||
#include "hw_md2.h"
|
||||
#include "../d_main.h"
|
||||
#include "../r_bsp.h"
|
||||
@@ -75,7 +74,7 @@
|
||||
|
||||
md2_t md2_models[NUMSPRITES];
|
||||
md2_t md2_playermodels[MAXSKINS];
|
||||
md2_t md2_localplayermodels[MAXSKINS];
|
||||
md2_t md2_localplayermodels[MAXLOCALSKINS];
|
||||
|
||||
|
||||
/*
|
||||
@@ -494,7 +493,9 @@ void HWR_InitMD2(void)
|
||||
md2_playermodels[s].skin = -1;
|
||||
md2_playermodels[s].notfound = true;
|
||||
md2_playermodels[s].error = false;
|
||||
|
||||
}
|
||||
for (s = 0; s < MAXLOCALSKINS; s++)
|
||||
{
|
||||
md2_localplayermodels[s].scale = -1.0f;
|
||||
md2_localplayermodels[s].model = NULL;
|
||||
md2_localplayermodels[s].grpatch = NULL;
|
||||
|
||||
@@ -37,7 +37,7 @@ typedef struct
|
||||
|
||||
extern md2_t md2_models[NUMSPRITES];
|
||||
extern md2_t md2_playermodels[MAXSKINS];
|
||||
extern md2_t md2_localplayermodels[MAXSKINS];
|
||||
extern md2_t md2_localplayermodels[MAXLOCALSKINS];
|
||||
|
||||
void HWR_InitMD2(void);
|
||||
void HWR_DrawMD2(gr_vissprite_t *spr);
|
||||
|
||||
+115
-1
@@ -82,6 +82,7 @@ static shadertarget_t gl_shadertargets[NUMSHADERTARGETS];
|
||||
#define WHITESPACE_CHARS " \t"
|
||||
|
||||
#define PALETTE_RENDERING_DEFINE "#define SRB2_PALETTE_RENDERING"
|
||||
#define LIGHT_DITHERING_DEFINE "#define SRB2_LIGHT_DITHER"
|
||||
|
||||
// Initialize shader variables and the backend's shader system. Load the base shaders.
|
||||
// Returns false if shaders cannot be used.
|
||||
@@ -282,6 +283,9 @@ static char *HWR_PreprocessShader(char *original)
|
||||
if (cv_grpaletterendering.value)
|
||||
ADD_TO_LEN(PALETTE_RENDERING_DEFINE)
|
||||
|
||||
if (cv_lightdither.value)
|
||||
ADD_TO_LEN(LIGHT_DITHERING_DEFINE)
|
||||
|
||||
#undef ADD_TO_LEN
|
||||
|
||||
#define VERSION_PART "#version "
|
||||
@@ -323,6 +327,9 @@ static char *HWR_PreprocessShader(char *original)
|
||||
if (cv_grpaletterendering.value)
|
||||
WRITE_DEFINE(PALETTE_RENDERING_DEFINE)
|
||||
|
||||
if (cv_lightdither.value)
|
||||
WRITE_DEFINE(LIGHT_DITHERING_DEFINE)
|
||||
|
||||
#undef WRITE_DEFINE
|
||||
|
||||
// Write a #line directive, so compiler errors will report line numbers from the
|
||||
@@ -446,6 +453,106 @@ void HWR_LoadAllCustomShaders(void)
|
||||
HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i]));
|
||||
}
|
||||
|
||||
static const char version_directives[][14] = {
|
||||
"#version 330\n",
|
||||
"#version 150\n",
|
||||
"#version 140\n",
|
||||
"#version 130\n",
|
||||
"#version 120\n",
|
||||
"#version 110\n",
|
||||
};
|
||||
|
||||
static boolean HWR_VersionDirectiveExists(const char* source)
|
||||
{
|
||||
return strncmp(source, "#version", 8) == 0;
|
||||
}
|
||||
|
||||
static char* HWR_PrependVersionDirective(const char* source, UINT32 version_index)
|
||||
{
|
||||
const UINT32 version_len = sizeof(version_directives[version_index]) - 1;
|
||||
const UINT32 source_len = strlen(source);
|
||||
|
||||
char* result = Z_Malloc(source_len + version_len + 1, PU_STATIC, NULL);
|
||||
strcpy(result, version_directives[version_index]);
|
||||
strcpy(result + version_len, source);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void HWR_ReplaceVersionInplace(char* shader, UINT32 version_index)
|
||||
{
|
||||
shader[9] = version_directives[version_index][9];
|
||||
shader[10] = version_directives[version_index][10];
|
||||
shader[11] = version_directives[version_index][11];
|
||||
}
|
||||
|
||||
static boolean HWR_CheckVersionDirectives(const char* vert, const char* frag)
|
||||
{
|
||||
return HWR_VersionDirectiveExists(vert) && HWR_VersionDirectiveExists(frag);
|
||||
}
|
||||
|
||||
static void HWR_TryToCompileShaderWithImplicitVersion(INT32 shader_index, INT32 shaderxlat_id)
|
||||
{
|
||||
char* vert_shader = gl_shaders[shader_index].vertex;
|
||||
char* frag_shader = gl_shaders[shader_index].fragment;
|
||||
|
||||
boolean vert_shader_version_exists = HWR_VersionDirectiveExists(vert_shader);
|
||||
boolean frag_shader_version_exists = HWR_VersionDirectiveExists(frag_shader);
|
||||
|
||||
if (!vert_shader_version_exists)
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: vertex shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
|
||||
|
||||
if (!frag_shader_version_exists)
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: fragment shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
|
||||
|
||||
// try to compile as is
|
||||
HWR_CompileShader(shader_index);
|
||||
|
||||
if (gl_shaders[shader_index].compiled)
|
||||
return;
|
||||
|
||||
// try each version directive
|
||||
for (UINT32 i = 0; i < sizeof(version_directives) / sizeof(version_directives[0]); ++i)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Trying %s\n", version_directives[i]);
|
||||
|
||||
if (!vert_shader_version_exists)
|
||||
{
|
||||
// first time reallocation would have to be made
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
void* old = (void*)gl_shaders[shader_index].vertex;
|
||||
vert_shader = gl_shaders[shader_index].vertex = HWR_PrependVersionDirective(vert_shader, i);
|
||||
Z_Free(old);
|
||||
}
|
||||
else
|
||||
HWR_ReplaceVersionInplace(vert_shader, i);
|
||||
}
|
||||
|
||||
if (!frag_shader_version_exists)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
void* old = (void*)gl_shaders[shader_index].fragment;
|
||||
frag_shader = gl_shaders[shader_index].fragment = HWR_PrependVersionDirective(frag_shader, i);
|
||||
Z_Free(old);
|
||||
}
|
||||
else
|
||||
HWR_ReplaceVersionInplace(frag_shader, i);
|
||||
}
|
||||
|
||||
HWR_CompileShader(shader_index);
|
||||
if (gl_shaders[shader_index].compiled)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Compiled with %s\n",
|
||||
version_directives[i]);
|
||||
CONS_Alert(CONS_WARNING, "Implicit GLSL version is used. Correct behavior is not guaranteed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
|
||||
{
|
||||
UINT16 lump;
|
||||
@@ -602,13 +709,20 @@ skip_field:
|
||||
{
|
||||
int shader_index = i + NUMSHADERTARGETS; // index to gl_shaders
|
||||
gl_shadertargets[i].custom_shader = shader_index;
|
||||
|
||||
// if only one stage (vertex/fragment) is defined, the other one
|
||||
// is copied from the base shaders.
|
||||
if (!gl_shaders[shader_index].fragment)
|
||||
gl_shaders[shader_index].fragment = Z_StrDup(gl_shadersources[i].fragment);
|
||||
|
||||
if (!gl_shaders[shader_index].vertex)
|
||||
gl_shaders[shader_index].vertex = Z_StrDup(gl_shadersources[i].vertex);
|
||||
HWR_CompileShader(shader_index);
|
||||
|
||||
if (!HWR_CheckVersionDirectives(gl_shaders[shader_index].vertex, gl_shaders[shader_index].fragment))
|
||||
HWR_TryToCompileShaderWithImplicitVersion(shader_index, i);
|
||||
else
|
||||
HWR_CompileShader(shader_index);
|
||||
|
||||
if (!gl_shaders[shader_index].compiled)
|
||||
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: A compilation error occured for the %s shader in file %s. See the console messages above for more information.\n", shaderxlat[i].type, wadfiles[wadnum]->filename);
|
||||
}
|
||||
|
||||
@@ -51,15 +51,53 @@
|
||||
//
|
||||
|
||||
// Include GLSL_FLOOR_FUDGES or GLSL_WALL_FUDGES or define the fudges in shaders that use this macro.
|
||||
#define GLSL_DOOM_COLORMAP_DITHER \
|
||||
"float baseValue = max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
|
||||
"float endResolutionx = scr_resolution.x;\n" \
|
||||
"float endResolutiony = scr_resolution.y;\n" \
|
||||
"if (scr_resolution.x > 1280.0) {\n" \
|
||||
"endResolutionx = scr_resolution.x * 0.5;\n" \
|
||||
"}\n" \
|
||||
"if (scr_resolution.y > 720.0) {\n" \
|
||||
"endResolutiony = scr_resolution.y * 0.5;\n" \
|
||||
"}\n" \
|
||||
"float zFactor = clamp((z - 192.0) / (6144.0 - 192.0), 0.0, 1.0);\n" \
|
||||
"int scaleFactor = int(mix(1.0, 8.0, zFactor));\n" \
|
||||
"endResolutionx = endResolutionx * scaleFactor;\n" \
|
||||
"endResolutiony = endResolutiony * scaleFactor;\n" \
|
||||
"vec2 normalizedPosition = position * vec2(endResolutionx / scr_resolution.x, endResolutiony / scr_resolution.y);\n" \
|
||||
"int x = int(mod(normalizedPosition.x, 4.0));\n" \
|
||||
"int y = int(mod(normalizedPosition.y, 4.0));\n" \
|
||||
"float bayerMatrix[4*4] = float[4*4](\n" \
|
||||
"0.0, 8.0, 2.0, 10.0,\n" \
|
||||
"12.0, 4.0, 14.0, 6.0,\n" \
|
||||
"3.0, 11.0, 1.0, 9.0,\n" \
|
||||
"15.0, 7.0, 13.0, 5.0\n" \
|
||||
");\n" \
|
||||
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||
"float threshold = (1.0 - pow(zFactor, 2.0)) * (bayerMatrix[y*4 + x] / 11.0);\n" \
|
||||
"#else\n" \
|
||||
"float threshold = (1.0 - pow(zFactor, 2.0)) * (bayerMatrix[y*4 + x] / 16.0);\n" \
|
||||
"#endif\n" \
|
||||
"return mix(baseValue + threshold - 0.5 / 16.0, baseValue, zFactor);\n"
|
||||
|
||||
#define GLSL_DOOM_COLORMAP_NODITHER \
|
||||
"return max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
|
||||
|
||||
#define GLSL_DOOM_COLORMAP \
|
||||
"float R_DoomColormap(float light, float z)\n" \
|
||||
"uniform vec2 scr_resolution;\n" \
|
||||
"float R_DoomColormap(float light, float z, vec2 position)\n" \
|
||||
"{\n" \
|
||||
"float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \
|
||||
"float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \
|
||||
"float startmap = (15.0 - lightnum) * 4.0;\n" \
|
||||
"float scale = 160.0 / (lightz + 1.0);\n" \
|
||||
"float cap = (155.0 - light) * 0.26;\n" \
|
||||
"return max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \
|
||||
"#ifdef SRB2_LIGHT_DITHER\n" \
|
||||
GLSL_DOOM_COLORMAP_DITHER \
|
||||
"#else\n" \
|
||||
GLSL_DOOM_COLORMAP_NODITHER \
|
||||
"#endif\n" \
|
||||
"}\n"
|
||||
// lighting cap adjustment:
|
||||
// first num (155.0), increase to make it start to go dark sooner
|
||||
@@ -69,7 +107,7 @@
|
||||
"float R_DoomLightingEquation(float light)\n" \
|
||||
"{\n" \
|
||||
"float z = gl_FragCoord.z / gl_FragCoord.w;\n" \
|
||||
"float colormap = floor(R_DoomColormap(light, z)) + 0.5;\n" \
|
||||
"float colormap = floor(R_DoomColormap(light, z, gl_FragCoord.xy)) + 0.5;\n" \
|
||||
"return clamp(colormap, 0.0, 31.0) / 32.0;\n" \
|
||||
"}\n"
|
||||
|
||||
@@ -95,7 +133,7 @@
|
||||
#define GLSL_PALETTE_RENDERING \
|
||||
"float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \
|
||||
"float z = gl_FragCoord.z / gl_FragCoord.w;\n" \
|
||||
"float light_y = clamp(floor(R_DoomColormap(lighting, z)), 0.0, 31.0);\n" \
|
||||
"float light_y = clamp(floor(R_DoomColormap(lighting, z, gl_FragCoord.xy)), 0.0, 31.0);\n" \
|
||||
"vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (light_y + 0.5) / 32.0);\n" \
|
||||
"vec4 final_color = texture2D(lighttable_tex, lighttable_coord);\n" \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
@@ -156,10 +194,12 @@
|
||||
|
||||
// hand tuned adjustments for light level calculation
|
||||
#define GLSL_FLOOR_FUDGES \
|
||||
"#version 120\n" \
|
||||
"#define STARTMAP_FUDGE 1.06\n" \
|
||||
"#define SCALE_FUDGE 1.15\n"
|
||||
|
||||
#define GLSL_WALL_FUDGES \
|
||||
"#version 120\n" \
|
||||
"#define STARTMAP_FUDGE 1.05\n" \
|
||||
"#define SCALE_FUDGE 2.2\n"
|
||||
|
||||
|
||||
@@ -120,8 +120,6 @@ GLfloat projMatrix[16];
|
||||
static GLint viewport[4];
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
static boolean GLFramebuffer_IsFuncAvailible(void);
|
||||
|
||||
GLuint FramebufferObject, FramebufferTexture, RenderbufferObject;
|
||||
GLboolean FrameBufferEnabled = GL_FALSE, RenderToFramebuffer = GL_FALSE;
|
||||
|
||||
@@ -608,6 +606,7 @@ typedef void (APIENTRY *PFNglDeleteProgram) (GLuint);
|
||||
typedef void (APIENTRY *PFNglAttachShader) (GLuint, GLuint);
|
||||
typedef void (APIENTRY *PFNglLinkProgram) (GLuint);
|
||||
typedef void (APIENTRY *PFNglGetProgramiv) (GLuint, GLenum, GLint*);
|
||||
typedef void (APIENTRY *PFNglGetProgramInfoLog) (GLuint, GLsizei, GLsizei*, GLchar*);
|
||||
typedef void (APIENTRY *PFNglUseProgram) (GLuint);
|
||||
typedef void (APIENTRY *PFNglUniform1i) (GLint, GLint);
|
||||
typedef void (APIENTRY *PFNglUniform1f) (GLint, GLfloat);
|
||||
@@ -630,6 +629,7 @@ static PFNglDeleteProgram pglDeleteProgram;
|
||||
static PFNglAttachShader pglAttachShader;
|
||||
static PFNglLinkProgram pglLinkProgram;
|
||||
static PFNglGetProgramiv pglGetProgramiv;
|
||||
static PFNglGetProgramInfoLog pglGetProgramInfoLog;
|
||||
static PFNglUseProgram pglUseProgram;
|
||||
static PFNglUniform1i pglUniform1i;
|
||||
static PFNglUniform1f pglUniform1f;
|
||||
@@ -669,6 +669,8 @@ typedef enum
|
||||
|
||||
// misc.
|
||||
gluniform_leveltime,
|
||||
|
||||
gluniform_scr_resolution,
|
||||
|
||||
gluniform_max,
|
||||
} gluniform_t;
|
||||
@@ -703,6 +705,9 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
||||
|
||||
static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
static boolean GLFramebuffer_IsFuncAvailible(void);
|
||||
#endif
|
||||
|
||||
void SetupGLFunc4(void)
|
||||
{
|
||||
@@ -735,6 +740,7 @@ void SetupGLFunc4(void)
|
||||
pglAttachShader = GetGLFunc("glAttachShader");
|
||||
pglLinkProgram = GetGLFunc("glLinkProgram");
|
||||
pglGetProgramiv = GetGLFunc("glGetProgramiv");
|
||||
pglGetProgramInfoLog = GetGLFunc("glGetProgramInfoLog");
|
||||
pglUseProgram = GetGLFunc("glUseProgram");
|
||||
pglUniform1i = GetGLFunc("glUniform1i");
|
||||
pglUniform1f = GetGLFunc("glUniform1f");
|
||||
@@ -759,6 +765,8 @@ void SetupGLFunc4(void)
|
||||
pglDeleteRenderbuffers = GetGLFunc("glDeleteRenderbuffers");
|
||||
pglRenderbufferStorage = GetGLFunc("glRenderbufferStorage");
|
||||
pglFramebufferRenderbuffer = GetGLFunc("glFramebufferRenderbuffer");
|
||||
|
||||
supportFBO = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -770,9 +778,7 @@ static boolean GLFramebuffer_IsFuncAvailible(void)
|
||||
if (majorGL < 3)
|
||||
return false;
|
||||
|
||||
return((isExtAvailable("GL_ARB_framebuffer_no_attachments",gl_extensions)) &&
|
||||
(isExtAvailable("GL_ARB_framebuffer_object",gl_extensions)) &&
|
||||
(isExtAvailable("GL_ARB_framebuffer_sRGB",gl_extensions)));
|
||||
return (isExtAvailable("GL_ARB_framebuffer_no_attachments",gl_extensions) && isExtAvailable("GL_ARB_framebuffer_object",gl_extensions) && isExtAvailable("GL_ARB_framebuffer_sRGB",gl_extensions));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -846,7 +852,7 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value)
|
||||
switch (info)
|
||||
{
|
||||
case HWD_SHADERINFO_LEVELTIME:
|
||||
shader_leveltime = value;
|
||||
shader_leveltime = (((float)(value-1)) + FIXED_TO_FLOAT(rendertimefrac)) / TICRATE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1038,37 +1044,9 @@ EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo)
|
||||
}
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
void GLFramebuffer_Generate(void)
|
||||
static void GLFramebuffer_GenerateAttachments(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
// Generate the framebuffer
|
||||
if (FramebufferObject == 0)
|
||||
pglGenFramebuffers(1, &FramebufferObject);
|
||||
|
||||
if (pglCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
|
||||
GLFramebuffer_GenerateAttachments();
|
||||
}
|
||||
|
||||
void GLFramebuffer_Delete(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
return;
|
||||
|
||||
// Unbind the framebuffer
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (FramebufferObject)
|
||||
pglDeleteFramebuffers(1, &FramebufferObject);
|
||||
|
||||
GLFramebuffer_DeleteAttachments();
|
||||
FramebufferObject = 0;
|
||||
}
|
||||
|
||||
void GLFramebuffer_GenerateAttachments(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
// Bind the framebuffer
|
||||
@@ -1109,11 +1087,12 @@ void GLFramebuffer_GenerateAttachments(void)
|
||||
|
||||
void GLFramebuffer_DeleteAttachments(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
// Unbind the framebuffer
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
if (FramebufferTexture)
|
||||
pglDeleteTextures(1, &FramebufferTexture);
|
||||
@@ -1125,9 +1104,43 @@ void GLFramebuffer_DeleteAttachments(void)
|
||||
RenderbufferObject = 0;
|
||||
}
|
||||
|
||||
void GLFramebuffer_Enable(void)
|
||||
static void GLFramebuffer_Generate(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
// Generate the framebuffer
|
||||
if (FramebufferObject == 0)
|
||||
pglGenFramebuffers(1, &FramebufferObject);
|
||||
|
||||
if (pglCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
|
||||
GLFramebuffer_GenerateAttachments();
|
||||
}
|
||||
|
||||
static void GLFramebuffer_Delete(void)
|
||||
{
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
if (FramebufferObject)
|
||||
pglDeleteFramebuffers(1, &FramebufferObject);
|
||||
|
||||
GLFramebuffer_DeleteAttachments();
|
||||
FramebufferObject = 0;
|
||||
}
|
||||
|
||||
inline void GLFramebuffer_Unbind(void)
|
||||
{
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
|
||||
inline void GLFramebuffer_Enable(void)
|
||||
{
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
if (FramebufferObject == 0)
|
||||
@@ -1141,11 +1154,13 @@ void GLFramebuffer_Enable(void)
|
||||
|
||||
void GLFramebuffer_Disable(void)
|
||||
{
|
||||
if (!GLFramebuffer_IsFuncAvailible())
|
||||
if (!supportFBO)
|
||||
return;
|
||||
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
GLFramebuffer_Delete();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1834,7 +1849,9 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f);
|
||||
}
|
||||
|
||||
UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)shader_leveltime) / TICRATE, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_leveltime], shader_leveltime, pglUniform1f);
|
||||
|
||||
UNIFORM_2(shader->uniforms[gluniform_scr_resolution], vid.width, vid.height, pglUniform2f);
|
||||
|
||||
#undef UNIFORM_1
|
||||
#undef UNIFORM_2
|
||||
@@ -1850,6 +1867,7 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
GLint result;
|
||||
const GLchar *vert_shader = shader->vertex_shader;
|
||||
const GLchar *frag_shader = shader->fragment_shader;
|
||||
GLchar info_log[512];
|
||||
|
||||
if (shader->program)
|
||||
pglDeleteProgram(shader->program);
|
||||
@@ -1879,7 +1897,10 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result);
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
GL_MSG_Error("Error compiling vertex shader", gl_vertShader, i);
|
||||
pglGetShaderInfoLog(gl_vertShader, 512, NULL, info_log);
|
||||
|
||||
GL_MSG_Error("Error compiling vertex shader: %s\n", info_log);
|
||||
|
||||
pglDeleteShader(gl_vertShader);
|
||||
return false;
|
||||
}
|
||||
@@ -1906,7 +1927,9 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result);
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
GL_MSG_Error("Error compiling fragment shader", gl_fragShader, i);
|
||||
pglGetShaderInfoLog(gl_fragShader, 512, NULL, info_log);
|
||||
|
||||
GL_MSG_Error("Error compiling fragment shader: %s\n", info_log);
|
||||
pglDeleteShader(gl_vertShader);
|
||||
pglDeleteShader(gl_fragShader);
|
||||
return false;
|
||||
@@ -1932,7 +1955,8 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
// couldn't link?
|
||||
if (result != GL_TRUE)
|
||||
{
|
||||
GL_MSG_Error("Shader_CompileProgram: Error linking shader program %s\n", HWR_GetShaderName(i));
|
||||
pglGetProgramInfoLog(shader->program, 512, NULL, info_log);
|
||||
GL_MSG_Error("Shader_CompileProgram: Error linking shader program %s: %s\n", HWR_GetShaderName(i), info_log);
|
||||
pglDeleteProgram(shader->program);
|
||||
return false;
|
||||
}
|
||||
@@ -1953,6 +1977,8 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
shader->uniforms[gluniform_palette_lookup_tex] = GETUNI("palette_lookup_tex");
|
||||
shader->uniforms[gluniform_lighttable_tex] = GETUNI("lighttable_tex");
|
||||
|
||||
shader->uniforms[gluniform_scr_resolution] = GETUNI("scr_resolution");
|
||||
|
||||
// misc.
|
||||
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
|
||||
#undef GETUNI
|
||||
@@ -2327,7 +2353,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
||||
#ifdef USE_FBO_OGL
|
||||
case HWD_SET_FRAMEBUFFER:
|
||||
FrameBufferEnabled = Value ? GL_TRUE : GL_FALSE;
|
||||
supportFBO = GLFramebuffer_IsFuncAvailible();
|
||||
|
||||
if (!supportFBO)
|
||||
{
|
||||
@@ -2960,7 +2985,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
||||
if (shearing)
|
||||
{
|
||||
float dy = FIXED_TO_FLOAT(AIMINGTODY((stransform->viewaiming)) * 2)* ((float)vid.width / vid.height) / ((float)BASEVIDWIDTH / BASEVIDHEIGHT); //screen_width/BASEVIDWIDTH;
|
||||
if (stransform->flip)
|
||||
if (stransform->flip || stransform->mirrorflip)
|
||||
dy *= -1.0f;
|
||||
pglTranslatef(0.0f, -dy/BASEVIDHEIGHT, 0.0f);
|
||||
}
|
||||
|
||||
@@ -105,12 +105,9 @@ static PFNglEnableClientState pglEnableClientState;
|
||||
#endif
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
void GLFramebuffer_Generate(void);
|
||||
void GLFramebuffer_Delete(void);
|
||||
|
||||
void GLFramebuffer_GenerateAttachments(void);
|
||||
void GLFramebuffer_DeleteAttachments(void);
|
||||
|
||||
void GLFramebuffer_Unbind(void);
|
||||
void GLFramebuffer_Enable(void);
|
||||
void GLFramebuffer_Disable(void);
|
||||
|
||||
|
||||
+6
-1
@@ -532,7 +532,9 @@ HMS_fetch_rules (char *buffer, size_t buffer_size)
|
||||
if (! hms)
|
||||
return NULL;
|
||||
|
||||
if (HMS_do(hms))
|
||||
boolean ok = HMS_do(hms);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
char *p = strstr(hms->buffer, "\n\n");
|
||||
|
||||
@@ -550,6 +552,9 @@ HMS_fetch_rules (char *buffer, size_t buffer_size)
|
||||
|
||||
HMS_end(hms);
|
||||
|
||||
if (!ok)
|
||||
return NULL;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
+14
-3
@@ -594,7 +594,10 @@ void HU_AddChatText(const char *text, boolean playsound)
|
||||
if (OLDCHAT) // if we're using oldchat, print directly in console
|
||||
CONS_Printf("%s\n", text);
|
||||
else // if we aren't, still save the message to log.txt
|
||||
CON_LogMessage(va("%s\n", text));
|
||||
{
|
||||
CON_LogMessage(text);
|
||||
CON_LogMessage("\n"); // Add newline. Don't use va for that, since `text` might be refering to va's buffer itself
|
||||
}
|
||||
#else
|
||||
(void)playsound;
|
||||
CONS_Printf("%s\n", text);
|
||||
@@ -1253,7 +1256,11 @@ void HU_Ticker(void)
|
||||
if (cechotimer > 0) --cechotimer;
|
||||
|
||||
// Animate the desynch dots
|
||||
if (hu_resynching)
|
||||
if (hu_resynching
|
||||
#ifdef SATURNSYNCH
|
||||
|| hu_redownloadinggamestate
|
||||
#endif
|
||||
)
|
||||
resynch_ticker++; //tic tic tic tic tic
|
||||
|
||||
HU_TickSongCredits();
|
||||
@@ -2418,7 +2425,11 @@ void HU_Drawer(void)
|
||||
HU_DrawSongCredits();
|
||||
|
||||
// draw desynch text
|
||||
if (hu_resynching)
|
||||
if (hu_resynching
|
||||
#ifdef SATURNSYNCH
|
||||
|| hu_redownloadinggamestate
|
||||
#endif
|
||||
)
|
||||
{
|
||||
char resynch_text[14];
|
||||
UINT32 i;
|
||||
|
||||
-20
@@ -34,7 +34,6 @@
|
||||
#define NO_BAN_TIME (time_t)(-1)
|
||||
|
||||
extern INT16 hardware_MAXPACKETLENGTH;
|
||||
extern INT32 net_bandwidth; // in byte/s
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
@@ -42,36 +41,17 @@ extern INT32 net_bandwidth; // in byte/s
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/// Supposed to be DOOMCOM_ID
|
||||
INT32 id;
|
||||
|
||||
/// SRB2 executes an INT32 to execute commands.
|
||||
INT16 intnum;
|
||||
/// Communication between SRB2 and the driver.
|
||||
/// Is CMD_SEND or CMD_GET.
|
||||
INT16 command;
|
||||
/// Is dest for send, set by get (-1 = no packet).
|
||||
INT16 remotenode;
|
||||
|
||||
/// Number of bytes in doomdata to be sent
|
||||
INT16 datalength;
|
||||
|
||||
/// Info common to all nodes.
|
||||
/// Console is always node 0.
|
||||
INT16 numnodes;
|
||||
/// Flag: 1 = no duplication, 2-5 = dup for slow nets.
|
||||
INT16 ticdup;
|
||||
/// Flag: 1 = send a backup tic in every packet.
|
||||
INT16 extratics;
|
||||
/// kind of game
|
||||
INT16 gametype;
|
||||
/// Flag: -1 = new game, 0-5 = load savegame
|
||||
INT16 savegame;
|
||||
/// currect map
|
||||
INT16 map;
|
||||
|
||||
/// Info specific to this node.
|
||||
INT16 consoleplayer;
|
||||
/// Number of "slots": the highest player number in use plus one.
|
||||
INT16 numslots;
|
||||
|
||||
|
||||
@@ -159,7 +159,6 @@ boolean I_SetSongPosition(UINT32 position);
|
||||
UINT32 I_GetSongPosition(void);
|
||||
|
||||
void I_UpdateSongLagThreshold (void);
|
||||
void I_UpdateSongLagConditions (void);
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC PLAYBACK
|
||||
|
||||
@@ -34,6 +34,9 @@ extern UINT8 graphics_started;
|
||||
*/
|
||||
extern UINT8 keyboard_started;
|
||||
|
||||
/** \brief Set to true when inside a signal handler that will exit the program. */
|
||||
extern boolean g_in_exiting_signal_handler;
|
||||
|
||||
/** \brief The I_GetFreeMem function
|
||||
|
||||
\param total total memory in the system
|
||||
@@ -227,6 +230,9 @@ INT32 I_NumJoys(void);
|
||||
*/
|
||||
const char *I_GetJoyName(INT32 joyindex);
|
||||
|
||||
void I_GamepadRumble(INT32 device_id, UINT16 low_strength, UINT16 high_strength, UINT32 duration);
|
||||
void I_SetGamepadIndicatorColor(INT32 device_id, UINT8 red, UINT8 green, UINT8 blue);
|
||||
|
||||
#ifndef NOMUMBLE
|
||||
#include "p_mobj.h" // mobj_t
|
||||
#include "s_sound.h" // listener_t
|
||||
|
||||
@@ -1692,8 +1692,6 @@ boolean I_InitTcpNetwork(void)
|
||||
// FIXME: for dedicated server, numnodes needs to be set to 0 upon start
|
||||
if (dedicated)
|
||||
doomcom->numnodes = 0;
|
||||
/* else if (M_IsNextParm())
|
||||
doomcom->numnodes = (INT16)atoi(M_GetNextParm());*/
|
||||
else
|
||||
doomcom->numnodes = 1;
|
||||
|
||||
@@ -1707,7 +1705,6 @@ boolean I_InitTcpNetwork(void)
|
||||
// FIXME:
|
||||
// ??? and now ?
|
||||
// server on a big modem ??? 4*isdn
|
||||
net_bandwidth = 16000;
|
||||
hardware_MAXPACKETLENGTH = INETPACKETLENGTH;
|
||||
|
||||
ret = true;
|
||||
@@ -1738,7 +1735,6 @@ boolean I_InitTcpNetwork(void)
|
||||
// so we're on a LAN
|
||||
COM_BufAddText("connect any\n");
|
||||
|
||||
net_bandwidth = 800000;
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
}
|
||||
}
|
||||
@@ -1763,8 +1759,6 @@ boolean I_InitTcpNetwork(void)
|
||||
{
|
||||
// so we're on a LAN
|
||||
COM_BufAddText("connect any\n");
|
||||
|
||||
net_bandwidth = 800000;
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,10 @@ UINT32 I_GetRefreshRate(void);
|
||||
boolean I_UseNativeKeyboard(void);
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
#if defined (__unix__)
|
||||
extern boolean xwaylandcrap;
|
||||
#endif
|
||||
|
||||
void RefreshOGLSDLSurface(void);
|
||||
void I_DownSample(void);
|
||||
extern boolean downsample;
|
||||
|
||||
+10
-10
@@ -1822,7 +1822,7 @@ state_t states[NUMSTATES] =
|
||||
|
||||
// Rain
|
||||
{SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1
|
||||
{SPR_RAIN, FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN
|
||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RAINRETURN
|
||||
|
||||
// Snowflake
|
||||
{SPR_SNO1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNOW1
|
||||
@@ -1841,9 +1841,9 @@ state_t states[NUMSTATES] =
|
||||
{SPR_SPLH, FF_TRANS50|8, 2, {NULL}, 0, 0, S_NULL}, // S_SPLISH9
|
||||
|
||||
// Water Splash
|
||||
{SPR_SPLA, FF_TRANS50 , 3, {NULL}, 0, 0, S_SPLASH2}, // S_SPLASH1
|
||||
{SPR_SPLA, FF_TRANS70|1, 3, {NULL}, 0, 0, S_SPLASH3}, // S_SPLASH2
|
||||
{SPR_SPLA, FF_TRANS90|2, 3, {NULL}, 0, 0, S_RAINRETURN}, // S_SPLASH3
|
||||
{SPR_SPLA, FF_TRANS50 , 3, {NULL}, 0, 0, S_SPLASH2}, // S_SPLASH1
|
||||
{SPR_SPLA, FF_TRANS70|1, 3, {NULL}, 0, 0, S_SPLASH3}, // S_SPLASH2
|
||||
{SPR_SPLA, FF_TRANS90|2, 3, {NULL}, 0, 0, S_NULL}, // S_SPLASH3
|
||||
|
||||
// Smoke
|
||||
{SPR_SMOK, FF_TRANS50 , 4, {NULL}, 0, 0, S_SMOKE2}, // S_SMOKE1
|
||||
@@ -11198,22 +11198,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||
S_RAIN1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_rainin, // seesound
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_SPLASH1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
-72*FRACUNIT, // speed -- -24*FRACUNIT originally, srb2kart x3 (nya)
|
||||
1*FRACUNIT, // radius
|
||||
8*FRACUNIT, // height
|
||||
0, // display offset
|
||||
4, // mass
|
||||
80, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP, // flags
|
||||
@@ -11226,7 +11226,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
0, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
@@ -11240,7 +11240,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||
4*FRACUNIT, // radius
|
||||
4*FRACUNIT, // height
|
||||
0, // display offset
|
||||
4, // mass
|
||||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP, // flags
|
||||
|
||||
+430
-203
@@ -22,211 +22,438 @@
|
||||
// dehacked.c now has lists for the more named enums! PLEASE keep them up to date!
|
||||
// For great modding!!
|
||||
|
||||
/** Action pointer for reading actions from Dehacked lumps.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
actionf_t action; ///< Function pointer corresponding to the actual action.
|
||||
const char *name; ///< Name of the action in ALL CAPS.
|
||||
} actionpointer_t;
|
||||
|
||||
/** Array mapping action names to action functions.
|
||||
* Names must be in ALL CAPS for case insensitive comparisons.
|
||||
*/
|
||||
extern actionpointer_t actionpointers[];
|
||||
|
||||
// IMPORTANT!
|
||||
// DO NOT FORGET TO SYNC THIS LIST WITH THE ACTIONPOINTERS ARRAY IN DEHACKED.C
|
||||
enum actionnum
|
||||
{
|
||||
A_EXPLODE = 0,
|
||||
A_PAIN,
|
||||
A_FALL,
|
||||
A_MONITORPOP,
|
||||
A_LOOK,
|
||||
A_CHASE,
|
||||
A_FACESTABCHASE,
|
||||
A_FACETARGET,
|
||||
A_FACETRACER,
|
||||
A_SCREAM,
|
||||
A_BOSSDEATH,
|
||||
A_CUSTOMPOWER,
|
||||
A_GIVEWEAPON,
|
||||
A_RINGSHIELD,
|
||||
A_RINGBOX,
|
||||
A_INVINCIBILITY,
|
||||
A_SUPERSNEAKERS,
|
||||
A_BUNNYHOP,
|
||||
A_BUBBLESPAWN,
|
||||
A_FANBUBBLESPAWN,
|
||||
A_BUBBLERISE,
|
||||
A_BUBBLECHECK,
|
||||
A_AWARDSCORE,
|
||||
A_EXTRALIFE,
|
||||
A_BOMBSHIELD,
|
||||
A_JUMPSHIELD,
|
||||
A_WATERSHIELD,
|
||||
A_FORCESHIELD,
|
||||
A_PITYSHIELD,
|
||||
A_GRAVITYBOX,
|
||||
A_SCORERISE,
|
||||
A_PARTICLESPAWN,
|
||||
A_ATTRACTCHASE,
|
||||
A_DROPMINE,
|
||||
A_FISHJUMP,
|
||||
A_THROWNRING,
|
||||
A_GRENADERING, // SRB2kart
|
||||
A_SETSOLIDSTEAM,
|
||||
A_UNSETSOLIDSTEAM,
|
||||
A_SIGNPLAYER,
|
||||
A_OVERLAYTHINK,
|
||||
A_JETCHASE,
|
||||
A_JETBTHINK,
|
||||
A_JETGTHINK,
|
||||
A_JETGSHOOT,
|
||||
A_SHOOTBULLET,
|
||||
A_MINUSDIGGING,
|
||||
A_MINUSPOPUP,
|
||||
A_MINUSCHECK,
|
||||
A_CHICKENCHECK,
|
||||
A_MOUSETHINK,
|
||||
A_DETONCHASE,
|
||||
A_CAPECHASE,
|
||||
A_ROTATESPIKEBALL,
|
||||
A_SLINGAPPEAR,
|
||||
A_MACEROTATE,
|
||||
A_UNIDUSBALL,
|
||||
A_ROCKSPAWN,
|
||||
A_SETFUSE,
|
||||
A_CRAWLACOMMANDERTHINK,
|
||||
A_SMOKETRAILER,
|
||||
A_RINGEXPLODE,
|
||||
A_OLDRINGEXPLODE,
|
||||
A_MIXUP,
|
||||
A_RECYCLEPOWERS,
|
||||
A_BOSS1CHASE,
|
||||
A_FOCUSTARGET,
|
||||
A_BOSS2CHASE,
|
||||
A_BOSS2POGO,
|
||||
A_BOSSZOOM,
|
||||
A_BOSSSCREAM,
|
||||
A_BOSS2TAKEDAMAGE,
|
||||
A_BOSS7CHASE,
|
||||
A_GOOPSPLAT,
|
||||
A_BOSS2POGOSFX,
|
||||
A_BOSS2POGOTARGET,
|
||||
A_BOSSJETFUME,
|
||||
A_EGGMANBOX,
|
||||
A_TURRETFIRE,
|
||||
A_SUPERTURRETFIRE,
|
||||
A_TURRETSTOP,
|
||||
A_JETJAWROAM,
|
||||
A_JETJAWCHOMP,
|
||||
A_POINTYTHINK,
|
||||
A_CHECKBUDDY,
|
||||
A_HOODTHINK,
|
||||
A_ARROWCHECK,
|
||||
A_SNAILERTHINK,
|
||||
A_SHARPCHASE,
|
||||
A_SHARPSPIN,
|
||||
A_VULTUREVTOL,
|
||||
A_VULTURECHECK,
|
||||
A_SKIMCHASE,
|
||||
A_1UPTHINKER,
|
||||
A_SKULLATTACK,
|
||||
A_LOBSHOT,
|
||||
A_FIRESHOT,
|
||||
A_SUPERFIRESHOT,
|
||||
A_BOSSFIRESHOT,
|
||||
A_BOSS7FIREMISSILES,
|
||||
A_BOSS1LASER,
|
||||
A_BOSS4REVERSE,
|
||||
A_BOSS4SPEEDUP,
|
||||
A_BOSS4RAISE,
|
||||
A_SPARKFOLLOW,
|
||||
A_BUZZFLY,
|
||||
A_GUARDCHASE,
|
||||
A_EGGSHIELD,
|
||||
A_SETREACTIONTIME,
|
||||
A_BOSS1SPIKEBALLS,
|
||||
A_BOSS3TAKEDAMAGE,
|
||||
A_BOSS3PATH,
|
||||
A_LINEDEFEXECUTE,
|
||||
A_PLAYSEESOUND,
|
||||
A_PLAYATTACKSOUND,
|
||||
A_PLAYACTIVESOUND,
|
||||
A_SPAWNOBJECTABSOLUTE,
|
||||
A_SPAWNOBJECTRELATIVE,
|
||||
A_CHANGEANGLERELATIVE,
|
||||
A_CHANGEANGLEABSOLUTE,
|
||||
A_ROLLANGLE,
|
||||
A_CHANGEROLLANGLERELATIVE,
|
||||
A_CHANGEROLLANGLEABSOLUTE,
|
||||
A_PLAYSOUND,
|
||||
A_FINDTARGET,
|
||||
A_FINDTRACER,
|
||||
A_SETTICS,
|
||||
A_SETRANDOMTICS,
|
||||
A_CHANGECOLORRELATIVE,
|
||||
A_CHANGECOLORABSOLUTE,
|
||||
A_MOVERELATIVE,
|
||||
A_MOVEABSOLUTE,
|
||||
A_THRUST,
|
||||
A_ZTHRUST,
|
||||
A_SETTARGETSTARGET,
|
||||
A_SETOBJECTFLAGS,
|
||||
A_SETOBJECTFLAGS2,
|
||||
A_RANDOMSTATE,
|
||||
A_RANDOMSTATERANGE,
|
||||
A_DUALACTION,
|
||||
A_REMOTEACTION,
|
||||
A_TOGGLEFLAMEJET,
|
||||
A_ITEMPOP, // SRB2kart
|
||||
A_JAWZCHASE, // SRB2kart
|
||||
A_JAWZEXPLODE, // SRB2kart
|
||||
A_SPBCHASE, // SRB2kart
|
||||
A_MINEEXPLODE, // SRB2kart
|
||||
A_BALLHOGEXPLODE, // SRB2kart
|
||||
A_LIGHTNINGFOLLOWPLAYER, //SRB2kart
|
||||
A_FZBOOMFLASH, //SRB2kart
|
||||
A_FZBOOMSMOKE, //SRB2kart
|
||||
A_RANDOMSHADOWFRAME, //SRB2kart
|
||||
A_ROAMINGSHADOWTHINKER, //SRB2kart
|
||||
A_MAYONAKAARROW, //SRB2kart
|
||||
A_REAPERTHINKER, //SRB2kart
|
||||
A_MEMENTOSTPPARTICLES, //SRB2kart
|
||||
A_FLAMEPARTICLE, // SRB2kart
|
||||
A_ORBITNIGHTS,
|
||||
A_GHOSTME,
|
||||
A_SETOBJECTSTATE,
|
||||
A_SETOBJECTTYPESTATE,
|
||||
A_KNOCKBACK,
|
||||
A_PUSHAWAY,
|
||||
A_RINGDRAIN,
|
||||
A_SPLITSHOT,
|
||||
A_MISSILESPLIT,
|
||||
A_MULTISHOT,
|
||||
A_INSTALOOP,
|
||||
A_CUSTOM3DROTATE,
|
||||
A_SEARCHFORPLAYERS,
|
||||
A_CHECKRANDOM,
|
||||
A_CHECKTARGETRINGS,
|
||||
A_CHECKRINGS,
|
||||
A_CHECKTOTALRINGS,
|
||||
A_CHECKHEALTH,
|
||||
A_CHECKRANGE,
|
||||
A_CHECKHEIGHT,
|
||||
A_CHECKTRUERANGE,
|
||||
A_CHECKTHINGCOUNT,
|
||||
A_CHECKAMBUSH,
|
||||
A_CHECKCUSTOMVALUE,
|
||||
A_CHECKCUSVALMEMO,
|
||||
A_SETCUSTOMVALUE,
|
||||
A_USECUSVALMEMO,
|
||||
A_RELAYCUSTOMVALUE,
|
||||
A_CUSVALACTION,
|
||||
A_FORCESTOP,
|
||||
A_FORCEWIN,
|
||||
A_SPIKERETRACT,
|
||||
A_INFOSTATE,
|
||||
A_REPEAT,
|
||||
A_SETSCALE,
|
||||
A_REMOTEDAMAGE,
|
||||
A_HOMINGCHASE,
|
||||
A_TRAPSHOT,
|
||||
A_VILETARGET,
|
||||
A_VILEATTACK,
|
||||
A_VILEFIRE,
|
||||
A_BRAKCHASE,
|
||||
A_BRAKFIRESHOT,
|
||||
A_BRAKLOBSHOT,
|
||||
A_NAPALMSCATTER,
|
||||
A_SPAWNFRESHCOPY,
|
||||
NUMACTIONS
|
||||
};
|
||||
|
||||
struct mobj_s;
|
||||
|
||||
// IMPORTANT NOTE: If you add/remove from this list of action
|
||||
// functions, don't forget to update them in dehacked.c!
|
||||
void A_Explode();
|
||||
void A_Pain();
|
||||
void A_Fall();
|
||||
void A_MonitorPop();
|
||||
void A_Look();
|
||||
void A_Chase();
|
||||
void A_FaceStabChase();
|
||||
void A_FaceTarget();
|
||||
void A_FaceTracer();
|
||||
void A_Scream();
|
||||
void A_BossDeath();
|
||||
void A_CustomPower(); // Use this for a custom power
|
||||
void A_GiveWeapon(); // Gives the player weapon(s)
|
||||
void A_JumpShield(); // Obtained Jump Shield
|
||||
void A_RingShield(); // Obtained Ring Shield
|
||||
void A_RingBox(); // Obtained Ring Box Tails
|
||||
void A_Invincibility(); // Obtained Invincibility Box
|
||||
void A_SuperSneakers(); // Obtained Super Sneakers Box
|
||||
void A_BunnyHop(); // have bunny hop tails
|
||||
void A_BubbleSpawn(); // Randomly spawn bubbles
|
||||
void A_FanBubbleSpawn();
|
||||
void A_BubbleRise(); // Bubbles float to surface
|
||||
void A_BubbleCheck(); // Don't draw if not underwater
|
||||
void A_AwardScore();
|
||||
void A_ExtraLife(); // Extra Life
|
||||
void A_BombShield(); // Obtained Bomb Shield
|
||||
void A_WaterShield(); // Obtained Water Shield
|
||||
void A_ForceShield(); // Obtained Force Shield
|
||||
void A_PityShield(); // Obtained Pity Shield. We're... sorry.
|
||||
void A_GravityBox();
|
||||
void A_ScoreRise(); // Rise the score logo
|
||||
void A_ParticleSpawn();
|
||||
void A_AttractChase(); // Ring Chase
|
||||
void A_DropMine(); // Drop Mine from Skim or Jetty-Syn Bomber
|
||||
void A_FishJump(); // Fish Jump
|
||||
void A_ThrownRing(); // Sparkle trail for red ring
|
||||
void A_GrenadeRing(); // SRB2kart
|
||||
void A_SetSolidSteam();
|
||||
void A_UnsetSolidSteam();
|
||||
void A_SignPlayer();
|
||||
void A_OverlayThink();
|
||||
void A_JetChase();
|
||||
void A_JetbThink(); // Jetty-Syn Bomber Thinker
|
||||
void A_JetgThink(); // Jetty-Syn Gunner Thinker
|
||||
void A_JetgShoot(); // Jetty-Syn Shoot Function
|
||||
void A_ShootBullet(); // JetgShoot without reactiontime setting
|
||||
void A_MinusDigging();
|
||||
void A_MinusPopup();
|
||||
void A_MinusCheck();
|
||||
void A_ChickenCheck();
|
||||
void A_MouseThink(); // Mouse Thinker
|
||||
void A_DetonChase(); // Deton Chaser
|
||||
void A_CapeChase(); // Fake little Super Sonic cape
|
||||
void A_RotateSpikeBall(); // Spike ball rotation
|
||||
void A_SlingAppear();
|
||||
void A_MaceRotate();
|
||||
void A_UnidusBall();
|
||||
void A_RockSpawn();
|
||||
void A_SetFuse();
|
||||
void A_CrawlaCommanderThink(); // Crawla Commander
|
||||
void A_SmokeTrailer();
|
||||
void A_RingExplode();
|
||||
void A_OldRingExplode();
|
||||
void A_MixUp();
|
||||
void A_RecyclePowers();
|
||||
void A_BossScream();
|
||||
void A_Boss2TakeDamage();
|
||||
void A_GoopSplat();
|
||||
void A_Boss2PogoSFX();
|
||||
void A_Boss2PogoTarget();
|
||||
void A_EggmanBox();
|
||||
void A_TurretFire();
|
||||
void A_SuperTurretFire();
|
||||
void A_TurretStop();
|
||||
void A_JetJawRoam();
|
||||
void A_JetJawChomp();
|
||||
void A_PointyThink();
|
||||
void A_CheckBuddy();
|
||||
void A_HoodThink();
|
||||
void A_ArrowCheck();
|
||||
void A_SnailerThink();
|
||||
void A_SharpChase();
|
||||
void A_SharpSpin();
|
||||
void A_VultureVtol();
|
||||
void A_VultureCheck();
|
||||
void A_SkimChase();
|
||||
void A_SkullAttack();
|
||||
void A_LobShot();
|
||||
void A_FireShot();
|
||||
void A_SuperFireShot();
|
||||
void A_BossFireShot();
|
||||
void A_Boss7FireMissiles();
|
||||
void A_Boss1Laser();
|
||||
void A_FocusTarget();
|
||||
void A_Boss4Reverse();
|
||||
void A_Boss4SpeedUp();
|
||||
void A_Boss4Raise();
|
||||
void A_SparkFollow();
|
||||
void A_BuzzFly();
|
||||
void A_GuardChase();
|
||||
void A_EggShield();
|
||||
void A_SetReactionTime();
|
||||
void A_Boss1Spikeballs();
|
||||
void A_Boss3TakeDamage();
|
||||
void A_Boss3Path();
|
||||
void A_LinedefExecute();
|
||||
void A_PlaySeeSound();
|
||||
void A_PlayAttackSound();
|
||||
void A_PlayActiveSound();
|
||||
void A_1upThinker();
|
||||
void A_BossZoom(); //Unused
|
||||
void A_Boss1Chase();
|
||||
void A_Boss2Chase();
|
||||
void A_Boss2Pogo();
|
||||
void A_Boss7Chase();
|
||||
void A_BossJetFume();
|
||||
void A_SpawnObjectAbsolute();
|
||||
void A_SpawnObjectRelative();
|
||||
void A_ChangeAngleRelative();
|
||||
void A_ChangeAngleAbsolute();
|
||||
void A_RollAngle();
|
||||
void A_ChangeRollAngleRelative();
|
||||
void A_ChangeRollAngleAbsolute();
|
||||
void A_PlaySound();
|
||||
void A_FindTarget();
|
||||
void A_FindTracer();
|
||||
void A_SetTics();
|
||||
void A_SetRandomTics();
|
||||
void A_ChangeColorRelative();
|
||||
void A_ChangeColorAbsolute();
|
||||
void A_MoveRelative();
|
||||
void A_MoveAbsolute();
|
||||
void A_Thrust();
|
||||
void A_ZThrust();
|
||||
void A_SetTargetsTarget();
|
||||
void A_SetObjectFlags();
|
||||
void A_SetObjectFlags2();
|
||||
void A_RandomState();
|
||||
void A_RandomStateRange();
|
||||
void A_DualAction();
|
||||
void A_RemoteAction();
|
||||
void A_ToggleFlameJet();
|
||||
void A_ItemPop(); // SRB2kart
|
||||
void A_JawzChase(); // SRB2kart
|
||||
void A_JawzExplode(); // SRB2kart
|
||||
void A_SPBChase(); // SRB2kart
|
||||
void A_MineExplode(); // SRB2kart
|
||||
void A_BallhogExplode(); // SRB2kart
|
||||
void A_LightningFollowPlayer(); // SRB2kart: Lightning shield effect player chasing
|
||||
void A_FZBoomFlash(); // SRB2kart
|
||||
void A_FZBoomSmoke(); // SRB2kart
|
||||
void A_RandomShadowFrame(); //SRB2kart: Shadow spawner frame randomizer
|
||||
void A_RoamingShadowThinker(); // SRB2kart: Roaming Shadow moving + attacking players.
|
||||
void A_MayonakaArrow(); //SRB2kart: midnight channel arrow sign
|
||||
void A_ReaperThinker(); //SRB2kart: mementos reaper
|
||||
void A_MementosTPParticles(); //SRB2kart: mementos teleporter particles. Man that's a lot of actions for my shite.
|
||||
void A_FlameParticle(); // SRB2kart
|
||||
void A_OrbitNights();
|
||||
void A_GhostMe();
|
||||
void A_SetObjectState();
|
||||
void A_SetObjectTypeState();
|
||||
void A_KnockBack();
|
||||
void A_PushAway();
|
||||
void A_RingDrain();
|
||||
void A_SplitShot();
|
||||
void A_MissileSplit();
|
||||
void A_MultiShot();
|
||||
void A_InstaLoop();
|
||||
void A_Custom3DRotate();
|
||||
void A_SearchForPlayers();
|
||||
void A_CheckRandom();
|
||||
void A_CheckTargetRings();
|
||||
void A_CheckRings();
|
||||
void A_CheckTotalRings();
|
||||
void A_CheckHealth();
|
||||
void A_CheckRange();
|
||||
void A_CheckHeight();
|
||||
void A_CheckTrueRange();
|
||||
void A_CheckThingCount();
|
||||
void A_CheckAmbush();
|
||||
void A_CheckCustomValue();
|
||||
void A_CheckCusValMemo();
|
||||
void A_SetCustomValue();
|
||||
void A_UseCusValMemo();
|
||||
void A_RelayCustomValue();
|
||||
void A_CusValAction();
|
||||
void A_ForceStop();
|
||||
void A_ForceWin();
|
||||
void A_SpikeRetract();
|
||||
void A_InfoState();
|
||||
void A_Repeat();
|
||||
void A_SetScale();
|
||||
void A_RemoteDamage();
|
||||
void A_HomingChase();
|
||||
void A_TrapShot();
|
||||
void A_VileTarget();
|
||||
void A_VileAttack();
|
||||
void A_VileFire();
|
||||
void A_BrakChase();
|
||||
void A_BrakFireShot();
|
||||
void A_BrakLobShot();
|
||||
void A_NapalmScatter();
|
||||
void A_SpawnFreshCopy();
|
||||
void A_Explode(struct mobj_s *actor);
|
||||
void A_Pain(struct mobj_s *actor);
|
||||
void A_Fall(struct mobj_s *actor);
|
||||
void A_MonitorPop(struct mobj_s *actor);
|
||||
void A_Look(struct mobj_s *actor);
|
||||
void A_Chase(struct mobj_s *actor);
|
||||
void A_FaceStabChase(struct mobj_s *actor);
|
||||
void A_FaceTarget(struct mobj_s *actor);
|
||||
void A_FaceTracer(struct mobj_s *actor);
|
||||
void A_Scream(struct mobj_s *actor);
|
||||
void A_BossDeath(struct mobj_s *actor);
|
||||
void A_CustomPower(struct mobj_s *actor); // Use this for a custom power
|
||||
void A_GiveWeapon(struct mobj_s *actor); // Gives the player weapon(s)
|
||||
void A_JumpShield(struct mobj_s *actor); // Obtained Jump Shield
|
||||
void A_RingShield(struct mobj_s *actor); // Obtained Ring Shield
|
||||
void A_RingBox(struct mobj_s *actor); // Obtained Ring Box Tails
|
||||
void A_Invincibility(struct mobj_s *actor); // Obtained Invincibility Box
|
||||
void A_SuperSneakers(struct mobj_s *actor); // Obtained Super Sneakers Box
|
||||
void A_BunnyHop(struct mobj_s *actor); // have bunny hop tails
|
||||
void A_BubbleSpawn(struct mobj_s *actor); // Randomly spawn bubbles
|
||||
void A_FanBubbleSpawn(struct mobj_s *actor);
|
||||
void A_BubbleRise(struct mobj_s *actor); // Bubbles float to surface
|
||||
void A_BubbleCheck(struct mobj_s *actor); // Don't draw if not underwater
|
||||
void A_AwardScore(struct mobj_s *actor);
|
||||
void A_ExtraLife(struct mobj_s *actor); // Extra Life
|
||||
void A_BombShield(struct mobj_s *actor); // Obtained Bomb Shield
|
||||
void A_WaterShield(struct mobj_s *actor); // Obtained Water Shield
|
||||
void A_ForceShield(struct mobj_s *actor); // Obtained Force Shield
|
||||
void A_PityShield(struct mobj_s *actor); // Obtained Pity Shield. We're... sorry.
|
||||
void A_GravityBox(struct mobj_s *actor);
|
||||
void A_ScoreRise(struct mobj_s *actor); // Rise the score logo
|
||||
void A_ParticleSpawn(struct mobj_s *actor);
|
||||
void A_AttractChase(struct mobj_s *actor); // Ring Chase
|
||||
void A_DropMine(struct mobj_s *actor); // Drop Mine from Skim or Jetty-Syn Bomber
|
||||
void A_FishJump(struct mobj_s *actor); // Fish Jump
|
||||
void A_ThrownRing(struct mobj_s *actor); // Sparkle trail for red ring
|
||||
void A_GrenadeRing(struct mobj_s *actor); // SRB2kart
|
||||
void A_SetSolidSteam(struct mobj_s *actor);
|
||||
void A_UnsetSolidSteam(struct mobj_s *actor);
|
||||
void A_SignPlayer(struct mobj_s *actor);
|
||||
void A_OverlayThink(struct mobj_s *actor);
|
||||
void A_JetChase(struct mobj_s *actor);
|
||||
void A_JetbThink(struct mobj_s *actor); // Jetty-Syn Bomber Thinker
|
||||
void A_JetgThink(struct mobj_s *actor); // Jetty-Syn Gunner Thinker
|
||||
void A_JetgShoot(struct mobj_s *actor); // Jetty-Syn Shoot Function
|
||||
void A_ShootBullet(struct mobj_s *actor); // JetgShoot without reactiontime setting
|
||||
void A_MinusDigging(struct mobj_s *actor);
|
||||
void A_MinusPopup(struct mobj_s *actor);
|
||||
void A_MinusCheck(struct mobj_s *actor);
|
||||
void A_ChickenCheck(struct mobj_s *actor);
|
||||
void A_MouseThink(struct mobj_s *actor); // Mouse Thinker
|
||||
void A_DetonChase(struct mobj_s *actor); // Deton Chaser
|
||||
void A_CapeChase(struct mobj_s *actor); // Fake little Super Sonic cape
|
||||
void A_RotateSpikeBall(struct mobj_s *actor); // Spike ball rotation
|
||||
void A_SlingAppear(struct mobj_s *actor);
|
||||
void A_MaceRotate(struct mobj_s *actor);
|
||||
void A_UnidusBall(struct mobj_s *actor);
|
||||
void A_RockSpawn(struct mobj_s *actor);
|
||||
void A_SetFuse(struct mobj_s *actor);
|
||||
void A_CrawlaCommanderThink(struct mobj_s *actor); // Crawla Commander
|
||||
void A_SmokeTrailer(struct mobj_s *actor);
|
||||
void A_RingExplode(struct mobj_s *actor);
|
||||
void A_OldRingExplode(struct mobj_s *actor);
|
||||
void A_MixUp(struct mobj_s *actor);
|
||||
void A_RecyclePowers(struct mobj_s *actor);
|
||||
void A_BossScream(struct mobj_s *actor);
|
||||
void A_Boss2TakeDamage(struct mobj_s *actor);
|
||||
void A_GoopSplat(struct mobj_s *actor);
|
||||
void A_Boss2PogoSFX(struct mobj_s *actor);
|
||||
void A_Boss2PogoTarget(struct mobj_s *actor);
|
||||
void A_EggmanBox(struct mobj_s *actor);
|
||||
void A_TurretFire(struct mobj_s *actor);
|
||||
void A_SuperTurretFire(struct mobj_s *actor);
|
||||
void A_TurretStop(struct mobj_s *actor);
|
||||
void A_JetJawRoam(struct mobj_s *actor);
|
||||
void A_JetJawChomp(struct mobj_s *actor);
|
||||
void A_PointyThink(struct mobj_s *actor);
|
||||
void A_CheckBuddy(struct mobj_s *actor);
|
||||
void A_HoodThink(struct mobj_s *actor);
|
||||
void A_ArrowCheck(struct mobj_s *actor);
|
||||
void A_SnailerThink(struct mobj_s *actor);
|
||||
void A_SharpChase(struct mobj_s *actor);
|
||||
void A_SharpSpin(struct mobj_s *actor);
|
||||
void A_VultureVtol(struct mobj_s *actor);
|
||||
void A_VultureCheck(struct mobj_s *actor);
|
||||
void A_SkimChase(struct mobj_s *actor);
|
||||
void A_SkullAttack(struct mobj_s *actor);
|
||||
void A_LobShot(struct mobj_s *actor);
|
||||
void A_FireShot(struct mobj_s *actor);
|
||||
void A_SuperFireShot(struct mobj_s *actor);
|
||||
void A_BossFireShot(struct mobj_s *actor);
|
||||
void A_Boss7FireMissiles(struct mobj_s *actor);
|
||||
void A_Boss1Laser(struct mobj_s *actor);
|
||||
void A_FocusTarget(struct mobj_s *actor);
|
||||
void A_Boss4Reverse(struct mobj_s *actor);
|
||||
void A_Boss4SpeedUp(struct mobj_s *actor);
|
||||
void A_Boss4Raise(struct mobj_s *actor);
|
||||
void A_SparkFollow(struct mobj_s *actor);
|
||||
void A_BuzzFly(struct mobj_s *actor);
|
||||
void A_GuardChase(struct mobj_s *actor);
|
||||
void A_EggShield(struct mobj_s *actor);
|
||||
void A_SetReactionTime(struct mobj_s *actor);
|
||||
void A_Boss1Spikeballs(struct mobj_s *actor);
|
||||
void A_Boss3TakeDamage(struct mobj_s *actor);
|
||||
void A_Boss3Path(struct mobj_s *actor);
|
||||
void A_LinedefExecute(struct mobj_s *actor);
|
||||
void A_PlaySeeSound(struct mobj_s *actor);
|
||||
void A_PlayAttackSound(struct mobj_s *actor);
|
||||
void A_PlayActiveSound(struct mobj_s *actor);
|
||||
void A_1upThinker(struct mobj_s *actor);
|
||||
void A_BossZoom(struct mobj_s *actor); //Unused
|
||||
void A_Boss1Chase(struct mobj_s *actor);
|
||||
void A_Boss2Chase(struct mobj_s *actor);
|
||||
void A_Boss2Pogo(struct mobj_s *actor);
|
||||
void A_Boss7Chase(struct mobj_s *actor);
|
||||
void A_BossJetFume(struct mobj_s *actor);
|
||||
void A_SpawnObjectAbsolute(struct mobj_s *actor);
|
||||
void A_SpawnObjectRelative(struct mobj_s *actor);
|
||||
void A_ChangeAngleRelative(struct mobj_s *actor);
|
||||
void A_ChangeAngleAbsolute(struct mobj_s *actor);
|
||||
void A_RollAngle(struct mobj_s *actor);
|
||||
void A_ChangeRollAngleRelative(struct mobj_s *actor);
|
||||
void A_ChangeRollAngleAbsolute(struct mobj_s *actor);
|
||||
void A_PlaySound(struct mobj_s *actor);
|
||||
void A_FindTarget(struct mobj_s *actor);
|
||||
void A_FindTracer(struct mobj_s *actor);
|
||||
void A_SetTics(struct mobj_s *actor);
|
||||
void A_SetRandomTics(struct mobj_s *actor);
|
||||
void A_ChangeColorRelative(struct mobj_s *actor);
|
||||
void A_ChangeColorAbsolute(struct mobj_s *actor);
|
||||
void A_MoveRelative(struct mobj_s *actor);
|
||||
void A_MoveAbsolute(struct mobj_s *actor);
|
||||
void A_Thrust(struct mobj_s *actor);
|
||||
void A_ZThrust(struct mobj_s *actor);
|
||||
void A_SetTargetsTarget(struct mobj_s *actor);
|
||||
void A_SetObjectFlags(struct mobj_s *actor);
|
||||
void A_SetObjectFlags2(struct mobj_s *actor);
|
||||
void A_RandomState(struct mobj_s *actor);
|
||||
void A_RandomStateRange(struct mobj_s *actor);
|
||||
void A_DualAction(struct mobj_s *actor);
|
||||
void A_RemoteAction(struct mobj_s *actor);
|
||||
void A_ToggleFlameJet(struct mobj_s *actor);
|
||||
void A_ItemPop(struct mobj_s *actor); // SRB2kart
|
||||
void A_JawzChase(struct mobj_s *actor); // SRB2kart
|
||||
void A_JawzExplode(struct mobj_s *actor); // SRB2kart
|
||||
void A_SPBChase(struct mobj_s *actor); // SRB2kart
|
||||
void A_MineExplode(struct mobj_s *actor); // SRB2kart
|
||||
void A_BallhogExplode(struct mobj_s *actor); // SRB2kart
|
||||
void A_LightningFollowPlayer(struct mobj_s *actor); // SRB2kart: Lightning shield effect player chasing
|
||||
void A_FZBoomFlash(struct mobj_s *actor); // SRB2kart
|
||||
void A_FZBoomSmoke(struct mobj_s *actor); // SRB2kart
|
||||
void A_RandomShadowFrame(struct mobj_s *actor); //SRB2kart: Shadow spawner frame randomizer
|
||||
void A_RoamingShadowThinker(struct mobj_s *actor); // SRB2kart: Roaming Shadow moving + attacking players.
|
||||
void A_MayonakaArrow(struct mobj_s *actor); //SRB2kart: midnight channel arrow sign
|
||||
void A_ReaperThinker(struct mobj_s *actor); //SRB2kart: mementos reaper
|
||||
void A_MementosTPParticles(struct mobj_s *actor); //SRB2kart: mementos teleporter particles. Man that's a lot of actions for my shite.
|
||||
void A_FlameParticle(struct mobj_s *actor); // SRB2kart
|
||||
void A_OrbitNights(struct mobj_s *actor);
|
||||
void A_GhostMe(struct mobj_s *actor);
|
||||
void A_SetObjectState(struct mobj_s *actor);
|
||||
void A_SetObjectTypeState(struct mobj_s *actor);
|
||||
void A_KnockBack(struct mobj_s *actor);
|
||||
void A_PushAway(struct mobj_s *actor);
|
||||
void A_RingDrain(struct mobj_s *actor);
|
||||
void A_SplitShot(struct mobj_s *actor);
|
||||
void A_MissileSplit(struct mobj_s *actor);
|
||||
void A_MultiShot(struct mobj_s *actor);
|
||||
void A_InstaLoop(struct mobj_s *actor);
|
||||
void A_Custom3DRotate(struct mobj_s *actor);
|
||||
void A_SearchForPlayers(struct mobj_s *actor);
|
||||
void A_CheckRandom(struct mobj_s *actor);
|
||||
void A_CheckTargetRings(struct mobj_s *actor);
|
||||
void A_CheckRings(struct mobj_s *actor);
|
||||
void A_CheckTotalRings(struct mobj_s *actor);
|
||||
void A_CheckHealth(struct mobj_s *actor);
|
||||
void A_CheckRange(struct mobj_s *actor);
|
||||
void A_CheckHeight(struct mobj_s *actor);
|
||||
void A_CheckTrueRange(struct mobj_s *actor);
|
||||
void A_CheckThingCount(struct mobj_s *actor);
|
||||
void A_CheckAmbush(struct mobj_s *actor);
|
||||
void A_CheckCustomValue(struct mobj_s *actor);
|
||||
void A_CheckCusValMemo(struct mobj_s *actor);
|
||||
void A_SetCustomValue(struct mobj_s *actor);
|
||||
void A_UseCusValMemo(struct mobj_s *actor);
|
||||
void A_RelayCustomValue(struct mobj_s *actor);
|
||||
void A_CusValAction(struct mobj_s *actor);
|
||||
void A_ForceStop(struct mobj_s *actor);
|
||||
void A_ForceWin(struct mobj_s *actor);
|
||||
void A_SpikeRetract(struct mobj_s *actor);
|
||||
void A_InfoState(struct mobj_s *actor);
|
||||
void A_Repeat(struct mobj_s *actor);
|
||||
void A_SetScale(struct mobj_s *actor);
|
||||
void A_RemoteDamage(struct mobj_s *actor);
|
||||
void A_HomingChase(struct mobj_s *actor);
|
||||
void A_TrapShot(struct mobj_s *actor);
|
||||
void A_VileTarget(struct mobj_s *actor);
|
||||
void A_VileAttack(struct mobj_s *actor);
|
||||
void A_VileFire(struct mobj_s *actor);
|
||||
void A_BrakChase(struct mobj_s *actor);
|
||||
void A_BrakFireShot(struct mobj_s *actor);
|
||||
void A_BrakLobShot(struct mobj_s *actor);
|
||||
void A_NapalmScatter(struct mobj_s *actor);
|
||||
void A_SpawnFreshCopy(struct mobj_s *actor);
|
||||
|
||||
extern boolean actionsoverridden[NUMACTIONS];
|
||||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#define NUMMOBJFREESLOTS 1024
|
||||
|
||||
@@ -0,0 +1,403 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by AJ "Tyron" Martinez.
|
||||
// Copyright (C) 2024 by James Robert Roman.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_director.c
|
||||
/// \brief SRB2kart automatic spectator camera.
|
||||
|
||||
//#include "k_kart.h"
|
||||
#include "doomdef.h"
|
||||
#include "g_game.h"
|
||||
#include "v_video.h"
|
||||
#include "k_director.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "p_local.h"
|
||||
|
||||
#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches
|
||||
#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart?
|
||||
#define TRANSFERTIME TICRATE // how long to delay reaction shots?
|
||||
#define BREAKAWAYDIST 2000 // how *far* until players considered far apart?
|
||||
#define WALKBACKDIST 600 // how close should a trailing player be before we switch?
|
||||
#define PINCHDIST 20000 // how close should the leader be to be considered "end of race"?
|
||||
|
||||
struct directorinfo
|
||||
{
|
||||
tic_t cooldown; // how long has it been since we last switched?
|
||||
tic_t freeze; // when nonzero, fixed switch pending, freeze logic!
|
||||
INT32 attacker; // who to switch to when freeze delay elapses
|
||||
INT32 maxdist; // how far is the closest player from finishing?
|
||||
|
||||
INT32 sortedplayers[MAXPLAYERS]; // position-1 goes in, player index comes out.
|
||||
INT32 gap[MAXPLAYERS]; // gap between a given position and their closest pursuer
|
||||
INT32 boredom[MAXPLAYERS]; // how long has a given position had no credible attackers?
|
||||
} directorinfo;
|
||||
|
||||
static inline boolean race_rules(void)
|
||||
{
|
||||
return gametype == GT_RACE;
|
||||
}
|
||||
|
||||
static fixed_t ScaleFromMap(fixed_t n, fixed_t scale)
|
||||
{
|
||||
return FixedMul(n, FixedDiv(scale, mapobjectscale));
|
||||
}
|
||||
|
||||
static boolean K_DirectorIsEnabled(void)
|
||||
{
|
||||
return cv_director.value && !splitscreen && (gamestate == GS_LEVEL && (!playeringame[consoleplayer] || players[consoleplayer].spectator || (demo.playback && (!demo.title || !modeattacking))));
|
||||
}
|
||||
|
||||
void K_InitDirector(void)
|
||||
{
|
||||
INT32 playernum;
|
||||
|
||||
directorinfo.cooldown = SWITCHTIME;
|
||||
directorinfo.freeze = 0;
|
||||
directorinfo.attacker = 0;
|
||||
directorinfo.maxdist = 0;
|
||||
|
||||
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
|
||||
{
|
||||
directorinfo.sortedplayers[playernum] = -1;
|
||||
directorinfo.gap[playernum] = INT32_MAX;
|
||||
directorinfo.boredom[playernum] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static fixed_t K_GetDistanceToFinish(player_t player)
|
||||
{
|
||||
mobj_t *mo;
|
||||
fixed_t dist = 0;
|
||||
INT16 maxMoveCount = -1;
|
||||
INT16 maxAngle = -1;
|
||||
|
||||
if (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE))
|
||||
{
|
||||
for (mo = waypointcap; mo != NULL; mo = mo->tracer)
|
||||
{
|
||||
if (mo->spawnpoint->angle != 0)
|
||||
continue;
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(mo->x - player.mo->x,
|
||||
mo->y - player.mo->y),
|
||||
mo->z - player.mo->z) / FRACUNIT;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // crappy optimization weeeee
|
||||
{
|
||||
for (mo = waypointcap; mo != NULL; mo = mo->tracer)
|
||||
{
|
||||
if (mo->movecount > maxMoveCount)
|
||||
maxMoveCount = mo->movecount;
|
||||
if (mo->spawnpoint->angle > maxAngle)
|
||||
maxAngle = mo->spawnpoint->angle;
|
||||
|
||||
if (!(mo->movecount == maxMoveCount && mo->spawnpoint->angle == maxAngle)) // sprint maps finishline waypoint is the one with highest movecount AND angle
|
||||
continue;
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(mo->x - player.mo->x,
|
||||
mo->y - player.mo->y),
|
||||
mo->z - player.mo->z) / FRACUNIT;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
static fixed_t K_GetFinishGap(INT32 leader, INT32 follower)
|
||||
{
|
||||
fixed_t dista = K_GetDistanceToFinish(players[follower]);
|
||||
fixed_t distb = K_GetDistanceToFinish(players[leader]);
|
||||
|
||||
if (players[follower].kartstuff[k_position] < players[leader].kartstuff[k_position])
|
||||
{
|
||||
return distb - dista;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dista - distb;
|
||||
}
|
||||
}
|
||||
|
||||
static void K_UpdateDirectorPositions(void)
|
||||
{
|
||||
INT32 playernum;
|
||||
INT32 position;
|
||||
player_t* target;
|
||||
|
||||
memset(directorinfo.sortedplayers, -1, sizeof(directorinfo.sortedplayers));
|
||||
|
||||
for (playernum = 0; playernum < MAXPLAYERS; playernum++)
|
||||
{
|
||||
target = &players[playernum];
|
||||
|
||||
if (playeringame[playernum] && !target->spectator && target->kartstuff[k_position] > 0)
|
||||
{
|
||||
directorinfo.sortedplayers[target->kartstuff[k_position] - 1] = playernum;
|
||||
}
|
||||
}
|
||||
|
||||
for (position = 0; position < MAXPLAYERS - 1; position++)
|
||||
{
|
||||
directorinfo.gap[position] = INT32_MAX;
|
||||
|
||||
if (directorinfo.sortedplayers[position] == -1 || directorinfo.sortedplayers[position + 1] == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
directorinfo.gap[position] = ScaleFromMap(K_GetFinishGap(directorinfo.sortedplayers[position], directorinfo.sortedplayers[position + 1]), FRACUNIT);
|
||||
|
||||
if (directorinfo.gap[position] >= BREAKAWAYDIST)
|
||||
{
|
||||
directorinfo.boredom[position] = (INT32)(min(BOREDOMTIME * 2, directorinfo.boredom[position] + 1));
|
||||
}
|
||||
else if (directorinfo.boredom[position] > 0)
|
||||
{
|
||||
directorinfo.boredom[position]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (directorinfo.sortedplayers[0] == -1)
|
||||
{
|
||||
directorinfo.maxdist = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
directorinfo.maxdist = ScaleFromMap(K_GetDistanceToFinish(players[directorinfo.sortedplayers[0]]), FRACUNIT);
|
||||
}
|
||||
|
||||
static boolean K_CanSwitchDirector(void)
|
||||
{
|
||||
if (directorinfo.cooldown > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void K_DirectorSwitch(INT32 player, boolean force)
|
||||
{
|
||||
if (!K_DirectorIsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_IsDisplayPlayer(&players[player]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (players[player].exiting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!force && !K_CanSwitchDirector())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
G_ResetView(1, player, true);
|
||||
directorinfo.cooldown = SWITCHTIME;
|
||||
}
|
||||
|
||||
static void K_DirectorForceSwitch(INT32 player, INT32 time)
|
||||
{
|
||||
if (players[player].exiting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
directorinfo.attacker = player;
|
||||
directorinfo.freeze = time;
|
||||
}
|
||||
|
||||
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||
{
|
||||
if (!K_DirectorIsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!P_IsDisplayPlayer(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inflictor && inflictor->player)
|
||||
{
|
||||
K_DirectorForceSwitch(inflictor->player - players, TRANSFERTIME);
|
||||
}
|
||||
else if (source && source->player)
|
||||
{
|
||||
K_DirectorForceSwitch(source->player - players, TRANSFERTIME);
|
||||
}
|
||||
}
|
||||
|
||||
void K_DrawDirectorDebugger(void)
|
||||
{
|
||||
INT32 position;
|
||||
INT32 leader;
|
||||
INT32 follower;
|
||||
INT32 ytxt;
|
||||
|
||||
if (!cv_kartdebugdirector.value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
V_DrawThinString(10, 0, V_70TRANS, va("PLACE"));
|
||||
V_DrawThinString(40, 0, V_70TRANS, va("CONF?"));
|
||||
V_DrawThinString(80, 0, V_70TRANS, va("GAP"));
|
||||
V_DrawThinString(120, 0, V_70TRANS, va("BORED"));
|
||||
V_DrawThinString(150, 0, V_70TRANS, va("COOLDOWN: %d", directorinfo.cooldown));
|
||||
V_DrawThinString(230, 0, V_70TRANS, va("MAXDIST: %d", directorinfo.maxdist));
|
||||
|
||||
for (position = 0; position < MAXPLAYERS - 1; position++)
|
||||
{
|
||||
ytxt = 10 * (position + 1);
|
||||
leader = directorinfo.sortedplayers[position];
|
||||
follower = directorinfo.sortedplayers[position + 1];
|
||||
|
||||
if (leader == -1 || follower == -1)
|
||||
break;
|
||||
|
||||
V_DrawThinString(10, ytxt, V_70TRANS, va("%d", position));
|
||||
V_DrawThinString(20, ytxt, V_70TRANS, va("%d", position + 1));
|
||||
|
||||
if (players[leader].kartstuff[k_positiondelay])
|
||||
{
|
||||
V_DrawThinString(40, ytxt, V_70TRANS, va("NG"));
|
||||
}
|
||||
|
||||
V_DrawThinString(80, ytxt, V_70TRANS, va("%d", directorinfo.gap[position]));
|
||||
|
||||
if (directorinfo.boredom[position] >= BOREDOMTIME)
|
||||
{
|
||||
V_DrawThinString(120, ytxt, V_70TRANS, va("BORED"));
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawThinString(120, ytxt, V_70TRANS, va("%d", directorinfo.boredom[position]));
|
||||
}
|
||||
|
||||
V_DrawThinString(150, ytxt, V_70TRANS, va("%s", player_names[leader]));
|
||||
V_DrawThinString(230, ytxt, V_70TRANS, va("%s", player_names[follower]));
|
||||
}
|
||||
}
|
||||
|
||||
void K_UpdateDirector(void)
|
||||
{
|
||||
INT32 *displayplayerp = &displayplayers[0];
|
||||
INT32 targetposition;
|
||||
|
||||
if (!K_DirectorIsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
K_UpdateDirectorPositions();
|
||||
|
||||
if (directorinfo.cooldown > 0) {
|
||||
directorinfo.cooldown--;
|
||||
}
|
||||
|
||||
// handle pending forced switches
|
||||
if (directorinfo.freeze > 0)
|
||||
{
|
||||
if (!(--directorinfo.freeze))
|
||||
K_DirectorSwitch(directorinfo.attacker, true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if there's only one player left in the list, just switch to that player
|
||||
if (directorinfo.sortedplayers[0] != -1 && (directorinfo.sortedplayers[1] == -1 ||
|
||||
// TODO: Battle; I just threw this together quick. Focus on leader.
|
||||
!race_rules()))
|
||||
{
|
||||
K_DirectorSwitch(directorinfo.sortedplayers[0], false);
|
||||
return;
|
||||
}
|
||||
|
||||
// aaight, time to walk through the standings to find the first interesting pair
|
||||
// NB: targetposition/sortedplayers is 0-indexed, aiming at the "back half" of a given pair by default.
|
||||
// we adjust for this when comparing to player->position or when looking at the leading player, Don't Freak Out
|
||||
for (targetposition = 1; targetposition < MAXPLAYERS; targetposition++)
|
||||
{
|
||||
INT32 target;
|
||||
|
||||
// you are out of players, try again
|
||||
if (directorinfo.sortedplayers[targetposition] == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// pair too far apart? try the next one
|
||||
if (directorinfo.boredom[targetposition - 1] >= BOREDOMTIME)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// pair finished? try the next one
|
||||
if (players[directorinfo.sortedplayers[targetposition]].exiting)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't risk switching away from forward pairs at race end, might miss something!
|
||||
if (directorinfo.maxdist > PINCHDIST)
|
||||
{
|
||||
// if the "next" player is close enough, they should be able to see everyone fine!
|
||||
// walk back through the standings to find a vantage that gets everyone in frame.
|
||||
// (also creates a pretty cool effect w/ overtakes at speed)
|
||||
while (targetposition < MAXPLAYERS && directorinfo.gap[targetposition] < WALKBACKDIST)
|
||||
{
|
||||
targetposition++;
|
||||
}
|
||||
}
|
||||
|
||||
target = directorinfo.sortedplayers[targetposition];
|
||||
|
||||
// stop here since we're already viewing this player
|
||||
if (*displayplayerp == target)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// if we're certain the back half of the pair is actually in this position, try to switch
|
||||
if (!players[target].kartstuff[k_positiondelay])
|
||||
{
|
||||
K_DirectorSwitch(target, false);
|
||||
}
|
||||
|
||||
// even if we're not certain, if we're certain we're watching the WRONG player, try to switch
|
||||
if (players[*displayplayerp].kartstuff[k_position] != targetposition+1 && !players[*displayplayerp].kartstuff[k_positiondelay])
|
||||
{
|
||||
K_DirectorSwitch(target, false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void K_ToggleDirector(void)
|
||||
{
|
||||
if (!K_DirectorIsEnabled())
|
||||
{
|
||||
directorinfo.cooldown = 0; // switch immediately
|
||||
}
|
||||
|
||||
COM_ImmedExecute("add director 1");
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by AJ "Tyron" Martinez.
|
||||
// Copyright (C) 2024 by James Robert Roman.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_director.h
|
||||
/// \brief SRB2kart automatic spectator camera.
|
||||
|
||||
void K_InitDirector(void);
|
||||
void K_UpdateDirector(void);
|
||||
void K_DrawDirectorDebugger(void);
|
||||
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||
void K_ToggleDirector(void);
|
||||
+268
-165
@@ -16,6 +16,7 @@
|
||||
#include "m_random.h"
|
||||
#include "m_menu.h" // ffdhidshfuisduifigergho9igj89dgodhfih AAAAAAAAAA
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_slopes.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_draw.h"
|
||||
@@ -31,12 +32,14 @@
|
||||
#include "z_zone.h"
|
||||
#include "m_misc.h"
|
||||
#include "m_cond.h"
|
||||
#include "k_director.h"
|
||||
#include "k_kart.h"
|
||||
#include "f_finale.h"
|
||||
#include "lua_hud.h" // For Lua hud checks
|
||||
#include "lua_hook.h" // For MobjDamage and ShouldDamage
|
||||
#include "d_main.h" // found_extra_kart
|
||||
|
||||
|
||||
#include "i_video.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
@@ -74,6 +77,7 @@ IMPL_HUD_OFFSET(stat); // Stats
|
||||
//extra hud things
|
||||
consvar_t cv_showstats = {"showstats", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_showinput = {"showinput", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_showlaptimes = {"showlaptimes", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
CV_PossibleValue_t speedo_cons_t[NUMSPEEDOSTUFF];
|
||||
consvar_t cv_newspeedometer = {"newspeedometer", "Default", CV_SAVE, speedo_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -84,7 +88,7 @@ consvar_t cv_saltyhopsfx = {"hardcodehopsfx", "On", CV_SAVE, CV_OnOff, NULL, 0,
|
||||
consvar_t cv_saltysquish = {"hardcodehopsquish", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
//Colourized HUD
|
||||
consvar_t cv_colorizedhud = {"colorizedhud", "Off", CV_SAVE|CV_CALL, CV_OnOff, Saturn_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_colorizedhud = {"colorizedhud", "Off", CV_SAVE|CV_CALL, CV_OnOff, SaturnHud_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_colorizeditembox = {"colorizeditembox", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t HudColor_cons_t[MAXSKINCOLORS+1];
|
||||
@@ -613,10 +617,8 @@ UINT8 K_GetKartColorByName(const char *name)
|
||||
|
||||
UINT8 K_GetHudColor(void)
|
||||
{
|
||||
if (cv_colorizedhud.value){
|
||||
if (cv_colorizedhudcolor.value) return cv_colorizedhudcolor.value;
|
||||
}
|
||||
if (stplyr && P_IsLocalPlayer(stplyr) && gamestate == GS_LEVEL) return stplyr->skincolor;
|
||||
if (cv_colorizedhud.value && cv_colorizedhudcolor.value) return cv_colorizedhudcolor.value;
|
||||
|
||||
return ((stplyr && gamestate == GS_LEVEL) ? stplyr->skincolor : cv_playercolor.value);
|
||||
}
|
||||
|
||||
@@ -678,6 +680,7 @@ void K_RegisterKartStuff(void)
|
||||
CV_RegisterVar(&cv_kartgametypepreference);
|
||||
CV_RegisterVar(&cv_kartspeedometer);
|
||||
CV_RegisterVar(&cv_kartvoices);
|
||||
CV_RegisterVar(&cv_karthitemdialog);
|
||||
CV_RegisterVar(&cv_karteliminatelast);
|
||||
CV_RegisterVar(&cv_votetime);
|
||||
|
||||
@@ -720,6 +723,7 @@ void K_RegisterKartStuff(void)
|
||||
|
||||
CV_RegisterVar(&cv_showstats);
|
||||
CV_RegisterVar(&cv_showinput);
|
||||
CV_RegisterVar(&cv_showlaptimes);
|
||||
CV_RegisterVar(&cv_newspeedometer);
|
||||
|
||||
CV_RegisterVar(&cv_battlespeedo);
|
||||
@@ -1896,6 +1900,31 @@ static void K_RegularVoiceTimers(player_t *player)
|
||||
player->kartstuff[k_tauntvoices] = 4*TICRATE;
|
||||
}
|
||||
|
||||
static void K_PlayGenericCombatSound(mobj_t *source, mobj_t *other, sfxenum_t sfx_id)
|
||||
{
|
||||
skin_t *skin = NULL;
|
||||
|
||||
// I HATE LOCALSKINS! I HATE LOCALSKINS! :AAAAAAAAAA:
|
||||
if (source->player)
|
||||
{
|
||||
INT32 skinnum = source->player->skinlocal ? (source->player->localskin - 1) : source->player->skin;
|
||||
skin = &(source->player->skinlocal ? localskins : skins)[skinnum];
|
||||
}
|
||||
|
||||
if (!skin)
|
||||
return;
|
||||
|
||||
boolean alwaysHear = false;
|
||||
|
||||
if (other != NULL && P_MobjWasRemoved(other) == false && other->player != NULL)
|
||||
alwaysHear = P_IsDisplayPlayer(other->player);
|
||||
|
||||
if (cv_kartvoices.value)
|
||||
S_StartSound(alwaysHear ? NULL : source, skin->soundsid[S_sfx[sfx_id].skinsound]);
|
||||
|
||||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
|
||||
void K_PlayAttackTaunt(mobj_t *source)
|
||||
{
|
||||
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
|
||||
@@ -1944,10 +1973,34 @@ void K_PlayOvertakeSound(mobj_t *source)
|
||||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
|
||||
void K_PlayHitEmSound(mobj_t *source)
|
||||
static boolean K_SetDelayedHitEm(player_t *player, player_t *victim)
|
||||
{
|
||||
player_t *prevvictim = NULL;
|
||||
|
||||
if (player->hitemtimer)
|
||||
prevvictim = &players[player->hitemvictim];
|
||||
|
||||
// We prioritize local players to hear "hit em" sfx
|
||||
if (prevvictim && P_IsDisplayPlayer(prevvictim) && !P_IsDisplayPlayer(victim))
|
||||
return false;
|
||||
|
||||
player->hitemtimer = TICRATE/2;
|
||||
player->hitemvictim = victim - players;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void K_PlayHitEmSound(mobj_t *source, mobj_t *victim)
|
||||
{
|
||||
if (cv_kartvoices.value)
|
||||
{
|
||||
if (cv_karthitemdialog.value
|
||||
&& source->player && victim && victim->player
|
||||
&& K_SetDelayedHitEm(source->player, victim->player))
|
||||
return; // Don't call K_RegularVoiceTimers yet, we didn't do any sound
|
||||
|
||||
S_StartSound(source, sfx_khitem);
|
||||
}
|
||||
else
|
||||
S_StartSound(source, sfx_s1c9); // The only lost gameplay functionality with voices disabled
|
||||
|
||||
@@ -1962,6 +2015,33 @@ void K_PlayPowerGloatSound(mobj_t *source)
|
||||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
|
||||
static void K_HandleDelayedHitByEm(player_t *player)
|
||||
{
|
||||
if (player->hitemtimer == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player->hitemtimer--;
|
||||
|
||||
if (player->hitemtimer == 0)
|
||||
{
|
||||
mobj_t *victim = NULL;
|
||||
|
||||
if (player->hitemvictim < MAXPLAYERS && playeringame[player->hitemvictim])
|
||||
{
|
||||
player_t *victimPlayer = &players[player->hitemvictim];
|
||||
|
||||
if (victimPlayer != NULL && victimPlayer->spectator == false)
|
||||
{
|
||||
victim = victimPlayer->mo;
|
||||
}
|
||||
}
|
||||
|
||||
K_PlayGenericCombatSound(player->mo, victim, sfx_khitem);
|
||||
}
|
||||
}
|
||||
|
||||
void K_MomentumToFacing(player_t *player)
|
||||
{
|
||||
angle_t dangle = player->mo->angle - R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
|
||||
@@ -2233,6 +2313,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
|
||||
// PS: Inflictor is unused for all purposes here and is actually only ever relevant to Lua. It may be nil too.
|
||||
boolean force = false; // Used to check if Lua ShouldSpin should get us damaged reguardless of flashtics or heck knows what.
|
||||
UINT8 shouldForce = LUAh_ShouldSpin(player, inflictor, source);
|
||||
|
||||
if (P_MobjWasRemoved(player->mo))
|
||||
return; // mobj was removed (in theory that shouldn't happen)
|
||||
if (shouldForce == 1)
|
||||
@@ -2240,6 +2321,8 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
|
||||
else if (shouldForce == 2)
|
||||
return;
|
||||
|
||||
K_DirectorFollowAttack(player, inflictor, source);
|
||||
|
||||
if (!trapitem && G_BattleGametype())
|
||||
{
|
||||
if (K_IsPlayerWanted(player))
|
||||
@@ -2266,7 +2349,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
|
||||
return;
|
||||
|
||||
if (source && source != player->mo && source->player)
|
||||
K_PlayHitEmSound(source);
|
||||
K_PlayHitEmSound(source, player->mo);
|
||||
|
||||
//player->kartstuff[k_sneakertimer] = 0;
|
||||
player->kartstuff[k_driftboost] = 0;
|
||||
@@ -2466,7 +2549,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor)
|
||||
if (player->mo->state != &states[S_KART_SQUISH]) // Squash
|
||||
P_SetPlayerMobjState(player->mo, S_KART_SQUISH);
|
||||
|
||||
P_PlayRinglossSound(player->mo);
|
||||
P_PlayRinglossSound(player->mo, source);
|
||||
|
||||
player->kartstuff[k_instashield] = 15;
|
||||
if (cv_kartdebughuddrop.value && !modeattacking)
|
||||
@@ -2490,6 +2573,8 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
|
||||
else if (shouldForce == 2)
|
||||
return;
|
||||
|
||||
K_DirectorFollowAttack(player, inflictor, source);
|
||||
|
||||
if (G_BattleGametype())
|
||||
{
|
||||
if (K_IsPlayerWanted(player))
|
||||
@@ -2516,7 +2601,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
|
||||
return;
|
||||
|
||||
if (source && source != player->mo && source->player)
|
||||
K_PlayHitEmSound(source);
|
||||
K_PlayHitEmSound(source, player->mo);
|
||||
|
||||
player->kartstuff[k_sneakertimer] = 0;
|
||||
player->kartstuff[k_driftboost] = 0;
|
||||
@@ -2597,7 +2682,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
|
||||
if (player->mo->state != &states[S_KART_SPIN])
|
||||
P_SetPlayerMobjState(player->mo, S_KART_SPIN);
|
||||
|
||||
P_PlayRinglossSound(player->mo);
|
||||
P_PlayRinglossSound(player->mo, source);
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
{
|
||||
@@ -4406,6 +4491,7 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
if (!player->mo->hnext)
|
||||
{
|
||||
player->kartstuff[k_bananadrag] = 0;
|
||||
|
||||
if (player->kartstuff[k_eggmanheld])
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
else if (player->kartstuff[k_itemheld])
|
||||
@@ -4421,6 +4507,7 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
|
||||
P_SetTarget(&player->mo->hnext, NULL);
|
||||
player->kartstuff[k_bananadrag] = 0;
|
||||
|
||||
if (player->kartstuff[k_eggmanheld])
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
else if (player->kartstuff[k_itemheld])
|
||||
@@ -4915,23 +5002,14 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
||||
static void K_UpdateInvincibilitySounds(player_t *player)
|
||||
{
|
||||
INT32 sfxnum = sfx_None;
|
||||
boolean localplayer = P_IsLocalPlayer(player);
|
||||
|
||||
if (player->mo->health > 0 && !P_IsLocalPlayer(player))
|
||||
if (player->mo->health > 0)
|
||||
{
|
||||
if (cv_kartinvinsfx.value)
|
||||
{
|
||||
if (player->kartstuff[k_growshrinktimer] > 0) // Prioritize Grow
|
||||
sfxnum = sfx_alarmg;
|
||||
else if (player->kartstuff[k_invincibilitytimer] > 0)
|
||||
sfxnum = sfx_alarmi;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player->kartstuff[k_growshrinktimer] > 0)
|
||||
sfxnum = sfx_kgrow;
|
||||
else if (player->kartstuff[k_invincibilitytimer] > 0)
|
||||
sfxnum = sfx_kinvnc;
|
||||
}
|
||||
if (player->kartstuff[k_growshrinktimer] > 0 && (!localplayer || cv_growmusic.value == 2)) // Prioritize Grow
|
||||
sfxnum = cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow;
|
||||
else if (player->kartstuff[k_invincibilitytimer] > 0 && (!localplayer || cv_supermusic.value == 2))
|
||||
sfxnum = cv_kartinvinsfx.value ? sfx_alarmi : sfx_kinvnc;
|
||||
}
|
||||
|
||||
if (sfxnum != sfx_None && !S_SoundPlaying(player->mo, sfxnum))
|
||||
@@ -5276,6 +5354,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
// Roulette Code
|
||||
K_KartItemRoulette(player, cmd);
|
||||
|
||||
// Used when karthitemdialog is On
|
||||
K_HandleDelayedHitByEm(player);
|
||||
|
||||
// Handle invincibility sfx
|
||||
K_UpdateInvincibilitySounds(player); // Also thanks, VAda!
|
||||
|
||||
@@ -5993,7 +6074,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||
P_SetScale(overlay, player->mo->scale);
|
||||
}
|
||||
player->kartstuff[k_invincibilitytimer] = itemtime+(2*TICRATE); // 10 seconds
|
||||
if (P_IsLocalPlayer(player) && cv_supermusic.value && cv_birdmusic.value)
|
||||
if (P_IsLocalPlayer(player) && cv_supermusic.value == 1 && cv_birdmusic.value)
|
||||
S_ChangeMusicSpecial("kinvnc");
|
||||
else
|
||||
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmi : sfx_kinvnc));
|
||||
@@ -6198,7 +6279,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
|
||||
player->mo->destscale = (6*player->mo->destscale)/8;
|
||||
player->kartstuff[k_growshrinktimer] = itemtime+(4*TICRATE); // 12 seconds
|
||||
if (P_IsLocalPlayer(player) && cv_growmusic.value && cv_birdmusic.value )
|
||||
if (P_IsLocalPlayer(player) && cv_growmusic.value == 1 && cv_birdmusic.value )
|
||||
S_ChangeMusicSpecial("kgrow");
|
||||
else
|
||||
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow));
|
||||
@@ -7507,55 +7588,55 @@ static void K_initKartHUD(void)
|
||||
|
||||
if (splitscreen) // Splitscreen
|
||||
{
|
||||
ITEM_X = 5 + cv_item_xoffset.value;
|
||||
ITEM_Y = 3 + cv_item_yoffset.value;
|
||||
ITEM_X = 5;
|
||||
ITEM_Y = 3;
|
||||
|
||||
LAPS_Y = (BASEVIDHEIGHT/2)-24 + cv_laps_yoffset.value;
|
||||
LAPS_Y = (BASEVIDHEIGHT/2)-24;
|
||||
|
||||
POSI_Y = (BASEVIDHEIGHT/2)- 2 + cv_posi_yoffset.value;
|
||||
POSI_Y = (BASEVIDHEIGHT/2)- 2;
|
||||
|
||||
STCD_Y = BASEVIDHEIGHT/4 + cv_stcd_yoffset.value;
|
||||
STCD_Y = BASEVIDHEIGHT/4;
|
||||
|
||||
MINI_Y = (BASEVIDHEIGHT/2) + cv_mini_yoffset.value;
|
||||
MINI_Y = (BASEVIDHEIGHT/2);
|
||||
|
||||
if (splitscreen > 1) // 3P/4P Small Splitscreen
|
||||
{
|
||||
// 1P (top left)
|
||||
ITEM_X = -9 + cv_item_xoffset.value;
|
||||
ITEM_Y = -8 + cv_item_yoffset.value;
|
||||
ITEM_X = -9;
|
||||
ITEM_Y = -8;
|
||||
|
||||
LAPS_X = 3 + cv_laps_xoffset.value;
|
||||
LAPS_Y = (BASEVIDHEIGHT/2)-13 + cv_laps_yoffset.value;
|
||||
LAPS_X = 3;
|
||||
LAPS_Y = (BASEVIDHEIGHT/2)-13;
|
||||
|
||||
POSI_X = 24 + cv_posi_xoffset.value;
|
||||
POSI_Y = (BASEVIDHEIGHT/2)- 16 + cv_posi_yoffset.value;
|
||||
POSI_X = 24;
|
||||
POSI_Y = (BASEVIDHEIGHT/2)- 16;
|
||||
|
||||
// 2P (top right)
|
||||
ITEM2_X = BASEVIDWIDTH-39 + cv_item_xoffset.value;
|
||||
ITEM2_Y = -8 + cv_item_yoffset.value;
|
||||
ITEM2_X = BASEVIDWIDTH-39;
|
||||
ITEM2_Y = -8;
|
||||
|
||||
LAPS2_X = BASEVIDWIDTH-3 + cv_laps_xoffset.value;
|
||||
LAPS2_Y = (BASEVIDHEIGHT/2)-13 + cv_laps_yoffset.value;
|
||||
LAPS2_X = BASEVIDWIDTH-3;
|
||||
LAPS2_Y = (BASEVIDHEIGHT/2)-13;
|
||||
|
||||
POSI2_X = BASEVIDWIDTH -4 + cv_posi_xoffset.value;
|
||||
POSI2_Y = (BASEVIDHEIGHT/2)- 16 + cv_posi_yoffset.value;
|
||||
POSI2_X = BASEVIDWIDTH -4;
|
||||
POSI2_Y = (BASEVIDHEIGHT/2)- 16;
|
||||
|
||||
// Reminder that 3P and 4P are just 1P and 2P splitscreen'd to the bottom.
|
||||
|
||||
STCD_X = BASEVIDWIDTH/4 + cv_stcd_xoffset.value;
|
||||
STCD_X = BASEVIDWIDTH/4;
|
||||
|
||||
MINI_X = (3*BASEVIDWIDTH/4) + cv_mini_xoffset.value;
|
||||
MINI_Y = (3*BASEVIDHEIGHT/4) + cv_mini_yoffset.value;
|
||||
MINI_X = (3*BASEVIDWIDTH/4);
|
||||
MINI_Y = (3*BASEVIDHEIGHT/4);
|
||||
|
||||
if (splitscreen > 2) // 4P-only
|
||||
{
|
||||
MINI_X = (BASEVIDWIDTH/2) + cv_mini_xoffset.value;
|
||||
MINI_Y = (BASEVIDHEIGHT/2) + cv_mini_yoffset.value;
|
||||
MINI_X = (BASEVIDWIDTH/2);
|
||||
MINI_Y = (BASEVIDHEIGHT/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timeinmap > 113)
|
||||
if (timeinmap > 113 || forceshowhud)
|
||||
hudtrans = cv_translucenthud.value;
|
||||
else if (timeinmap > 105)
|
||||
hudtrans = ((((INT32)timeinmap) - 105)*cv_translucenthud.value)/(113-105);
|
||||
@@ -7710,49 +7791,6 @@ static void K_drawKartStats(void)
|
||||
|
||||
if (!LUA_HudEnabled(hud_statdisplay))
|
||||
return;
|
||||
|
||||
// I tried my best, but this is still mess :/
|
||||
if (splitscreen)
|
||||
{
|
||||
if (splitscreen == 1)
|
||||
{
|
||||
// If we are in 2-player splitscreen, for player 1 we move hud to up and remove snapping
|
||||
// to bottom
|
||||
if (splitnum == 0)
|
||||
{
|
||||
y /= 2;
|
||||
flags = V_SNAPTOLEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can move it down a bit
|
||||
y += 20;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// In 4-player splitscreen...
|
||||
flags = 0;
|
||||
|
||||
// ...For players 2 and 4, which are at right side, we move x coordinate...
|
||||
if (splitnum == 1 || splitnum == 3)
|
||||
x += BASEVIDWIDTH/2;
|
||||
// ...Else, for players on left side we can snap position to left...
|
||||
else
|
||||
flags |= V_SNAPTOLEFT;
|
||||
|
||||
// ...For players 1 and 2, which are at top side, we move y coordinate...
|
||||
if (splitnum == 0 || splitnum == 1)
|
||||
y /= 2;
|
||||
// ...Else, for players on bottom side we can snap position to bottom
|
||||
else
|
||||
{
|
||||
flags |= V_SNAPTOBOTTOM;
|
||||
// Can move it down a bit
|
||||
y += 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Internal offset for speedometer
|
||||
if (cv_kartspeedometer.value)
|
||||
@@ -7764,10 +7802,49 @@ static void K_drawKartStats(void)
|
||||
}
|
||||
else
|
||||
spdoffset = 0;
|
||||
|
||||
|
||||
// Customizations c:
|
||||
x += 18 + cv_stat_xoffset.value;
|
||||
y += cv_stat_yoffset.value + (G_BattleGametype() ? (stplyr->kartstuff[k_bumper] ? -5 : -8) : 0) + spdoffset;
|
||||
if (!splitscreen)
|
||||
{
|
||||
x += 18 + cv_stat_xoffset.value;
|
||||
y += cv_stat_yoffset.value + (G_BattleGametype() ? (stplyr->kartstuff[k_bumper] ? -5 : -8) : 0) + spdoffset;
|
||||
}
|
||||
else if (splitscreen == 1) // I tried my best, but this is still mess :/ < :Blobcatpats: c:
|
||||
{
|
||||
x -= 10;
|
||||
y -= 40;
|
||||
y += (G_BattleGametype() ? (stplyr->kartstuff[k_bumper] ? -5 : -8) : 0);
|
||||
|
||||
// If we are in 2-player splitscreen, for player 1 we move hud to up and remove snapping
|
||||
// to bottom
|
||||
if (splitnum == 0)
|
||||
{
|
||||
y /= 2;
|
||||
flags = V_SNAPTOLEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can move it down a bit
|
||||
y += 45;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (splitnum == 0 || splitnum == 2) // If we are P1 or P3...
|
||||
{
|
||||
// ye i just align it to position number lol
|
||||
x = POSI_X + 19;
|
||||
y = POSI_Y - 6;
|
||||
flags = V_SNAPTOLEFT|((splitnum == 2) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
|
||||
}
|
||||
else // else, that means we're P2 or P4.
|
||||
{
|
||||
x = POSI2_X - 75;
|
||||
y = POSI2_Y - 6;
|
||||
flags = V_SNAPTORIGHT|((splitnum == 3) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
|
||||
}
|
||||
}
|
||||
|
||||
flags |= V_HUDTRANS;
|
||||
|
||||
skin_t *fakeskin;
|
||||
@@ -8111,8 +8188,6 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
||||
{
|
||||
// TIME_X = BASEVIDWIDTH-124; // 196
|
||||
// TIME_Y = 6; // 6
|
||||
|
||||
tic_t worktime;
|
||||
|
||||
INT32 splitflags = 0;
|
||||
if (!mode)
|
||||
@@ -8137,63 +8212,51 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
||||
|
||||
TX += 33;
|
||||
|
||||
worktime = drawtime/(60*TICRATE);
|
||||
|
||||
if (mode && !drawtime)
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("--'--\"--"));
|
||||
else if (worktime < 100) // 99:99:99 only
|
||||
if (drawtime == UINT32_MAX)
|
||||
;
|
||||
else if (mode && !drawtime)
|
||||
{
|
||||
if ((cv_timelimit.value && G_BattleGametype()) && (!players[consoleplayer].exiting && (leveltime > (timelimitintics + starttime + TICRATE/2)) && cv_overtime.value)) // i hate this so much
|
||||
{
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("OVERTIME"));
|
||||
return;
|
||||
}
|
||||
|
||||
// zero minute
|
||||
if (worktime < 10)
|
||||
{
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("0"));
|
||||
// minutes time 0 __ __
|
||||
V_DrawKartString(TX+12, TY+3, splitflags, va("%d", worktime));
|
||||
}
|
||||
// minutes time 0 __ __
|
||||
else
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("%d", worktime));
|
||||
|
||||
// apostrophe location _'__ __
|
||||
V_DrawKartString(TX+24, TY+3, splitflags, va("'"));
|
||||
|
||||
worktime = (drawtime/TICRATE % 60);
|
||||
|
||||
// zero second _ 0_ __
|
||||
if (worktime < 10)
|
||||
{
|
||||
V_DrawKartString(TX+36, TY+3, splitflags, va("0"));
|
||||
// seconds time _ _0 __
|
||||
V_DrawKartString(TX+48, TY+3, splitflags, va("%d", worktime));
|
||||
}
|
||||
// zero second _ 00 __
|
||||
else
|
||||
V_DrawKartString(TX+36, TY+3, splitflags, va("%d", worktime));
|
||||
|
||||
// quotation mark location _ __"__
|
||||
V_DrawKartString(TX+60, TY+3, splitflags, va("\""));
|
||||
|
||||
worktime = G_TicsToCentiseconds(drawtime);
|
||||
|
||||
// zero tick _ __ 0_
|
||||
if (worktime < 10)
|
||||
{
|
||||
V_DrawKartString(TX+72, TY+3, splitflags, va("0"));
|
||||
// tics _ __ _0
|
||||
V_DrawKartString(TX+84, TY+3, splitflags, va("%d", worktime));
|
||||
}
|
||||
// zero tick _ __ 00
|
||||
else
|
||||
V_DrawKartString(TX+72, TY+3, splitflags, va("%d", worktime));
|
||||
}
|
||||
else if ((drawtime/TICRATE) & 1)
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("99'59\"99"));
|
||||
else
|
||||
{
|
||||
tic_t worktime = drawtime/(60*TICRATE);
|
||||
|
||||
if ((G_BattleGametype() && cv_timelimit.value) && (!players[consoleplayer].exiting && (leveltime > (timelimitintics + starttime + TICRATE/2)) && cv_overtime.value)) // i hate this so much
|
||||
{
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("OVERTIME"));
|
||||
}
|
||||
else if (worktime < 100)
|
||||
{
|
||||
// minutes time 00 __ __
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("%d", worktime/10));
|
||||
V_DrawKartString(TX+12, TY+3, splitflags, va("%d", worktime%10));
|
||||
|
||||
// apostrophe location _'__ __
|
||||
V_DrawKartString(TX+24, TY+3, splitflags, va("'"));
|
||||
|
||||
worktime = (drawtime/TICRATE % 60);
|
||||
|
||||
// seconds time _ 00 __
|
||||
V_DrawKartString(TX+36, TY+3, splitflags, va("%d", worktime/10));
|
||||
V_DrawKartString(TX+48, TY+3, splitflags, va("%d", worktime%10));
|
||||
|
||||
// quotation mark location _ __"__
|
||||
V_DrawKartString(TX+60, TY+3, splitflags, va("\""));
|
||||
|
||||
worktime = G_TicsToCentiseconds(drawtime);
|
||||
|
||||
// tics _ __ 00
|
||||
V_DrawKartString(TX+72, TY+3, splitflags, va("%d", worktime/10));
|
||||
V_DrawKartString(TX+84, TY+3, splitflags, va("%d", worktime%10));
|
||||
}
|
||||
else if ((drawtime/TICRATE) & 1)
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("99'59\"99"));
|
||||
}
|
||||
|
||||
if (emblemmap && (modeattacking || (mode == 1)) && !demo.playback) // emblem time!
|
||||
{
|
||||
@@ -8707,7 +8770,7 @@ static void K_drawKartLaps(void)
|
||||
else
|
||||
V_DrawMappedPatch(fx, fy, V_HUDTRANS|splitflags, kp_lapstickerclr, colormap);
|
||||
}
|
||||
|
||||
|
||||
if (stplyr->exiting)
|
||||
V_DrawKartString(fx+33, fy+3, V_HUDTRANS|splitflags, "FIN");
|
||||
else
|
||||
@@ -8722,7 +8785,7 @@ static void K_drawKartSpeedometer(void)
|
||||
return;
|
||||
|
||||
fixed_t convSpeed = 0;
|
||||
|
||||
|
||||
//KartZ speedo
|
||||
fixed_t fuspeed = 0;
|
||||
INT32 spdpatch = 0;
|
||||
@@ -8860,6 +8923,14 @@ static void K_drawKartBumpersOrKarma(void)
|
||||
fy = info.y;
|
||||
fflags = info.flags;
|
||||
|
||||
if (cv_battlespeedo.value && !splitscreen)
|
||||
{
|
||||
if ((cv_newspeedometer.value == 2 && xtra_speedo) || (cv_newspeedometer.value == 3 && achi_speedo) || (cv_newspeedometer.value == 5 && xtra_speedo3))
|
||||
fy += 5;
|
||||
else
|
||||
fy += 7;
|
||||
}
|
||||
|
||||
if (splitscreen > 1)
|
||||
{
|
||||
if (stplyr->kartstuff[k_bumper] <= 0)
|
||||
@@ -8996,11 +9067,11 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe
|
||||
offset = FixedMul(FINETANGENT(((aimingangle+ANGLE_90)>>ANGLETOFINESHIFT) & 4095), xres);
|
||||
// this isn't fovtan... what am i even doing anymore
|
||||
if (splitscreen == 1)
|
||||
offset = 17*offset/10;
|
||||
// OpenGL with software perspective is miscentered on non-16:10 resolutions
|
||||
offset = 17*offset/120;
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
offset = FixedMul(offset, FixedDiv(104857, FixedDiv(xres, yres)));
|
||||
// OpenGL with software perspective is miscentered on non-16:10 resolutions
|
||||
//if (rendermode == render_opengl)
|
||||
//offset = FixedMul(offset, FixedDiv(104857, FixedDiv(xres, yres)));
|
||||
#endif
|
||||
// thanks fickle
|
||||
offset = FixedDiv(offset, fovratio);
|
||||
@@ -9023,12 +9094,14 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe
|
||||
int splitindex = stplyrnum;
|
||||
|
||||
// adjust coords for splitscreen
|
||||
if (splitscreen == 1){ // 2P
|
||||
if (splitscreen == 1) // 2P
|
||||
{
|
||||
y = y>>1;
|
||||
if (splitindex)
|
||||
y = y + yres;
|
||||
}
|
||||
if (splitscreen >= 2) { // 3P or 4P
|
||||
if (splitscreen >= 2) // 3P or 4P
|
||||
{
|
||||
x = x>>1;
|
||||
y = y>>1;
|
||||
if (splitindex & 1)
|
||||
@@ -9297,9 +9370,17 @@ static void K_drawDriftGauge(void)
|
||||
0, 31, 47, 63, 79, 95, 111, 119, 127, 143, 159, 175, 183, 191, 199, 207, 223, 247
|
||||
};
|
||||
|
||||
if (!stplyr->mo || !stplyr->kartstuff[k_drift] || (!splitscreen && !camera->chase))
|
||||
if (!stplyr->mo || (!splitscreen && !camera->chase))
|
||||
return;
|
||||
|
||||
if (forceshowhud)
|
||||
goto skipcrap; // i will skip the drift early return and you cant stop me!
|
||||
|
||||
if (!stplyr->kartstuff[k_drift])
|
||||
return;
|
||||
|
||||
skipcrap:
|
||||
|
||||
if (!K_GetScreenCoords(&pos, stplyr, stplyr->mo, FixedMul(cv_driftgaugeofs.value, cv_driftgaugeofs.value > 0 ? stplyr->mo->scale : mapobjectscale), false))
|
||||
return;
|
||||
|
||||
@@ -9352,9 +9433,7 @@ static void K_drawDriftGauge(void)
|
||||
{
|
||||
cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
V_DrawFill(barx, bary+dup*1+dup*i, BAR_WIDTH, dup, (driftrainbow[(leveltime % 18) + 1] + i*2) | V_NOSCALESTART|drifttrans);
|
||||
}
|
||||
V_DrawFill(barx, bary+dup*1+dup*i, BAR_WIDTH, dup, (driftrainbow[min((leveltime % 18) + 1, 18 - 1)] + i*2) | V_NOSCALESTART|drifttrans);
|
||||
}
|
||||
else // none/blue/red
|
||||
{
|
||||
@@ -9679,7 +9758,9 @@ static void K_drawKartMinimap(void)
|
||||
splitflags = info.flags;
|
||||
|
||||
|
||||
if (timeinmap > 105)
|
||||
if (forceshowhud)
|
||||
minimaptrans = cv_kartminimap.value;
|
||||
else if (timeinmap > 105)
|
||||
{
|
||||
minimaptrans = cv_kartminimap.value;
|
||||
if (timeinmap <= 113)
|
||||
@@ -10492,9 +10573,27 @@ void K_drawKartHUD(void)
|
||||
// If not splitscreen, draw...
|
||||
if (!splitscreen && !demo.title)
|
||||
{
|
||||
tic_t realtime = stplyr->realtime;
|
||||
|
||||
if (cv_showlaptimes.value
|
||||
&& stplyr->kartstuff[k_lapanimation]
|
||||
&& !stplyr->exiting
|
||||
&& stplyr->laptime[LAP_LAST] != 0
|
||||
&& !midgamejoin)
|
||||
{
|
||||
if ((stplyr->kartstuff[k_lapanimation] / 5) & 1)
|
||||
{
|
||||
realtime = stplyr->laptime[LAP_LAST];
|
||||
}
|
||||
else
|
||||
{
|
||||
realtime = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the timestamp
|
||||
if (LUA_HudEnabled(hud_time))
|
||||
K_drawKartTimestamp(stplyr->realtime, TIME_X, TIME_Y, gamemap, 0);
|
||||
K_drawKartTimestamp(realtime, TIME_X, TIME_Y, gamemap, 0);
|
||||
|
||||
if (!modeattacking)
|
||||
{
|
||||
@@ -10521,6 +10620,7 @@ void K_drawKartHUD(void)
|
||||
if (demo.title) // Draw title logo instead in demo.titles
|
||||
{
|
||||
INT32 x = (BASEVIDWIDTH - 32)*FRACUNIT, y = 128*FRACUNIT, offs;
|
||||
INT32 logoflags = V_SNAPTORIGHT|V_SNAPTOBOTTOM;
|
||||
|
||||
if (splitscreen == 3)
|
||||
{
|
||||
@@ -10539,8 +10639,8 @@ void K_drawKartHUD(void)
|
||||
x += offs - frac;
|
||||
}
|
||||
|
||||
V_DrawSciencePatch(x - (54*FRACUNIT), y, 0, W_CachePatchName("TTKBANNR", PU_CACHE), FRACUNIT/4);
|
||||
V_DrawSciencePatch(x - (54*FRACUNIT), y + (25*FRACUNIT), 0, W_CachePatchName("TTKART", PU_CACHE), FRACUNIT/4);
|
||||
V_DrawSciencePatch(x - (54*FRACUNIT), y, logoflags, W_CachePatchName("TTKBANNR", PU_CACHE), FRACUNIT/4);
|
||||
V_DrawSciencePatch(x - (54*FRACUNIT), y + (25*FRACUNIT), logoflags, W_CachePatchName("TTKART", PU_CACHE), FRACUNIT/4);
|
||||
}
|
||||
else if (G_RaceGametype()) // Race-only elements
|
||||
{
|
||||
@@ -10636,6 +10736,9 @@ void K_drawKartHUD(void)
|
||||
if (cv_kartdebugcheckpoint.value)
|
||||
K_drawCheckpointDebugger();
|
||||
|
||||
if (cv_kartdebugdirector.value)
|
||||
K_DrawDirectorDebugger();
|
||||
|
||||
if (cv_kartdebugnodes.value)
|
||||
{
|
||||
UINT8 p;
|
||||
|
||||
+2
-1
@@ -31,6 +31,7 @@ extern consvar_t cv_highresportrait;
|
||||
extern consvar_t cv_stat_xoffset;
|
||||
extern consvar_t cv_stat_yoffset;
|
||||
extern consvar_t cv_showstats;
|
||||
extern consvar_t cv_showlaptimes;
|
||||
extern consvar_t cv_battlespeedo;
|
||||
|
||||
#define NUMSPEEDOSTUFF 6
|
||||
@@ -91,7 +92,7 @@ void K_UpdateSpectateGrief(void);
|
||||
void K_PlayAttackTaunt(mobj_t *source);
|
||||
void K_PlayBoostTaunt(mobj_t *source);
|
||||
void K_PlayOvertakeSound(mobj_t *source);
|
||||
void K_PlayHitEmSound(mobj_t *source);
|
||||
void K_PlayHitEmSound(mobj_t *source, mobj_t *victim);
|
||||
void K_PlayPowerGloatSound(mobj_t *source);
|
||||
|
||||
const char *K_GetItemPatch(UINT8 item, boolean tiny);
|
||||
|
||||
+80
-3
@@ -20,6 +20,7 @@
|
||||
#include "m_random.h"
|
||||
#include "s_sound.h"
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
#include "hu_stuff.h" // HU_AddChatText
|
||||
#include "console.h"
|
||||
#include "k_kart.h" // SRB2Kart
|
||||
@@ -655,7 +656,7 @@ static int lib_pSpawnShadowMobj(lua_State *L)
|
||||
NOHUD
|
||||
if (!caster)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
caster->haveshadow = true;
|
||||
P_SpawnShadowMobj(caster);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1258,6 +1259,7 @@ static int lib_pPlayRinglossSound(lua_State *L)
|
||||
{
|
||||
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
player_t *player = NULL;
|
||||
mobj_t *damager = NULL;
|
||||
NOHUD
|
||||
if (!source)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
@@ -1267,8 +1269,15 @@ static int lib_pPlayRinglossSound(lua_State *L)
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
}
|
||||
if (!lua_isnoneornil(L, 3))
|
||||
{
|
||||
damager = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
||||
if (!damager)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
}
|
||||
if (!player || P_IsLocalPlayer(player))
|
||||
P_PlayRinglossSound(source);
|
||||
P_PlayRinglossSound(source, damager);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2556,10 +2565,22 @@ static int lib_kOvertakeSound(lua_State *L)
|
||||
static int lib_kHitEmSound(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
mobj_t *victim = NULL;
|
||||
|
||||
if (!lua_isnoneornil(L, 2))
|
||||
{
|
||||
victim = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||
if (!victim)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
}
|
||||
|
||||
NOHUD
|
||||
if (!mobj->player)
|
||||
return luaL_error(L, "K_PlayHitEmSound: mobj_t isn't a player object."); //Nothing bad would happen if we let it run the func, but telling why it ain't doing anything is helpful.
|
||||
K_PlayHitEmSound(mobj);
|
||||
if (victim && !victim->player)
|
||||
return luaL_error(L, "K_PlayHitEmSound: mobj_t isn't a player object."); //Same as above
|
||||
|
||||
K_PlayHitEmSound(mobj, victim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3000,6 +3021,58 @@ static int lib_kSetHyuCountdown(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// G_INPUT
|
||||
////////////
|
||||
|
||||
static int lib_gSetPlayerGamepadIndicatorColor(lua_State *L)
|
||||
{
|
||||
INT32 player = -1;
|
||||
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
|
||||
UINT16 color = (UINT16)luaL_checkinteger(L, 2); // skincolor
|
||||
|
||||
for (int i = 0; i < MAXSPLITSCREENPLAYERS; ++i)
|
||||
{
|
||||
if (plr - players == displayplayers[i])
|
||||
{
|
||||
player = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Not a local player
|
||||
if (player == -1) return 0;
|
||||
|
||||
// pls update with color 0 when youre done with changing led stuff so it can get player color again
|
||||
G_SetPlayerGamepadIndicatorColor(player, color);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_gPlayerDeviceRumble(lua_State *L)
|
||||
{
|
||||
INT32 player = -1;
|
||||
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
|
||||
UINT16 low_strength = (UINT16)luaL_checkinteger(L, 2); // low frequency rumble motor strenght
|
||||
UINT16 high_strength = (UINT16)luaL_checkinteger(L, 3); // high frequency rumble motor strenght
|
||||
UINT32 duration = (UINT32)luaL_optinteger(L, 4, 84); // duration of rumble in ms
|
||||
|
||||
for (int i = 0; i < MAXSPLITSCREENPLAYERS; ++i)
|
||||
{
|
||||
if (plr - players == displayplayers[i])
|
||||
{
|
||||
player = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Not a local player
|
||||
if (player == -1) return 0;
|
||||
|
||||
G_PlayerDeviceRumble(player, low_strength, high_strength, duration);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static luaL_Reg lib[] = {
|
||||
{"print", lib_print},
|
||||
{"chatprint", lib_chatprint},
|
||||
@@ -3247,6 +3320,10 @@ static luaL_Reg lib[] = {
|
||||
{"K_SetIndirectItemCooldown",lib_kSetIndirectItemCountdown},
|
||||
{"K_SetHyudoroCooldown",lib_kSetHyuCountdown},
|
||||
|
||||
//g_input
|
||||
{"G_SetPlayerGamepadIndicatorColor",lib_gSetPlayerGamepadIndicatorColor},
|
||||
{"G_PlayerDeviceRumble",lib_gPlayerDeviceRumble},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
+50
-12
@@ -453,9 +453,11 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||
|
||||
if (!(((cvar->flags & CV_HIDEN)) || (cvar->flags & CV_NOSHOWHELP)) && (cvar->PossibleValue || !(cvar->value == 0 && stricmp(cvar->string, "0"))))
|
||||
{
|
||||
char *temp = NULL;
|
||||
|
||||
if (!category)
|
||||
{
|
||||
char *temp = strdup(wadfiles[numwadfiles - 1]->filename);
|
||||
temp = strdup(wadfiles[numwadfiles - 1]->filename);
|
||||
nameonly(temp);
|
||||
|
||||
category = temp;
|
||||
@@ -465,6 +467,8 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||
M_SlotCvarIntoModMenu(cvar, category, menu_name);
|
||||
else
|
||||
M_SlotCvarIntoModMenu(cvar, category, cvar->name);
|
||||
|
||||
free (temp);
|
||||
}
|
||||
|
||||
// return cvar userdata
|
||||
@@ -580,27 +584,59 @@ static luaL_Reg lib[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
enum cvar_e
|
||||
{
|
||||
cvar_name,
|
||||
cvar_defaultvalue,
|
||||
cvar_flags,
|
||||
cvar_value,
|
||||
cvar_string,
|
||||
cvar_changed,
|
||||
};
|
||||
|
||||
static const char *const cvar_opt[] = {
|
||||
"name",
|
||||
"defaultvalue",
|
||||
"flags",
|
||||
"value",
|
||||
"string",
|
||||
"changed",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int cvar_fields_ref = LUA_NOREF;
|
||||
|
||||
static int cvar_get(lua_State *L)
|
||||
{
|
||||
consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR);
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum cvar_e field = Lua_optoption(L, 2, -1, cvar_fields_ref);
|
||||
|
||||
if(fastcmp(field,"name"))
|
||||
switch (field)
|
||||
{
|
||||
case cvar_name:
|
||||
lua_pushstring(L, cvar->name);
|
||||
else if(fastcmp(field,"defaultvalue"))
|
||||
break;
|
||||
case cvar_defaultvalue:
|
||||
lua_pushstring(L, cvar->defaultvalue);
|
||||
else if(fastcmp(field,"flags"))
|
||||
break;
|
||||
case cvar_flags:
|
||||
lua_pushinteger(L, cvar->flags);
|
||||
else if(fastcmp(field,"value"))
|
||||
break;
|
||||
case cvar_value:
|
||||
lua_pushinteger(L, cvar->value);
|
||||
else if(fastcmp(field,"string"))
|
||||
break;
|
||||
case cvar_string:
|
||||
lua_pushstring(L, cvar->string);
|
||||
else if(fastcmp(field,"changed"))
|
||||
break;
|
||||
case cvar_changed:
|
||||
lua_pushboolean(L, cvar->changed);
|
||||
else if (devparm)
|
||||
return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
if (devparm)
|
||||
return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -612,6 +648,8 @@ int LUA_ConsoleLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L,1);
|
||||
|
||||
cvar_fields_ref = Lua_CreateFieldTable(L, cvar_opt);
|
||||
|
||||
// Set empty registry tables
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "COM_Command");
|
||||
|
||||
+4
-1
@@ -55,6 +55,7 @@ enum hook {
|
||||
hook_PlayerCmd, //SRB2KART
|
||||
hook_IntermissionThinker, //SRB2KART
|
||||
hook_VoteThinker, //SRB2KART
|
||||
hook_ServerJoin, // SRB2KART - Saturn 32p
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
@@ -106,8 +107,10 @@ boolean LUAh_PlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source); //
|
||||
boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_ExplodePlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||
boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SquishPlayer. Allows Lua to execute code and/or overwrite its behavior.
|
||||
|
||||
void LUAh_ServerJoin(void); // SRB2KART - Saturn 32p: called by client when joining a server, allows lua to load any sort of config file
|
||||
|
||||
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them.
|
||||
|
||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||
void LUAh_VoteThinker(void); // Hook for Y_VoteTicker
|
||||
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
||||
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
||||
+1032
-811
File diff suppressed because it is too large.
Load diff
+10
-2
@@ -106,6 +106,8 @@ static const char *const hudhook_opt[] = {
|
||||
"vote",
|
||||
NULL};
|
||||
|
||||
static int patch_fields_ref = LUA_NOREF;
|
||||
|
||||
// alignment types for v.drawString
|
||||
enum align {
|
||||
align_left = 0,
|
||||
@@ -229,6 +231,8 @@ static const char *const hud_drawinfo_options[] = {
|
||||
"minimap",
|
||||
NULL};
|
||||
|
||||
static int camera_fields_ref = LUA_NOREF;
|
||||
|
||||
static int lib_getHudInfo(lua_State *L)
|
||||
{
|
||||
UINT32 i;
|
||||
@@ -298,7 +302,7 @@ static int colormap_get(lua_State *L)
|
||||
static int patch_get(lua_State *L)
|
||||
{
|
||||
patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH));
|
||||
enum patch field = luaL_checkoption(L, 2, NULL, patch_opt);
|
||||
enum patch field = Lua_optoption(L, 2, -1, patch_fields_ref);
|
||||
|
||||
// patches are CURRENTLY always valid, expected to be cached with PU_STATIC
|
||||
// this may change in the future, so patch.valid still exists
|
||||
@@ -333,7 +337,7 @@ static int patch_set(lua_State *L)
|
||||
static int camera_get(lua_State *L)
|
||||
{
|
||||
camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA));
|
||||
enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt);
|
||||
enum cameraf field = Lua_optoption(L, 2, -1, camera_fields_ref);
|
||||
|
||||
// cameras should always be valid unless I'm a nutter
|
||||
I_Assert(cam != NULL);
|
||||
@@ -1439,11 +1443,15 @@ int LUA_HudLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
patch_fields_ref = Lua_CreateFieldTable(L, patch_opt);
|
||||
|
||||
luaL_newmetatable(L, META_CAMERA);
|
||||
lua_pushcfunction(L, camera_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L,1);
|
||||
|
||||
camera_fields_ref = Lua_CreateFieldTable(L, camera_opt);
|
||||
|
||||
luaL_register(L, "hud", lib_hud);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ static UINT64 GetItemId(void)
|
||||
return 0;
|
||||
|
||||
// leave bits 0 and 1 free for the string mode
|
||||
UINT64 id = ((uintptr_t)gL->savedpc << 32) | (hud_interpcounter << 10) | (hud_interptag << 2);
|
||||
UINT64 id = ((UINT64)(uintptr_t)gL->savedpc << 32) | (hud_interpcounter << 10) | (hud_interptag << 2);
|
||||
|
||||
if (hud_interplatch)
|
||||
{
|
||||
|
||||
+354
-162
@@ -23,34 +23,10 @@
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // cmd errors
|
||||
|
||||
boolean LUA_CallAction(const char *action, mobj_t *actor);
|
||||
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
|
||||
state_t *astate;
|
||||
|
||||
enum sfxinfo_read {
|
||||
sfxinfor_name = 0,
|
||||
sfxinfor_singular,
|
||||
sfxinfor_priority,
|
||||
sfxinfor_flags, // "pitch"
|
||||
sfxinfor_skinsound
|
||||
};
|
||||
const char *const sfxinfo_ropt[] = {
|
||||
"name",
|
||||
"singular",
|
||||
"priority",
|
||||
"flags",
|
||||
"skinsound",
|
||||
NULL};
|
||||
|
||||
enum sfxinfo_write {
|
||||
sfxinfow_singular = 0,
|
||||
sfxinfow_priority,
|
||||
sfxinfow_flags // "pitch"
|
||||
};
|
||||
const char *const sfxinfo_wopt[] = {
|
||||
"singular",
|
||||
"priority",
|
||||
"flags",
|
||||
NULL};
|
||||
boolean actionsoverridden[NUMACTIONS] = {false};
|
||||
|
||||
//
|
||||
// Sprite Names
|
||||
@@ -101,7 +77,7 @@ static void A_Lua(mobj_t *actor)
|
||||
{
|
||||
boolean found = false;
|
||||
I_Assert(actor != NULL);
|
||||
|
||||
|
||||
lua_settop(gL, 0); // Just in case...
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
@@ -276,27 +252,21 @@ boolean LUA_SetLuaAction(void *stv, const char *action)
|
||||
return true; // action successfully set.
|
||||
}
|
||||
|
||||
boolean LUA_CallAction(const char *csaction, mobj_t *actor)
|
||||
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor)
|
||||
{
|
||||
I_Assert(csaction != NULL);
|
||||
I_Assert(actor != NULL);
|
||||
|
||||
if (!gL) // Lua isn't loaded,
|
||||
if (!actionsoverridden[actionnum]) // The action is not overriden,
|
||||
return false; // action not called.
|
||||
|
||||
if (superstack && fasticmp(csaction, superactions[superstack-1])) // the action is calling itself,
|
||||
return false; // let it call the hardcoded function instead.
|
||||
if (superstack && fasticmp(actionpointers[actionnum].name, superactions[superstack-1])) // the action is calling itself,
|
||||
return false; // let it call the hardcoded function
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
// grab function by uppercase name.
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
|
||||
{
|
||||
char *action = Z_StrDup(csaction);
|
||||
strupr(action);
|
||||
lua_getfield(gL, -1, action);
|
||||
Z_Free(action);
|
||||
}
|
||||
lua_getfield(gL, -1, actionpointers[actionnum].name);
|
||||
lua_remove(gL, -2); // pop LREG_ACTIONS
|
||||
|
||||
if (lua_isnil(gL, -1)) // no match
|
||||
@@ -319,7 +289,7 @@ boolean LUA_CallAction(const char *csaction, mobj_t *actor)
|
||||
lua_pushinteger(gL, var1);
|
||||
lua_pushinteger(gL, var2);
|
||||
|
||||
superactions[superstack] = csaction;
|
||||
superactions[superstack] = actionpointers[actionnum].name;
|
||||
++superstack;
|
||||
|
||||
LUA_Call(gL, 3, 0, -(2 + 3));
|
||||
@@ -330,49 +300,93 @@ boolean LUA_CallAction(const char *csaction, mobj_t *actor)
|
||||
return true; // action successfully called.
|
||||
}
|
||||
|
||||
enum state_e {
|
||||
state_sprite = 0,
|
||||
state_frame,
|
||||
state_tics,
|
||||
state_action,
|
||||
state_var1,
|
||||
state_var2,
|
||||
state_nextstate,
|
||||
};
|
||||
|
||||
const char *const state_opt[] = {
|
||||
"sprite",
|
||||
"frame",
|
||||
"tics",
|
||||
"action",
|
||||
"var1",
|
||||
"var2",
|
||||
"nextstate",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int state_fields_ref = LUA_NOREF;
|
||||
|
||||
// state_t *, field -> number
|
||||
static int state_get(lua_State *L)
|
||||
{
|
||||
state_t *st = *((state_t **)luaL_checkudata(L, 1, META_STATE));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum state_e field = Lua_optoption(L, 2, -1, state_fields_ref);
|
||||
lua_Integer number;
|
||||
|
||||
if (fastcmp(field,"sprite"))
|
||||
number = st->sprite;
|
||||
else if (fastcmp(field,"frame"))
|
||||
number = st->frame;
|
||||
else if (fastcmp(field,"tics"))
|
||||
number = st->tics;
|
||||
else if (fastcmp(field,"action")) {
|
||||
const char *name;
|
||||
if (!st->action.acp1) // Action is NULL.
|
||||
return 0; // return nil.
|
||||
if (st->action.acp1 == (actionf_p1)A_Lua) { // This is a Lua function?
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushlightuserdata(L, st); // Push the state pointer and
|
||||
lua_rawget(L, -2); // use it to get the actual Lua function.
|
||||
lua_remove(L, -2); // pop LREG_STATEACTION
|
||||
return 1; // Return the Lua function.
|
||||
switch (field)
|
||||
{
|
||||
case state_sprite:
|
||||
number = st->sprite;
|
||||
break;
|
||||
|
||||
case state_frame:
|
||||
number = st->frame;
|
||||
break;
|
||||
|
||||
case state_tics:
|
||||
number = st->tics;
|
||||
break;
|
||||
|
||||
case state_action:
|
||||
{
|
||||
const char *name;
|
||||
if (!st->action.acp1) // Action is NULL.
|
||||
return 0; // return nil.
|
||||
if (st->action.acp1 == (actionf_p1)A_Lua) { // This is a Lua function?
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushlightuserdata(L, st); // Push the state pointer and
|
||||
lua_rawget(L, -2); // use it to get the actual Lua function.
|
||||
lua_remove(L, -2); // pop LREG_STATEACTION
|
||||
return 1; // Return the Lua function.
|
||||
}
|
||||
name = LUA_GetActionName(&st->action); // find a hardcoded function name
|
||||
if (!name) // If it's not a hardcoded function and it's not a Lua function...
|
||||
return 0; // Just what is this??
|
||||
// get the function from the global
|
||||
// because the metatable will trigger.
|
||||
lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a new C closure if not.
|
||||
lua_pushstring(L, name); // push the name we found.
|
||||
return 2; // return both the function and its name, in case somebody wanted to do a comparison by name or something?
|
||||
}
|
||||
name = LUA_GetActionName(&st->action); // find a hardcoded function name
|
||||
if (!name) // If it's not a hardcoded function and it's not a Lua function...
|
||||
return 0; // Just what is this??
|
||||
// get the function from the global
|
||||
// because the metatable will trigger.
|
||||
lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a new C closure if not.
|
||||
lua_pushstring(L, name); // push the name we found.
|
||||
return 2; // return both the function and its name, in case somebody wanted to do a comparison by name or something?
|
||||
} else if (fastcmp(field,"var1"))
|
||||
number = st->var1;
|
||||
else if (fastcmp(field,"var2"))
|
||||
number = st->var2;
|
||||
else if (fastcmp(field,"nextstate"))
|
||||
number = st->nextstate;
|
||||
else if (devparm)
|
||||
return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case state_var1:
|
||||
number = st->var1;
|
||||
break;
|
||||
|
||||
case state_var2:
|
||||
number = st->var2;
|
||||
break;
|
||||
|
||||
case state_nextstate:
|
||||
number = st->nextstate;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if (devparm)
|
||||
return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushinteger(L, number);
|
||||
return 1;
|
||||
@@ -382,7 +396,7 @@ static int state_get(lua_State *L)
|
||||
static int state_set(lua_State *L)
|
||||
{
|
||||
state_t *st = *((state_t **)luaL_checkudata(L, 1, META_STATE));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum state_e field = Lua_optoption(L, 2, -1, state_fields_ref);
|
||||
lua_Integer value;
|
||||
|
||||
if (hud_running)
|
||||
@@ -390,16 +404,24 @@ static int state_set(lua_State *L)
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter states in BuildCMD code!");
|
||||
|
||||
if (fastcmp(field,"sprite")) {
|
||||
switch (field)
|
||||
{
|
||||
case state_sprite:
|
||||
value = luaL_checknumber(L, 3);
|
||||
if (value < SPR_NULL || value >= NUMSPRITES)
|
||||
return luaL_error(L, "sprite number %d is invalid.", value);
|
||||
st->sprite = (spritenum_t)value;
|
||||
} else if (fastcmp(field,"frame"))
|
||||
break;
|
||||
|
||||
case state_frame:
|
||||
st->frame = (UINT32)luaL_checknumber(L, 3);
|
||||
else if (fastcmp(field,"tics"))
|
||||
break;
|
||||
|
||||
case state_tics:
|
||||
st->tics = (INT32)luaL_checknumber(L, 3);
|
||||
else if (fastcmp(field,"action")) {
|
||||
break;
|
||||
|
||||
case state_action:
|
||||
switch(lua_type(L, 3))
|
||||
{
|
||||
case LUA_TNIL: // Null? Set the action to nothing, then.
|
||||
@@ -420,17 +442,26 @@ static int state_set(lua_State *L)
|
||||
default: // ?!
|
||||
return luaL_typerror(L, 3, "function");
|
||||
}
|
||||
} else if (fastcmp(field,"var1"))
|
||||
break;
|
||||
|
||||
case state_var1:
|
||||
st->var1 = (INT32)luaL_checknumber(L, 3);
|
||||
else if (fastcmp(field,"var2"))
|
||||
break;
|
||||
|
||||
case state_var2:
|
||||
st->var2 = (INT32)luaL_checknumber(L, 3);
|
||||
else if (fastcmp(field,"nextstate")) {
|
||||
break;
|
||||
|
||||
case state_nextstate:
|
||||
value = luaL_checkinteger(L, 3);
|
||||
if (value < S_NULL || value >= NUMSTATES)
|
||||
return luaL_error(L, "nextstate number %d is invalid.", value);
|
||||
st->nextstate = (statenum_t)value;
|
||||
} else
|
||||
break;
|
||||
|
||||
default:
|
||||
return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -565,75 +596,161 @@ static int lib_mobjinfolen(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum mobjinfo_e
|
||||
{
|
||||
mobjinfo_doomednum,
|
||||
mobjinfo_spawnstate,
|
||||
mobjinfo_spawnhealth,
|
||||
mobjinfo_seestate,
|
||||
mobjinfo_seesound,
|
||||
mobjinfo_reactiontime,
|
||||
mobjinfo_attacksound,
|
||||
mobjinfo_painstate,
|
||||
mobjinfo_painchance,
|
||||
mobjinfo_painsound,
|
||||
mobjinfo_meleestate,
|
||||
mobjinfo_missilestate,
|
||||
mobjinfo_deathstate,
|
||||
mobjinfo_xdeathstate,
|
||||
mobjinfo_deathsound,
|
||||
mobjinfo_speed,
|
||||
mobjinfo_radius,
|
||||
mobjinfo_height,
|
||||
mobjinfo_dispoffset,
|
||||
mobjinfo_mass,
|
||||
mobjinfo_damage,
|
||||
mobjinfo_activesound,
|
||||
mobjinfo_flags,
|
||||
mobjinfo_raisestate,
|
||||
};
|
||||
|
||||
const char *const mobjinfo_opt[] = {
|
||||
"doomednum",
|
||||
"spawnstate",
|
||||
"spawnhealth",
|
||||
"seestate",
|
||||
"seesound",
|
||||
"reactiontime",
|
||||
"attacksound",
|
||||
"painstate",
|
||||
"painchance",
|
||||
"painsound",
|
||||
"meleestate",
|
||||
"missilestate",
|
||||
"deathstate",
|
||||
"xdeathstate",
|
||||
"deathsound",
|
||||
"speed",
|
||||
"radius",
|
||||
"height",
|
||||
"dispoffset",
|
||||
"mass",
|
||||
"damage",
|
||||
"activesound",
|
||||
"flags",
|
||||
"raisestate",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int mobjinfo_fields_ref = LUA_NOREF;
|
||||
|
||||
// mobjinfo_t *, field -> number
|
||||
static int mobjinfo_get(lua_State *L)
|
||||
{
|
||||
mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum mobjinfo_e field = Lua_optoption(L, 2, -1, mobjinfo_fields_ref);
|
||||
|
||||
I_Assert(info != NULL);
|
||||
I_Assert(info >= mobjinfo);
|
||||
|
||||
if (fastcmp(field,"doomednum"))
|
||||
switch (field)
|
||||
{
|
||||
case mobjinfo_doomednum:
|
||||
lua_pushinteger(L, info->doomednum);
|
||||
else if (fastcmp(field,"spawnstate"))
|
||||
break;
|
||||
case mobjinfo_spawnstate:
|
||||
lua_pushinteger(L, info->spawnstate);
|
||||
else if (fastcmp(field,"spawnhealth"))
|
||||
break;
|
||||
case mobjinfo_spawnhealth:
|
||||
lua_pushinteger(L, info->spawnhealth);
|
||||
else if (fastcmp(field,"seestate"))
|
||||
break;
|
||||
case mobjinfo_seestate:
|
||||
lua_pushinteger(L, info->seestate);
|
||||
else if (fastcmp(field,"seesound"))
|
||||
break;
|
||||
case mobjinfo_seesound:
|
||||
lua_pushinteger(L, info->seesound);
|
||||
else if (fastcmp(field,"reactiontime"))
|
||||
break;
|
||||
case mobjinfo_reactiontime:
|
||||
lua_pushinteger(L, info->reactiontime);
|
||||
else if (fastcmp(field,"attacksound"))
|
||||
break;
|
||||
case mobjinfo_attacksound:
|
||||
lua_pushinteger(L, info->attacksound);
|
||||
else if (fastcmp(field,"painstate"))
|
||||
break;
|
||||
case mobjinfo_painstate:
|
||||
lua_pushinteger(L, info->painstate);
|
||||
else if (fastcmp(field,"painchance"))
|
||||
break;
|
||||
case mobjinfo_painchance:
|
||||
lua_pushinteger(L, info->painchance);
|
||||
else if (fastcmp(field,"painsound"))
|
||||
break;
|
||||
case mobjinfo_painsound:
|
||||
lua_pushinteger(L, info->painsound);
|
||||
else if (fastcmp(field,"meleestate"))
|
||||
break;
|
||||
case mobjinfo_meleestate:
|
||||
lua_pushinteger(L, info->meleestate);
|
||||
else if (fastcmp(field,"missilestate"))
|
||||
break;
|
||||
case mobjinfo_missilestate:
|
||||
lua_pushinteger(L, info->missilestate);
|
||||
else if (fastcmp(field,"deathstate"))
|
||||
break;
|
||||
case mobjinfo_deathstate:
|
||||
lua_pushinteger(L, info->deathstate);
|
||||
else if (fastcmp(field,"xdeathstate"))
|
||||
break;
|
||||
case mobjinfo_xdeathstate:
|
||||
lua_pushinteger(L, info->xdeathstate);
|
||||
else if (fastcmp(field,"deathsound"))
|
||||
break;
|
||||
case mobjinfo_deathsound:
|
||||
lua_pushinteger(L, info->deathsound);
|
||||
else if (fastcmp(field,"speed"))
|
||||
break;
|
||||
case mobjinfo_speed:
|
||||
lua_pushinteger(L, info->speed); // sometimes it's fixed_t, sometimes it's not...
|
||||
else if (fastcmp(field,"radius"))
|
||||
break;
|
||||
case mobjinfo_radius:
|
||||
lua_pushfixed(L, info->radius);
|
||||
else if (fastcmp(field,"height"))
|
||||
break;
|
||||
case mobjinfo_height:
|
||||
lua_pushfixed(L, info->height);
|
||||
else if (fastcmp(field,"dispoffset"))
|
||||
break;
|
||||
case mobjinfo_dispoffset:
|
||||
lua_pushinteger(L, info->dispoffset);
|
||||
else if (fastcmp(field,"mass"))
|
||||
break;
|
||||
case mobjinfo_mass:
|
||||
lua_pushinteger(L, info->mass);
|
||||
else if (fastcmp(field,"damage"))
|
||||
break;
|
||||
case mobjinfo_damage:
|
||||
lua_pushinteger(L, info->damage);
|
||||
else if (fastcmp(field,"activesound"))
|
||||
break;
|
||||
case mobjinfo_activesound:
|
||||
lua_pushinteger(L, info->activesound);
|
||||
else if (fastcmp(field,"flags"))
|
||||
break;
|
||||
case mobjinfo_flags:
|
||||
lua_pushinteger(L, info->flags);
|
||||
else if (fastcmp(field,"raisestate"))
|
||||
break;
|
||||
case mobjinfo_raisestate:
|
||||
lua_pushinteger(L, info->raisestate);
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushlightuserdata(L, info);
|
||||
lua_rawget(L, -2);
|
||||
if (!lua_istable(L, -1)) { // no extra values table
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", field);
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", lua_tostring(L, 2));
|
||||
return 0;
|
||||
}
|
||||
lua_getfield(L, -1, field);
|
||||
lua_pushvalue(L, 2); // field name
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isnil(L, -1)) // no value for this field
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", field);
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", lua_tostring(L, 2));
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -642,7 +759,7 @@ static int mobjinfo_get(lua_State *L)
|
||||
static int mobjinfo_set(lua_State *L)
|
||||
{
|
||||
mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum mobjinfo_e field = Lua_optoption(L, 2, -1, mobjinfo_fields_ref);
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!");
|
||||
@@ -652,55 +769,81 @@ static int mobjinfo_set(lua_State *L)
|
||||
I_Assert(info != NULL);
|
||||
I_Assert(info >= mobjinfo);
|
||||
|
||||
if (fastcmp(field,"doomednum"))
|
||||
switch (field)
|
||||
{
|
||||
case mobjinfo_doomednum:
|
||||
info->doomednum = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"spawnstate"))
|
||||
break;
|
||||
case mobjinfo_spawnstate:
|
||||
info->spawnstate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"spawnhealth"))
|
||||
break;
|
||||
case mobjinfo_spawnhealth:
|
||||
info->spawnhealth = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"seestate"))
|
||||
break;
|
||||
case mobjinfo_seestate:
|
||||
info->seestate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"seesound"))
|
||||
break;
|
||||
case mobjinfo_seesound:
|
||||
info->seesound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"reactiontime"))
|
||||
break;
|
||||
case mobjinfo_reactiontime:
|
||||
info->reactiontime = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"attacksound"))
|
||||
break;
|
||||
case mobjinfo_attacksound:
|
||||
info->attacksound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"painstate"))
|
||||
break;
|
||||
case mobjinfo_painstate:
|
||||
info->painstate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"painchance"))
|
||||
break;
|
||||
case mobjinfo_painchance:
|
||||
info->painchance = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"painsound"))
|
||||
break;
|
||||
case mobjinfo_painsound:
|
||||
info->painsound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"meleestate"))
|
||||
break;
|
||||
case mobjinfo_meleestate:
|
||||
info->meleestate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"missilestate"))
|
||||
break;
|
||||
case mobjinfo_missilestate:
|
||||
info->missilestate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"deathstate"))
|
||||
break;
|
||||
case mobjinfo_deathstate:
|
||||
info->deathstate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"xdeathstate"))
|
||||
break;
|
||||
case mobjinfo_xdeathstate:
|
||||
info->xdeathstate = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"deathsound"))
|
||||
break;
|
||||
case mobjinfo_deathsound:
|
||||
info->deathsound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"speed"))
|
||||
break;
|
||||
case mobjinfo_speed:
|
||||
info->speed = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"radius"))
|
||||
break;
|
||||
case mobjinfo_radius:
|
||||
info->radius = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"height"))
|
||||
break;
|
||||
case mobjinfo_height:
|
||||
info->height = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"dispoffset"))
|
||||
break;
|
||||
case mobjinfo_dispoffset:
|
||||
info->dispoffset = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"mass"))
|
||||
break;
|
||||
case mobjinfo_mass:
|
||||
info->mass = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"damage"))
|
||||
break;
|
||||
case mobjinfo_damage:
|
||||
info->damage = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"activesound"))
|
||||
break;
|
||||
case mobjinfo_activesound:
|
||||
info->activesound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"flags"))
|
||||
break;
|
||||
case mobjinfo_flags:
|
||||
info->flags = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"raisestate"))
|
||||
break;
|
||||
case mobjinfo_raisestate:
|
||||
info->raisestate = luaL_checkinteger(L, 3);
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushlightuserdata(L, info);
|
||||
@@ -708,18 +851,17 @@ static int mobjinfo_set(lua_State *L)
|
||||
if (lua_isnil(L, -1)) {
|
||||
// This index doesn't have a table for extra values yet, let's make one.
|
||||
lua_pop(L, 1);
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "mobjinfo_t", field);
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "mobjinfo_t", lua_tostring(L, 2));
|
||||
lua_newtable(L);
|
||||
lua_pushlightuserdata(L, info);
|
||||
lua_pushvalue(L, -2); // ext value table
|
||||
lua_rawset(L, -4); // LREG_EXTVARS table
|
||||
}
|
||||
lua_pushvalue(L, 2); // key
|
||||
lua_pushvalue(L, 3); // value to store
|
||||
lua_setfield(L, -2, field);
|
||||
lua_settable(L, -3);
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
//else
|
||||
//return luaL_error(L, LUA_QL("mobjinfo_t") " has no field named " LUA_QS, field);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -752,6 +894,25 @@ static int lib_getSfxInfo(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum sfxinfo_e {
|
||||
sfxinfo_name = 0,
|
||||
sfxinfo_singular,
|
||||
sfxinfo_priority,
|
||||
sfxinfo_flags, // "pitch"
|
||||
sfxinfo_skinsound
|
||||
};
|
||||
|
||||
const char *const sfxinfo_opt[] = {
|
||||
"name",
|
||||
"singular",
|
||||
"priority",
|
||||
"flags",
|
||||
"skinsound",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int sfxinfo_fields_ref = LUA_NOREF;
|
||||
|
||||
// stack: dummy, S_sfx[] table index, table of values to set.
|
||||
static int lib_setSfxInfo(lua_State *L)
|
||||
{
|
||||
@@ -775,22 +936,44 @@ static int lib_setSfxInfo(lua_State *L)
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1)) {
|
||||
enum sfxinfo_write i;
|
||||
enum sfxinfo_e i;
|
||||
|
||||
if (lua_isnumber(L, 2))
|
||||
i = lua_tointeger(L, 2) - 1; // lua is one based, this enum is zero based.
|
||||
{
|
||||
int j = lua_tointeger(L, 2) - 1;
|
||||
|
||||
// Read and Write enums were combined, need to do this switch now
|
||||
switch (j)
|
||||
{
|
||||
case 1:
|
||||
i = sfxinfo_singular;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
i = sfxinfo_priority;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
i = sfxinfo_flags;
|
||||
break;
|
||||
|
||||
default:
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
i = luaL_checkoption(L, 2, NULL, sfxinfo_wopt);
|
||||
i = Lua_optoption(L, 2, -1, sfxinfo_fields_ref);
|
||||
|
||||
switch(i)
|
||||
{
|
||||
case sfxinfow_singular:
|
||||
case sfxinfo_singular:
|
||||
info->singularity = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case sfxinfow_priority:
|
||||
case sfxinfo_priority:
|
||||
info->priority = (INT32)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case sfxinfow_flags:
|
||||
case sfxinfo_flags:
|
||||
info->pitch = (INT32)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
default:
|
||||
@@ -812,29 +995,29 @@ static int lib_sfxlen(lua_State *L)
|
||||
static int sfxinfo_get(lua_State *L)
|
||||
{
|
||||
sfxinfo_t *sfx = *((sfxinfo_t **)luaL_checkudata(L, 1, META_SFXINFO));
|
||||
enum sfxinfo_read field = luaL_checkoption(L, 2, NULL, sfxinfo_ropt);
|
||||
enum sfxinfo_e field = Lua_optoption(L, 2, -1, sfxinfo_fields_ref);
|
||||
|
||||
I_Assert(sfx != NULL);
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case sfxinfor_name:
|
||||
case sfxinfo_name:
|
||||
lua_pushstring(L, sfx->name);
|
||||
return 1;
|
||||
case sfxinfor_singular:
|
||||
case sfxinfo_singular:
|
||||
lua_pushboolean(L, sfx->singularity);
|
||||
return 1;
|
||||
case sfxinfor_priority:
|
||||
case sfxinfo_priority:
|
||||
lua_pushinteger(L, sfx->priority);
|
||||
return 1;
|
||||
case sfxinfor_flags:
|
||||
case sfxinfo_flags:
|
||||
lua_pushinteger(L, sfx->pitch);
|
||||
return 1;
|
||||
case sfxinfor_skinsound:
|
||||
case sfxinfo_skinsound:
|
||||
lua_pushinteger(L, sfx->skinsound);
|
||||
return 1;
|
||||
default:
|
||||
return luaL_error(L, "impossible error");
|
||||
return luaL_error(L, LUA_QL("sfxinfo_t") " has no field named " LUA_QS, lua_tostring(L, 2));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -843,7 +1026,7 @@ static int sfxinfo_get(lua_State *L)
|
||||
static int sfxinfo_set(lua_State *L)
|
||||
{
|
||||
sfxinfo_t *sfx = *((sfxinfo_t **)luaL_checkudata(L, 1, META_SFXINFO));
|
||||
enum sfxinfo_write field = luaL_checkoption(L, 2, NULL, sfxinfo_wopt);
|
||||
int field = Lua_optoption(L, 2, -1, sfxinfo_fields_ref);
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter S_sfx in HUD rendering code!");
|
||||
@@ -858,17 +1041,20 @@ static int sfxinfo_set(lua_State *L)
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case sfxinfow_singular:
|
||||
case sfxinfo_singular:
|
||||
sfx->singularity = luaL_checkboolean(L, 1);
|
||||
break;
|
||||
case sfxinfow_priority:
|
||||
case sfxinfo_priority:
|
||||
sfx->priority = luaL_checkinteger(L, 1);
|
||||
break;
|
||||
case sfxinfow_flags:
|
||||
case sfxinfo_flags:
|
||||
sfx->pitch = luaL_checkinteger(L, 1);
|
||||
break;
|
||||
default:
|
||||
return luaL_error(L, "impossible error");
|
||||
if (field == -1)
|
||||
return luaL_error(L, LUA_QL("sfxinfo_t") " has no field named " LUA_QS, lua_tostring(L, 2));
|
||||
else
|
||||
return luaL_error(L, LUA_QL("sfxinfo_t") " field " LUA_QS " is read-only", lua_tostring(L, 2));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -910,6 +1096,8 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
state_fields_ref = Lua_CreateFieldTable(L, state_opt);
|
||||
|
||||
luaL_newmetatable(L, META_MOBJINFO);
|
||||
lua_pushcfunction(L, mobjinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -921,6 +1109,8 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
mobjinfo_fields_ref = Lua_CreateFieldTable(L, mobjinfo_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SFXINFO);
|
||||
lua_pushcfunction(L, sfxinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -932,6 +1122,8 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
sfxinfo_fields_ref = Lua_CreateFieldTable(L, sfxinfo_opt);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSprname);
|
||||
@@ -983,4 +1175,4 @@ int LUA_InfoLib(lua_State *L)
|
||||
lua_setglobal(L, "S_sfx");
|
||||
lua_setglobal(L, "sfxinfo");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+193
-49
@@ -71,6 +71,8 @@ enum subsector_e {
|
||||
subsector_firstline,
|
||||
};
|
||||
|
||||
static int sector_fields_ref = LUA_NOREF;
|
||||
|
||||
static const char *const subsector_opt[] = {
|
||||
"valid",
|
||||
"sector",
|
||||
@@ -78,6 +80,8 @@ static const char *const subsector_opt[] = {
|
||||
"firstline",
|
||||
NULL};
|
||||
|
||||
static int subsector_fields_ref = LUA_NOREF;
|
||||
|
||||
enum line_e {
|
||||
line_valid = 0,
|
||||
line_v1,
|
||||
@@ -120,6 +124,8 @@ static const char *const line_opt[] = {
|
||||
"callcount",
|
||||
NULL};
|
||||
|
||||
static int line_fields_ref = LUA_NOREF;
|
||||
|
||||
enum side_e {
|
||||
side_valid = 0,
|
||||
side_textureoffset,
|
||||
@@ -146,6 +152,8 @@ static const char *const side_opt[] = {
|
||||
"text",
|
||||
NULL};
|
||||
|
||||
static int side_fields_ref = LUA_NOREF;
|
||||
|
||||
enum vertex_e {
|
||||
vertex_valid = 0,
|
||||
vertex_x,
|
||||
@@ -160,6 +168,8 @@ static const char *const vertex_opt[] = {
|
||||
"z",
|
||||
NULL};
|
||||
|
||||
static int vertex_fields_ref = LUA_NOREF;
|
||||
|
||||
enum ffloor_e {
|
||||
ffloor_valid = 0,
|
||||
ffloor_topheight,
|
||||
@@ -196,6 +206,8 @@ static const char *const ffloor_opt[] = {
|
||||
"alpha",
|
||||
NULL};
|
||||
|
||||
static int ffloor_fields_ref = LUA_NOREF;
|
||||
|
||||
enum slope_e {
|
||||
slope_valid = 0,
|
||||
slope_o,
|
||||
@@ -222,6 +234,8 @@ static const char *const slope_opt[] = {
|
||||
"flags",
|
||||
NULL};
|
||||
|
||||
static int slope_fields_ref = LUA_NOREF;
|
||||
|
||||
// shared by both vector2_t and vector3_t
|
||||
enum vector_e {
|
||||
vector_x = 0,
|
||||
@@ -387,7 +401,7 @@ static int sectorlines_num(lua_State *L)
|
||||
static int sector_get(lua_State *L)
|
||||
{
|
||||
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
|
||||
enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt);
|
||||
enum sector_e field = Lua_optoption(L, 2, sector_valid, sector_fields_ref);
|
||||
INT16 i;
|
||||
|
||||
if (!sector)
|
||||
@@ -473,7 +487,7 @@ static int sector_get(lua_State *L)
|
||||
static int sector_set(lua_State *L)
|
||||
{
|
||||
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
|
||||
enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt);
|
||||
enum sector_e field = Lua_optoption(L, 2, sector_valid, sector_fields_ref);
|
||||
|
||||
if (!sector)
|
||||
return luaL_error(L, "accessed sector_t doesn't exist anymore.");
|
||||
@@ -551,7 +565,7 @@ static int sector_num(lua_State *L)
|
||||
static int subsector_get(lua_State *L)
|
||||
{
|
||||
subsector_t *subsector = *((subsector_t **)luaL_checkudata(L, 1, META_SUBSECTOR));
|
||||
enum subsector_e field = luaL_checkoption(L, 2, subsector_opt[0], subsector_opt);
|
||||
enum subsector_e field = Lua_optoption(L, 2, subsector_valid, subsector_fields_ref);
|
||||
|
||||
if (!subsector)
|
||||
{
|
||||
@@ -590,7 +604,7 @@ static int subsector_num(lua_State *L)
|
||||
static int line_get(lua_State *L)
|
||||
{
|
||||
line_t *line = *((line_t **)luaL_checkudata(L, 1, META_LINE));
|
||||
enum line_e field = luaL_checkoption(L, 2, line_opt[0], line_opt);
|
||||
enum line_e field = Lua_optoption(L, 2, line_valid, line_fields_ref);
|
||||
|
||||
if (!line)
|
||||
{
|
||||
@@ -715,7 +729,7 @@ static int sidenum_get(lua_State *L)
|
||||
static int side_get(lua_State *L)
|
||||
{
|
||||
side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE));
|
||||
enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt);
|
||||
enum side_e field = Lua_optoption(L, 2, side_valid, side_fields_ref);
|
||||
|
||||
if (!side)
|
||||
{
|
||||
@@ -765,7 +779,7 @@ static int side_get(lua_State *L)
|
||||
static int side_set(lua_State *L)
|
||||
{
|
||||
side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE));
|
||||
enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt);
|
||||
enum side_e field = Lua_optoption(L, 2, side_valid, side_fields_ref);
|
||||
|
||||
if (!side)
|
||||
{
|
||||
@@ -816,7 +830,7 @@ static int side_num(lua_State *L)
|
||||
static int vertex_get(lua_State *L)
|
||||
{
|
||||
vertex_t *vertex = *((vertex_t **)luaL_checkudata(L, 1, META_VERTEX));
|
||||
enum vertex_e field = luaL_checkoption(L, 2, vertex_opt[0], vertex_opt);
|
||||
enum vertex_e field = Lua_optoption(L, 2, vertex_valid, vertex_fields_ref);
|
||||
|
||||
if (!vertex)
|
||||
{
|
||||
@@ -1085,7 +1099,7 @@ static int lib_numvertexes(lua_State *L)
|
||||
static int ffloor_get(lua_State *L)
|
||||
{
|
||||
ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
|
||||
enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt);
|
||||
enum ffloor_e field = Lua_optoption(L, 2, ffloor_valid, ffloor_fields_ref);
|
||||
INT16 i;
|
||||
|
||||
if (!ffloor)
|
||||
@@ -1161,7 +1175,7 @@ static int ffloor_get(lua_State *L)
|
||||
static int ffloor_set(lua_State *L)
|
||||
{
|
||||
ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
|
||||
enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt);
|
||||
enum ffloor_e field = Lua_optoption(L, 2, ffloor_valid, ffloor_fields_ref);
|
||||
|
||||
if (!ffloor)
|
||||
return luaL_error(L, "accessed ffloor_t doesn't exist anymore.");
|
||||
@@ -1239,7 +1253,7 @@ static int ffloor_set(lua_State *L)
|
||||
static int slope_get(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt);
|
||||
enum slope_e field = Lua_optoption(L, 2, slope_valid, slope_fields_ref);
|
||||
|
||||
if (!slope)
|
||||
{
|
||||
@@ -1289,7 +1303,7 @@ static int slope_get(lua_State *L)
|
||||
static int slope_set(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt);
|
||||
enum slope_e field = Lua_optoption(L, 2, slope_valid, slope_fields_ref);
|
||||
|
||||
if (!slope)
|
||||
return luaL_error(L, "accessed pslope_t doesn't exist anymore.");
|
||||
@@ -1446,93 +1460,207 @@ static int lib_nummapheaders(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum mapheaderinfo_e
|
||||
{
|
||||
mapheaderinfo_lvlttl,
|
||||
mapheaderinfo_subttl,
|
||||
mapheaderinfo_zonttl,
|
||||
mapheaderinfo_actnum,
|
||||
mapheaderinfo_typeoflevel,
|
||||
mapheaderinfo_nextlevel,
|
||||
mapheaderinfo_musname,
|
||||
mapheaderinfo_mustrack,
|
||||
mapheaderinfo_muspos,
|
||||
mapheaderinfo_musinterfadeout,
|
||||
mapheaderinfo_musintername,
|
||||
mapheaderinfo_forcecharacter,
|
||||
mapheaderinfo_weather,
|
||||
mapheaderinfo_skynum,
|
||||
mapheaderinfo_skybox_scalex,
|
||||
mapheaderinfo_skybox_scaley,
|
||||
mapheaderinfo_skybox_scalez,
|
||||
mapheaderinfo_interscreen,
|
||||
mapheaderinfo_runsoc,
|
||||
mapheaderinfo_scriptname,
|
||||
mapheaderinfo_precutscenenum,
|
||||
mapheaderinfo_cutscenenum,
|
||||
mapheaderinfo_countdown,
|
||||
mapheaderinfo_palette,
|
||||
mapheaderinfo_numlaps,
|
||||
mapheaderinfo_unlockrequired,
|
||||
mapheaderinfo_levelselect,
|
||||
mapheaderinfo_bonustype,
|
||||
mapheaderinfo_saveoverride,
|
||||
mapheaderinfo_levelflags,
|
||||
mapheaderinfo_menuflags,
|
||||
//mapheaderinfo_automap,
|
||||
mapheaderinfo_mobj_scale,
|
||||
};
|
||||
|
||||
static const char *const mapheaderinfo_opt[] = {
|
||||
"lvlttl",
|
||||
"subttl",
|
||||
"zonttl",
|
||||
"actnum",
|
||||
"typeoflevel",
|
||||
"nextlevel",
|
||||
"musname",
|
||||
"mustrack",
|
||||
"muspos",
|
||||
"musinterfadeout",
|
||||
"musintername",
|
||||
"forcecharacter",
|
||||
"weather",
|
||||
"skynum",
|
||||
"skybox_scalex",
|
||||
"skybox_scaley",
|
||||
"skybox_scalez",
|
||||
"interscreen",
|
||||
"runsoc",
|
||||
"scriptname",
|
||||
"precutscenenum",
|
||||
"cutscenenum",
|
||||
"countdown",
|
||||
"palette",
|
||||
"numlaps",
|
||||
"unlockrequired",
|
||||
"levelselect",
|
||||
"bonustype",
|
||||
"saveoverride",
|
||||
"levelflags",
|
||||
"menuflags",
|
||||
//"automap",
|
||||
"mobj_scale",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int mapheaderinfo_fields_ref = LUA_NOREF;
|
||||
|
||||
static int mapheaderinfo_get(lua_State *L)
|
||||
{
|
||||
mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum mapheaderinfo_e field = Lua_optoption(L, 2, -1, mapheaderinfo_fields_ref);
|
||||
INT16 i;
|
||||
if (fastcmp(field,"lvlttl"))
|
||||
switch (field)
|
||||
{
|
||||
case mapheaderinfo_lvlttl:
|
||||
lua_pushstring(L, header->lvlttl);
|
||||
else if (fastcmp(field,"subttl"))
|
||||
break;
|
||||
case mapheaderinfo_subttl:
|
||||
lua_pushstring(L, header->subttl);
|
||||
else if (fastcmp(field,"zonttl"))
|
||||
break;
|
||||
case mapheaderinfo_zonttl:
|
||||
lua_pushstring(L, header->zonttl);
|
||||
else if (fastcmp(field,"actnum"))
|
||||
break;
|
||||
case mapheaderinfo_actnum:
|
||||
lua_pushstring(L, header->actnum);
|
||||
else if (fastcmp(field,"typeoflevel"))
|
||||
break;
|
||||
case mapheaderinfo_typeoflevel:
|
||||
lua_pushinteger(L, header->typeoflevel);
|
||||
else if (fastcmp(field,"nextlevel"))
|
||||
break;
|
||||
case mapheaderinfo_nextlevel:
|
||||
lua_pushinteger(L, header->nextlevel);
|
||||
else if (fastcmp(field,"musname"))
|
||||
break;
|
||||
case mapheaderinfo_musname:
|
||||
lua_pushstring(L, header->musname);
|
||||
else if (fastcmp(field,"mustrack"))
|
||||
break;
|
||||
case mapheaderinfo_mustrack:
|
||||
lua_pushinteger(L, header->mustrack);
|
||||
else if (fastcmp(field,"muspos"))
|
||||
break;
|
||||
case mapheaderinfo_muspos:
|
||||
lua_pushinteger(L, header->muspos);
|
||||
else if (fastcmp(field,"musinterfadeout"))
|
||||
break;
|
||||
case mapheaderinfo_musinterfadeout:
|
||||
lua_pushinteger(L, header->musinterfadeout);
|
||||
else if (fastcmp(field,"musintername"))
|
||||
break;
|
||||
case mapheaderinfo_musintername:
|
||||
lua_pushstring(L, header->musintername);
|
||||
else if (fastcmp(field,"forcecharacter"))
|
||||
break;
|
||||
case mapheaderinfo_forcecharacter:
|
||||
lua_pushstring(L, header->forcecharacter);
|
||||
else if (fastcmp(field,"weather"))
|
||||
break;
|
||||
case mapheaderinfo_weather:
|
||||
lua_pushinteger(L, header->weather);
|
||||
else if (fastcmp(field,"skynum"))
|
||||
break;
|
||||
case mapheaderinfo_skynum:
|
||||
lua_pushinteger(L, header->skynum);
|
||||
else if (fastcmp(field,"skybox_scalex"))
|
||||
break;
|
||||
case mapheaderinfo_skybox_scalex:
|
||||
lua_pushinteger(L, header->skybox_scalex);
|
||||
else if (fastcmp(field,"skybox_scaley"))
|
||||
break;
|
||||
case mapheaderinfo_skybox_scaley:
|
||||
lua_pushinteger(L, header->skybox_scaley);
|
||||
else if (fastcmp(field,"skybox_scalez"))
|
||||
break;
|
||||
case mapheaderinfo_skybox_scalez:
|
||||
lua_pushinteger(L, header->skybox_scalez);
|
||||
else if (fastcmp(field,"interscreen")) {
|
||||
break;
|
||||
case mapheaderinfo_interscreen:
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!header->interscreen[i])
|
||||
break;
|
||||
lua_pushlstring(L, header->interscreen, i);
|
||||
} else if (fastcmp(field,"runsoc"))
|
||||
break;
|
||||
case mapheaderinfo_runsoc:
|
||||
lua_pushstring(L, header->runsoc);
|
||||
else if (fastcmp(field,"scriptname"))
|
||||
break;
|
||||
case mapheaderinfo_scriptname:
|
||||
lua_pushstring(L, header->scriptname);
|
||||
else if (fastcmp(field,"precutscenenum"))
|
||||
break;
|
||||
case mapheaderinfo_precutscenenum:
|
||||
lua_pushinteger(L, header->precutscenenum);
|
||||
else if (fastcmp(field,"cutscenenum"))
|
||||
break;
|
||||
case mapheaderinfo_cutscenenum:
|
||||
lua_pushinteger(L, header->cutscenenum);
|
||||
else if (fastcmp(field,"countdown"))
|
||||
break;
|
||||
case mapheaderinfo_countdown:
|
||||
lua_pushinteger(L, header->countdown);
|
||||
else if (fastcmp(field,"palette"))
|
||||
break;
|
||||
case mapheaderinfo_palette:
|
||||
lua_pushinteger(L, header->palette);
|
||||
else if (fastcmp(field,"numlaps"))
|
||||
break;
|
||||
case mapheaderinfo_numlaps:
|
||||
lua_pushinteger(L, header->numlaps);
|
||||
else if (fastcmp(field,"unlockrequired"))
|
||||
break;
|
||||
case mapheaderinfo_unlockrequired:
|
||||
lua_pushinteger(L, header->unlockrequired);
|
||||
else if (fastcmp(field,"levelselect"))
|
||||
break;
|
||||
case mapheaderinfo_levelselect:
|
||||
lua_pushinteger(L, header->levelselect);
|
||||
else if (fastcmp(field,"bonustype"))
|
||||
break;
|
||||
case mapheaderinfo_bonustype:
|
||||
lua_pushinteger(L, header->bonustype);
|
||||
else if (fastcmp(field,"saveoverride"))
|
||||
break;
|
||||
case mapheaderinfo_saveoverride:
|
||||
lua_pushinteger(L, header->saveoverride);
|
||||
else if (fastcmp(field,"levelflags"))
|
||||
break;
|
||||
case mapheaderinfo_levelflags:
|
||||
lua_pushinteger(L, header->levelflags);
|
||||
else if (fastcmp(field,"menuflags"))
|
||||
break;
|
||||
case mapheaderinfo_menuflags:
|
||||
lua_pushinteger(L, header->menuflags);
|
||||
/*else if (fastcmp(field,"automap"))
|
||||
lua_pushboolean(L, header->automap);*/
|
||||
else if (fastcmp(field,"mobj_scale"))
|
||||
break;
|
||||
/*case mapheaderinfo_automap:
|
||||
lua_pushstring(L, header->selectheading);
|
||||
break;*/
|
||||
case mapheaderinfo_mobj_scale:
|
||||
lua_pushfixed(L, header->mobj_scale);
|
||||
break;
|
||||
// TODO add support for reading numGradedMares and grades
|
||||
else {
|
||||
default:
|
||||
{
|
||||
// Read custom vars now
|
||||
// (note: don't include the "LUA." in your lua scripts!)
|
||||
UINT8 j = 0;
|
||||
for (;j < header->numCustomOptions && !fastcmp(field, header->customopts[j].option); ++j);
|
||||
for (;j < header->numCustomOptions && !fastcmp(lua_tostring(L, 2), header->customopts[j].option); ++j);
|
||||
|
||||
if(j < header->numCustomOptions)
|
||||
lua_pushstring(L, header->customopts[j].value);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int LUA_MapLib(lua_State *L)
|
||||
@@ -1556,6 +1684,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
sector_fields_ref = Lua_CreateFieldTable(L, sector_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SUBSECTOR);
|
||||
lua_pushcfunction(L, subsector_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1564,6 +1694,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
subsector_fields_ref = Lua_CreateFieldTable(L, subsector_opt);
|
||||
|
||||
luaL_newmetatable(L, META_LINE);
|
||||
lua_pushcfunction(L, line_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1572,6 +1704,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
line_fields_ref = Lua_CreateFieldTable(L, line_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SIDENUM);
|
||||
lua_pushcfunction(L, sidenum_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1588,6 +1722,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
side_fields_ref = Lua_CreateFieldTable(L, side_opt);
|
||||
|
||||
luaL_newmetatable(L, META_VERTEX);
|
||||
lua_pushcfunction(L, vertex_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1596,6 +1732,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
vertex_fields_ref = Lua_CreateFieldTable(L, vertex_opt);
|
||||
|
||||
luaL_newmetatable(L, META_FFLOOR);
|
||||
lua_pushcfunction(L, ffloor_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1604,6 +1742,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L, 1);
|
||||
|
||||
ffloor_fields_ref = Lua_CreateFieldTable(L, ffloor_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SLOPE);
|
||||
lua_pushcfunction(L, slope_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1612,6 +1752,8 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L, 1);
|
||||
|
||||
slope_fields_ref = Lua_CreateFieldTable(L, slope_opt);
|
||||
|
||||
luaL_newmetatable(L, META_VECTOR2);
|
||||
lua_pushcfunction(L, vector2_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
@@ -1630,6 +1772,8 @@ int LUA_MapLib(lua_State *L)
|
||||
//lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
mapheaderinfo_fields_ref = Lua_CreateFieldTable(L, mapheaderinfo_opt);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSector);
|
||||
@@ -1690,4 +1834,4 @@ int LUA_MapLib(lua_State *L)
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "mapheaderinfo");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+105
-49
@@ -147,7 +147,7 @@ static const udata_field_t mobj_fields[] = {
|
||||
FIELD(mobj_t, colorized, udatalib_getter_boolean, udatalib_setter_boolean),
|
||||
FIELD(mobj_t, mirrored, udatalib_getter_boolean, udatalib_setter_boolean),
|
||||
FIELD(mobj_t, rollmodel, udatalib_getter_boolean, udatalib_setter_boolean),
|
||||
{ NULL },
|
||||
{ NULL, 0, NULL, NULL },
|
||||
};
|
||||
#undef FIELD
|
||||
|
||||
@@ -769,14 +769,41 @@ static int mobj_set(lua_State *L)
|
||||
#undef NOSETPOS
|
||||
#undef NOFIELD
|
||||
|
||||
enum mapthing_e {
|
||||
mapthing_valid = 0,
|
||||
mapthing_x,
|
||||
mapthing_y,
|
||||
mapthing_angle,
|
||||
mapthing_type,
|
||||
mapthing_options,
|
||||
mapthing_z,
|
||||
mapthing_extrainfo,
|
||||
mapthing_mobj,
|
||||
};
|
||||
|
||||
const char *const mapthing_opt[] = {
|
||||
"valid",
|
||||
"x",
|
||||
"y",
|
||||
"angle",
|
||||
"type",
|
||||
"options",
|
||||
"z",
|
||||
"extrainfo",
|
||||
"mobj",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int mapthing_fields_ref = LUA_NOREF;
|
||||
|
||||
static int mapthing_get(lua_State *L)
|
||||
{
|
||||
mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
lua_Integer number;
|
||||
enum mapthing_e field = Lua_optoption(L, 2, -1, mapthing_fields_ref);
|
||||
lua_settop(L, 2);
|
||||
|
||||
if (!mt) {
|
||||
if (fastcmp(field,"valid")) {
|
||||
if (field == mapthing_valid) {
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
@@ -785,39 +812,50 @@ static int mapthing_get(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fastcmp(field,"valid")) {
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
} else if(fastcmp(field,"x"))
|
||||
number = mt->x;
|
||||
else if(fastcmp(field,"y"))
|
||||
number = mt->y;
|
||||
else if(fastcmp(field,"angle"))
|
||||
number = mt->angle;
|
||||
else if(fastcmp(field,"type"))
|
||||
number = mt->type;
|
||||
else if(fastcmp(field,"options"))
|
||||
number = mt->options;
|
||||
else if(fastcmp(field,"z"))
|
||||
number = mt->z;
|
||||
else if(fastcmp(field,"extrainfo"))
|
||||
number = mt->extrainfo;
|
||||
else if(fastcmp(field,"mobj")) {
|
||||
LUA_PushUserdata(L, mt->mobj, META_MOBJ);
|
||||
return 1;
|
||||
} else if (devparm)
|
||||
return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
switch (field)
|
||||
{
|
||||
case mapthing_valid:
|
||||
lua_pushboolean(L, true);
|
||||
break;
|
||||
case mapthing_x:
|
||||
lua_pushinteger(L, mt->x);
|
||||
break;
|
||||
case mapthing_y:
|
||||
lua_pushinteger(L, mt->y);
|
||||
break;
|
||||
case mapthing_angle:
|
||||
lua_pushinteger(L, mt->angle);
|
||||
break;
|
||||
case mapthing_type:
|
||||
lua_pushinteger(L, mt->type);
|
||||
break;
|
||||
case mapthing_options:
|
||||
lua_pushinteger(L, mt->options);
|
||||
break;
|
||||
case mapthing_z:
|
||||
lua_pushinteger(L, mt->z);
|
||||
break;
|
||||
case mapthing_extrainfo:
|
||||
lua_pushinteger(L, mt->extrainfo);
|
||||
break;
|
||||
case mapthing_mobj:
|
||||
LUA_PushUserdata(L, mt->mobj, META_MOBJ);
|
||||
break;
|
||||
default:
|
||||
if (devparm)
|
||||
return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pushinteger(L, number);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mapthing_set(lua_State *L)
|
||||
{
|
||||
mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum mapthing_e field = Lua_optoption(L, 2, -1, mapthing_fields_ref);
|
||||
lua_settop(L, 3);
|
||||
|
||||
if (!mt)
|
||||
return luaL_error(L, "accessed mapthing_t doesn't exist anymore.");
|
||||
@@ -827,24 +865,40 @@ static int mapthing_set(lua_State *L)
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter mapthing_t in BuildCMD code!");
|
||||
|
||||
if(fastcmp(field,"x"))
|
||||
mt->x = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"y"))
|
||||
mt->y = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"angle"))
|
||||
mt->angle = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"type"))
|
||||
mt->type = (UINT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"options"))
|
||||
mt->options = (UINT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"z"))
|
||||
mt->z = (INT16)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"extrainfo"))
|
||||
mt->extrainfo = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if(fastcmp(field,"mobj"))
|
||||
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
else
|
||||
return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field);
|
||||
switch (field)
|
||||
{
|
||||
case mapthing_x:
|
||||
mt->x = (INT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_y:
|
||||
mt->y = (INT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_angle:
|
||||
mt->angle = (INT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_type:
|
||||
mt->type = (UINT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_options:
|
||||
mt->options = (UINT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_z:
|
||||
mt->z = (INT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mapthing_extrainfo:
|
||||
{
|
||||
INT32 extrainfo = luaL_checkinteger(L, 3);
|
||||
if (extrainfo & ~15)
|
||||
return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15);
|
||||
mt->extrainfo = (UINT8)extrainfo;
|
||||
break;
|
||||
}
|
||||
case mapthing_mobj:
|
||||
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
break;
|
||||
default:
|
||||
return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -915,6 +969,8 @@ int LUA_MobjLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
mapthing_fields_ref = Lua_CreateFieldTable(L, mapthing_opt);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getMapthing);
|
||||
@@ -925,4 +981,4 @@ int LUA_MobjLib(lua_State *L)
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "mapthings");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+81
-18
@@ -51,6 +51,9 @@ int player_localskin_setter(lua_State *L);
|
||||
int player_sliproll_getter(lua_State *L);
|
||||
int player_sliproll_noset(lua_State *L);
|
||||
|
||||
int player_viewrollangle_getter(lua_State *L);
|
||||
int player_viewrollangle_noset(lua_State *L);
|
||||
|
||||
#define FIELD(type, field_name, getter, setter) { #field_name, offsetof(type, field_name), getter, setter }
|
||||
static const udata_field_t player_fields[] = {
|
||||
// Player doesn't actually have field "name" so macro fails. Need to declare field manually.
|
||||
@@ -159,8 +162,9 @@ static const udata_field_t player_fields[] = {
|
||||
#endif
|
||||
// Same as player.name
|
||||
{ "sliproll", 0, player_sliproll_getter, player_sliproll_noset },
|
||||
{ "viewrollangle", 0, player_viewrollangle_getter, player_viewrollangle_noset },
|
||||
{ "ping", 0, player_ping_getter, player_ping_noset }, // Hmm originally setter doesn't exist so data is written as unreachable custom field...
|
||||
{ NULL },
|
||||
{ NULL, 0, NULL, NULL },
|
||||
};
|
||||
#undef FIELD
|
||||
|
||||
@@ -217,6 +221,7 @@ NOSET(bot)
|
||||
NOSET(splitscreenindex)
|
||||
NOSET(ping)
|
||||
NOSET(sliproll)
|
||||
NOSET(viewrollangle)
|
||||
|
||||
#undef NOSET
|
||||
|
||||
@@ -372,6 +377,15 @@ int player_sliproll_getter(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int player_viewrollangle_getter(lua_State *L)
|
||||
{
|
||||
player_t *plr = GETPLAYER();
|
||||
|
||||
lua_pushangle(L, R_ViewRollAngle(plr));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_iteratePlayers(lua_State *L)
|
||||
{
|
||||
INT32 i = -1;
|
||||
@@ -694,30 +708,65 @@ static int kartstuff_len(lua_State *L)
|
||||
}
|
||||
|
||||
#define NOFIELD luaL_error(L, LUA_QL("ticcmd_t") " has no field named " LUA_QS, field)
|
||||
#define NOSET luaL_error(L, LUA_QL("ticcmd_t") " field " LUA_QS " should not be set directly.", field)
|
||||
|
||||
enum ticcmd_e
|
||||
{
|
||||
ticcmd_forwardmove,
|
||||
ticcmd_sidemove,
|
||||
ticcmd_angleturn,
|
||||
ticcmd_aiming,
|
||||
ticcmd_buttons,
|
||||
ticcmd_driftturn,
|
||||
ticcmd_latency,
|
||||
};
|
||||
|
||||
static const char *const ticcmd_opt[] = {
|
||||
"forwardmove",
|
||||
"sidemove",
|
||||
"angleturn",
|
||||
"aiming",
|
||||
"buttons",
|
||||
"driftturn",
|
||||
"latency",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int ticcmd_fields_ref = LUA_NOREF;
|
||||
|
||||
static int ticcmd_get(lua_State *L)
|
||||
{
|
||||
ticcmd_t *cmd = *((ticcmd_t **)luaL_checkudata(L, 1, META_TICCMD));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref);
|
||||
if (!cmd)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
if (fastcmp(field,"forwardmove"))
|
||||
switch (field)
|
||||
{
|
||||
case ticcmd_forwardmove:
|
||||
lua_pushinteger(L, cmd->forwardmove);
|
||||
else if (fastcmp(field,"sidemove"))
|
||||
break;
|
||||
case ticcmd_sidemove:
|
||||
lua_pushinteger(L, cmd->sidemove);
|
||||
else if (fastcmp(field,"angleturn"))
|
||||
break;
|
||||
case ticcmd_angleturn:
|
||||
lua_pushinteger(L, cmd->angleturn);
|
||||
else if (fastcmp(field,"aiming"))
|
||||
break;
|
||||
case ticcmd_aiming:
|
||||
lua_pushinteger(L, cmd->aiming);
|
||||
else if (fastcmp(field,"buttons"))
|
||||
break;
|
||||
case ticcmd_buttons:
|
||||
lua_pushinteger(L, cmd->buttons);
|
||||
else if (fastcmp(field,"driftturn"))
|
||||
break;
|
||||
case ticcmd_driftturn:
|
||||
lua_pushinteger(L, cmd->driftturn);
|
||||
else if (fastcmp(field,"latency"))
|
||||
break;
|
||||
case ticcmd_latency:
|
||||
lua_pushinteger(L, cmd->latency);
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return NOFIELD;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -725,32 +774,44 @@ static int ticcmd_get(lua_State *L)
|
||||
static int ticcmd_set(lua_State *L)
|
||||
{
|
||||
ticcmd_t *cmd = *((ticcmd_t **)luaL_checkudata(L, 1, META_TICCMD));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref);
|
||||
if (!cmd)
|
||||
return LUA_ErrInvalid(L, "ticcmd_t");
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||
|
||||
if (fastcmp(field,"forwardmove"))
|
||||
switch (field)
|
||||
{
|
||||
case ticcmd_forwardmove:
|
||||
cmd->forwardmove = (SINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"sidemove"))
|
||||
break;
|
||||
case ticcmd_sidemove:
|
||||
cmd->sidemove = (SINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"angleturn"))
|
||||
break;
|
||||
case ticcmd_angleturn:
|
||||
cmd->angleturn = (INT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"aiming"))
|
||||
break;
|
||||
case ticcmd_aiming:
|
||||
cmd->aiming = (INT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"buttons"))
|
||||
break;
|
||||
case ticcmd_buttons:
|
||||
cmd->buttons = (UINT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"driftturn"))
|
||||
break;
|
||||
case ticcmd_driftturn:
|
||||
cmd->driftturn = (INT16)luaL_checkinteger(L, 3);
|
||||
else
|
||||
break;
|
||||
case ticcmd_latency:
|
||||
return NOSET;
|
||||
default:
|
||||
return NOFIELD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef NOFIELD
|
||||
#undef NOSET
|
||||
|
||||
int LUA_PlayerLib(lua_State *L)
|
||||
{
|
||||
@@ -797,6 +858,8 @@ int LUA_PlayerLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
ticcmd_fields_ref = Lua_CreateFieldTable(L, ticcmd_opt);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getPlayer);
|
||||
|
||||
+80
-21
@@ -152,6 +152,7 @@ static int noglobals(lua_State *L)
|
||||
{
|
||||
const char *csname;
|
||||
char *name;
|
||||
enum actionnum actionnum;
|
||||
|
||||
lua_remove(L, 1); // we're not gonna be using _G
|
||||
csname = lua_tostring(L, 1);
|
||||
@@ -170,6 +171,10 @@ static int noglobals(lua_State *L)
|
||||
lua_rawset(L, -3); // rawset doesn't trigger this metatable again.
|
||||
// otherwise we would've used setfield, obviously.
|
||||
|
||||
actionnum = LUA_GetActionNumByName(name);
|
||||
if (actionnum < NUMACTIONS)
|
||||
actionsoverridden[actionnum] = true;
|
||||
|
||||
Z_Free(name);
|
||||
return 0;
|
||||
}
|
||||
@@ -394,8 +399,14 @@ fixed_t LUA_EvalMath(const char *word)
|
||||
if (luaL_dostring(mL, buf))
|
||||
{
|
||||
p = lua_tostring(mL, -1);
|
||||
while (*p++ != ':' && *p) ;
|
||||
p += 3; // "1: "
|
||||
|
||||
// If there is [string "..."]:1: text, skip it
|
||||
if (strstr(p, ":") != NULL)
|
||||
{
|
||||
while (*p++ != ':' && *p);
|
||||
|
||||
p += 3; // "1: "
|
||||
}
|
||||
CONS_Alert(CONS_WARNING, "%s\n", p);
|
||||
}
|
||||
else
|
||||
@@ -659,8 +670,17 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
t++;
|
||||
|
||||
if (t == 0)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Too many tables to archive!\n");
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
WRITEUINT8(save_p, ARCH_TABLE);
|
||||
WRITEUINT16(save_p, t);
|
||||
|
||||
@@ -1427,7 +1447,12 @@ static void UnArchiveExtVars(void *pointer)
|
||||
|
||||
if (field_count == 0)
|
||||
return;
|
||||
I_Assert(gL != NULL);
|
||||
|
||||
// Technically possible new, since server may have local lua scripts but no "public" ones, so
|
||||
// field_count would be non zero (there is no way to tell local field from non-local, so
|
||||
// everything gets archived)
|
||||
if (!gL)
|
||||
return;
|
||||
|
||||
TABLESINDEX = lua_gettop(gL);
|
||||
lua_createtable(gL, 0, field_count); // pointer's ext vars subtable
|
||||
@@ -1587,12 +1612,14 @@ void LUA_Archive(void)
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
{
|
||||
// archive function will determine when to skip mobjs,
|
||||
// and write mobjnum in otherwise.
|
||||
ArchiveExtVars(th, "mobj");
|
||||
}
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
// archive function will determine when to skip mobjs,
|
||||
// and write mobjnum in otherwise.
|
||||
ArchiveExtVars(th, "mobj");
|
||||
}
|
||||
}
|
||||
WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
|
||||
|
||||
@@ -1620,11 +1647,15 @@ void LUA_UnArchive(void)
|
||||
}
|
||||
|
||||
do {
|
||||
mobjnum = READUINT32(save_p); // read a mobjnum
|
||||
mobjnum = READUINT32(save_p); // read a mobjnum
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker
|
||||
&& ((mobj_t *)th)->mobjnum == mobjnum) // find matching mobj
|
||||
UnArchiveExtVars(th); // apply variables
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
if (((mobj_t *)th)->mobjnum != mobjnum) // find matching mobj
|
||||
continue;
|
||||
UnArchiveExtVars(th); // apply variables
|
||||
}
|
||||
} while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker.
|
||||
|
||||
LUAh_NetArchiveHook(NetUnArchive); // call the NetArchive hook in unarchive mode
|
||||
@@ -1678,13 +1709,41 @@ void LUA_UnArchiveDemo(void)
|
||||
}
|
||||
|
||||
// For mobj_t, player_t, etc. to take custom variables.
|
||||
int Lua_optoption(lua_State *L, int narg,
|
||||
const char *def, const char *const lst[])
|
||||
int Lua_optoption(lua_State *L, int narg, int def, int list_ref)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (lua_isnoneornil(L, narg))
|
||||
return def;
|
||||
|
||||
I_Assert(lua_checkstack(L, 2));
|
||||
luaL_checkstring(L, narg);
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, list_ref);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_pushvalue(L, narg);
|
||||
lua_rawget(L, -2);
|
||||
|
||||
if (lua_isnumber(L, -1))
|
||||
result = lua_tointeger(L, -1);
|
||||
|
||||
lua_pop(L, 2); // Pop result and fields table
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int Lua_CreateFieldTable(lua_State *L, const char *const lst[])
|
||||
{
|
||||
const char *name = (def) ? luaL_optstring(L, narg, def) : luaL_checkstring(L, narg);
|
||||
int i;
|
||||
for (i=0; lst[i]; i++)
|
||||
if (fastcmp(lst[i], name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lua_newtable(L);
|
||||
for (i = 0; lst[i] != NULL; i++)
|
||||
{
|
||||
lua_pushstring(L, lst[i]);
|
||||
lua_pushinteger(L, i);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
+2
-2
@@ -63,8 +63,8 @@ void LUA_UnArchiveDemo(void);
|
||||
|
||||
void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
|
||||
void LUA_CVarChanged(const char *name); // lua_consolelib.c
|
||||
int Lua_optoption(lua_State *L, int narg,
|
||||
const char *def, const char *const lst[]);
|
||||
int Lua_optoption(lua_State *L, int narg, int def, int list_ref);
|
||||
int Lua_CreateFieldTable(lua_State *L, const char *const lst[]);
|
||||
void LUAh_NetArchiveHook(lua_CFunction archFunc);
|
||||
|
||||
// Console wrapper
|
||||
|
||||
+6
-1
@@ -38,6 +38,7 @@ enum skin {
|
||||
skin_highresscale,
|
||||
skin_soundsid
|
||||
};
|
||||
|
||||
static const char *const skin_opt[] = {
|
||||
"valid",
|
||||
"name",
|
||||
@@ -61,10 +62,12 @@ static const char *const skin_opt[] = {
|
||||
|
||||
#define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field])
|
||||
|
||||
static int skin_fields_ref = LUA_NOREF;
|
||||
|
||||
static int skin_get(lua_State *L)
|
||||
{
|
||||
skin_t *skin = *((skin_t **)luaL_checkudata(L, 1, META_SKIN));
|
||||
enum skin field = luaL_checkoption(L, 2, NULL, skin_opt);
|
||||
enum skin field = Lua_optoption(L, 2, -1, skin_fields_ref);
|
||||
INT32 i;
|
||||
|
||||
// skins are always valid, only added, never removed
|
||||
@@ -253,6 +256,8 @@ int LUA_SkinLib(lua_State *L)
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L,1);
|
||||
|
||||
skin_fields_ref = Lua_CreateFieldTable(L, skin_opt);
|
||||
|
||||
luaL_newmetatable(L, META_SOUNDSID);
|
||||
lua_pushcfunction(L, soundsid_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
+3
-2
@@ -909,8 +909,9 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
// get offset from mt, which points to old mapthings, then add new location
|
||||
if (mo->spawnpoint)
|
||||
mo->spawnpoint = (mo->spawnpoint - mt) + mapthings;
|
||||
if (!mo->spawnpoint)
|
||||
continue;
|
||||
mo->spawnpoint = (mo->spawnpoint - mt) + mapthings;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1011,13 +1011,6 @@ int main(int argc, char** argv)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void *cpu_cpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
return memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy;
|
||||
|
||||
void I_Error(const char *error, ...)
|
||||
{
|
||||
(void)error;
|
||||
|
||||
+840
-792
File diff suppressed because it is too large.
Load diff
+19
-2
@@ -21,6 +21,8 @@
|
||||
#include "mserv.h"
|
||||
#include "r_things.h" // for SKINNAMESIZE
|
||||
|
||||
extern boolean forceshowhud;
|
||||
|
||||
//
|
||||
// MENUS
|
||||
//
|
||||
@@ -59,6 +61,9 @@ void M_SortServerList(void);
|
||||
// Draws a box with a texture inside as background for messages
|
||||
void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines);
|
||||
|
||||
// Same but with extra flags applied
|
||||
void M_DrawTextBoxFlags(INT32 x, INT32 y, INT32 width, INT32 boxlines, INT32 flags);
|
||||
|
||||
// Used in d_netcmd to restart time attack
|
||||
void M_ModeAttackRetry(INT32 choice);
|
||||
|
||||
@@ -255,6 +260,7 @@ extern INT32 mapwads[NUMMAPS];
|
||||
|
||||
extern description_t description[MAXSKINS];
|
||||
|
||||
extern consvar_t cv_replaysearchrate;
|
||||
extern consvar_t cv_showfocuslost;
|
||||
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
|
||||
extern consvar_t cv_showallmaps;
|
||||
@@ -286,8 +292,8 @@ void PDistort_menu_Onchange(void);
|
||||
// Bird menu updating
|
||||
void Bird_menu_Onchange(void);
|
||||
|
||||
// Saturn menu updating
|
||||
void Saturn_menu_Onchange(void);
|
||||
// Saturn Hud menu updating
|
||||
void SaturnHud_menu_Onchange(void);
|
||||
|
||||
void M_ReplayHut(INT32 choice);
|
||||
void M_SetPlaybackMenuPointer(void);
|
||||
@@ -397,4 +403,15 @@ void M_SlotCvarIntoModMenu(consvar_t* cvar, const char* category, const char* na
|
||||
{NULL}\
|
||||
}
|
||||
|
||||
#define DoToolTips(menu, tooltip)\
|
||||
if (currentMenu == &menu)\
|
||||
{\
|
||||
if (!(tooltip[itemOn] == NULL))\
|
||||
{\
|
||||
M_DrawSplitText(BASEVIDWIDTH / 2, BASEVIDHEIGHT-50, V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, tooltip[itemOn], coolalphatimer);\
|
||||
if (coolalphatimer > 0 && interpTimerHackAllow)\
|
||||
coolalphatimer--;\
|
||||
}\
|
||||
}
|
||||
|
||||
#endif //__X_MENU__
|
||||
+50
-1
@@ -334,6 +334,38 @@ boolean FIL_FileOK(char const *name)
|
||||
return access(name,6)+1; //R_OK|W_OK
|
||||
}
|
||||
|
||||
/** Copies contents of one file to another
|
||||
*
|
||||
* \param src File to copy from
|
||||
* \param dst File to write into
|
||||
* \return true if copy was succesful, false if it doesn't.
|
||||
*/
|
||||
boolean FIL_CopyFile(const char *src, const char *dst)
|
||||
{
|
||||
FILE *srcFile = fopen(src, "rb");
|
||||
|
||||
if (srcFile == NULL)
|
||||
return false;
|
||||
|
||||
FILE *dstFile = fopen(dst, "wb");
|
||||
|
||||
if (dstFile == NULL)
|
||||
{
|
||||
fclose(srcFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
size_t n;
|
||||
|
||||
while ((n = fread(buffer, 1, sizeof(buffer), srcFile)) > 0)
|
||||
fwrite(buffer, 1, n, dstFile);
|
||||
|
||||
fclose(srcFile);
|
||||
fclose(dstFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Checks if a pathname has a file extension and adds the extension provided
|
||||
* if not.
|
||||
@@ -525,11 +557,28 @@ void M_SaveConfig(const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
char *filepath;
|
||||
char backupfile[MAX_WADPATH+4];
|
||||
|
||||
// make sure not to write back the config until it's been correctly loaded
|
||||
if (!gameconfig_loaded)
|
||||
return;
|
||||
|
||||
// Create backup of the config file
|
||||
snprintf(backupfile, sizeof backupfile, "%s.bak", configfile);
|
||||
backupfile[sizeof backupfile - 1] = '\0';
|
||||
|
||||
FILE *config = fopen(configfile, "r");
|
||||
|
||||
if (config != NULL)
|
||||
{
|
||||
fclose(config);
|
||||
if (FIL_CopyFile(configfile, backupfile) == false)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING,"Failed to create a backup of the configuration file. Will not attempt to write to file\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// can change the file name
|
||||
if (filename)
|
||||
{
|
||||
@@ -1938,7 +1987,7 @@ char *sizeu5(size_t num)
|
||||
return sizeu5_buf;
|
||||
}
|
||||
|
||||
void *M_Memcpy(void *dest, const void *src, size_t n)
|
||||
FUNCINLINE ATTRINLINE void *M_Memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
return memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ boolean FIL_FileExists(const char *name);
|
||||
boolean FIL_WriteFileOK(char const *name);
|
||||
boolean FIL_ReadFileOK(char const *name);
|
||||
boolean FIL_FileOK(char const *name);
|
||||
boolean FIL_CopyFile(const char *src, const char *dst);
|
||||
|
||||
void FIL_DefaultExtension (char *path, const char *extension);
|
||||
void FIL_ForceExtension(char *path, const char *extension);
|
||||
|
||||
@@ -58,7 +58,6 @@ static ps_metric_t ps_regularcount = {0};
|
||||
static ps_metric_t ps_scenerycount = {0};
|
||||
static ps_metric_t ps_nothinkcount = {0};
|
||||
static ps_metric_t ps_otherthcount = {0};
|
||||
static ps_metric_t ps_precipcount = {0};
|
||||
static ps_metric_t ps_removecount = {0};
|
||||
|
||||
ps_metric_t ps_checkposition_calls = {0};
|
||||
@@ -173,7 +172,6 @@ perfstatrow_t thinkercount_rows[] = {
|
||||
{" scenery", " Scenery: ", &ps_scenerycount, PS_LEVEL},
|
||||
{" nothink", " Nothink: ", &ps_nothinkcount, PS_HIDE_ZERO|PS_LEVEL},
|
||||
{" other ", " Other: ", &ps_otherthcount, PS_LEVEL},
|
||||
{" precip ", " Precipitation: ", &ps_precipcount, PS_LEVEL},
|
||||
{" remove ", " Pending removal:", &ps_removecount, PS_LEVEL},
|
||||
{0}
|
||||
};
|
||||
@@ -572,7 +570,6 @@ static void PS_CountThinkers(void)
|
||||
ps_scenerycount.value.i = 0;
|
||||
ps_nothinkcount.value.i = 0;
|
||||
ps_otherthcount.value.i = 0;
|
||||
ps_precipcount.value.i = 0;
|
||||
ps_removecount.value.i = 0;
|
||||
for (thinker = thinkercap.next; thinker != &thinkercap; thinker = thinker->next)
|
||||
{
|
||||
@@ -590,8 +587,6 @@ static void PS_CountThinkers(void)
|
||||
else
|
||||
ps_regularcount.value.i++;
|
||||
}
|
||||
else if (thinker->function.acp1 == (actionf_p1)P_NullPrecipThinker)
|
||||
ps_precipcount.value.i++;
|
||||
else
|
||||
ps_otherthcount.value.i++;
|
||||
}
|
||||
|
||||
+73
-16
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "doomdef.h"
|
||||
#include "console.h" // con_startup
|
||||
#include "command.h"
|
||||
#include "i_threads.h"
|
||||
#include "mserv.h"
|
||||
@@ -212,20 +213,50 @@ static void Command_Listserv_f(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static boolean firstmsrules = false;
|
||||
|
||||
static void
|
||||
Get_masterserver_rules (boolean checkfirst)
|
||||
{
|
||||
char rules[256];
|
||||
|
||||
if (checkfirst)
|
||||
{
|
||||
boolean MSRulesExist;
|
||||
|
||||
Lock_state();
|
||||
MSRulesExist = (MSRules != NULL);
|
||||
Unlock_state();
|
||||
|
||||
if (MSRulesExist)
|
||||
return;
|
||||
}
|
||||
|
||||
if (HMS_fetch_rules(rules, sizeof rules))
|
||||
{
|
||||
Lock_state();
|
||||
Z_Free(MSRules);
|
||||
MSRules = Z_StrDup(rules);
|
||||
|
||||
if (MSRegistered == true)
|
||||
{
|
||||
CONS_Printf("\n");
|
||||
CONS_Alert(CONS_NOTICE, "%s\n", rules);
|
||||
}
|
||||
|
||||
firstmsrules = true;
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Finish_registration (void)
|
||||
{
|
||||
int registered;
|
||||
char *rules = GetMasterServerRules();
|
||||
|
||||
CONS_Printf("Registering this server on the master server...\n");
|
||||
|
||||
if (rules)
|
||||
{
|
||||
CONS_Printf("\n");
|
||||
CONS_Alert(CONS_NOTICE, "%s\n", rules);
|
||||
}
|
||||
|
||||
registered = HMS_register();
|
||||
|
||||
Lock_state();
|
||||
@@ -237,6 +268,17 @@ Finish_registration (void)
|
||||
}
|
||||
Unlock_state();
|
||||
|
||||
char *rules = GetMasterServerRules();
|
||||
if (rules == NULL)
|
||||
{
|
||||
Get_masterserver_rules(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("\n");
|
||||
CONS_Alert(CONS_NOTICE, "%s\n", rules);
|
||||
}
|
||||
|
||||
if (registered)
|
||||
CONS_Printf("Master server registration successful.\n");
|
||||
}
|
||||
@@ -322,17 +364,10 @@ Finish_unlist (void)
|
||||
static void
|
||||
Finish_masterserver_change (char *api)
|
||||
{
|
||||
char rules[256];
|
||||
|
||||
HMS_set_api(api);
|
||||
|
||||
if (HMS_fetch_rules(rules, sizeof rules))
|
||||
{
|
||||
Lock_state();
|
||||
Z_Free(MSRules);
|
||||
MSRules = Z_StrDup(rules);
|
||||
Unlock_state();
|
||||
}
|
||||
if (!con_startup)
|
||||
Get_masterserver_rules(false);
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
@@ -430,6 +465,14 @@ Change_masterserver_thread (char *api)
|
||||
|
||||
Finish_masterserver_change(api);
|
||||
}
|
||||
|
||||
static void
|
||||
Get_masterserver_rules_thread (void)
|
||||
{
|
||||
// THIS FUNC has its own lock check in it
|
||||
Get_masterserver_rules(true);
|
||||
}
|
||||
|
||||
#endif/*HAVE_THREADS*/
|
||||
|
||||
void RegisterServer(void)
|
||||
@@ -540,6 +583,20 @@ Set_api (const char *api)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Get_rules (void)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread(
|
||||
"get-masterserver-rules",
|
||||
(I_thread_fn)Get_masterserver_rules_thread,
|
||||
NULL
|
||||
);
|
||||
#else
|
||||
Get_masterserver_rules(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
static void
|
||||
|
||||
+5
-1
@@ -82,6 +82,8 @@ extern I_mutex ms_ServerList_mutex;
|
||||
void RegisterServer(void);
|
||||
void UnregisterServer(void);
|
||||
|
||||
void Get_rules(void);
|
||||
|
||||
void MasterClient_Ticker(void);
|
||||
|
||||
msg_server_t *GetShortServersList(int id);
|
||||
@@ -90,9 +92,11 @@ char *GetMODVersion(int id);
|
||||
#endif
|
||||
|
||||
char *GetMasterServerRules(void);
|
||||
#endif
|
||||
|
||||
void AddMServCommands(void);
|
||||
|
||||
#ifdef MASTERSERVER
|
||||
/* HTTP */
|
||||
void HMS_set_api (char *api);
|
||||
int HMS_register (void);
|
||||
@@ -105,4 +109,4 @@ const char * HMS_fetch_rules (char *buffer, size_t size_of_buffer);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+203
-203
File diff suppressed because it is too large.
Load diff
@@ -1968,32 +1968,8 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||
}
|
||||
else // Not going anywhere, so look for players.
|
||||
{
|
||||
//thinker_t *th;
|
||||
//mobj_t *mo;
|
||||
|
||||
thwomp->direction = -1;
|
||||
|
||||
/* // SRB2kart 170217 - Thwomps are automatic.
|
||||
// scan the thinkers to find players!
|
||||
if (!rover || (rover->flags & FF_EXISTS))
|
||||
{
|
||||
// scan the thinkers to find players!
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
if (mo->type == MT_PLAYER && mo->health && mo->player && !mo->player->spectator
|
||||
&& mo->z <= thwomp->sector->ceilingheight
|
||||
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
|
||||
{
|
||||
thwomp->direction = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
thwomp->sector->ceilspeed = 0;
|
||||
thwomp->sector->floorspeed = 0;
|
||||
}
|
||||
|
||||
+65
-595
@@ -17,6 +17,7 @@
|
||||
#include "g_game.h"
|
||||
#include "m_random.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "s_sound.h"
|
||||
#include "r_main.h"
|
||||
#include "st_stuff.h"
|
||||
@@ -253,26 +254,21 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
|
||||
if (heightcheck)
|
||||
{
|
||||
/*if (special->type == MT_FLINGEMERALD) // little hack here...
|
||||
{ // flingemerald sprites are low to the ground, so extend collision radius down some.
|
||||
if (toucher->z > (special->z + special->height))
|
||||
return;
|
||||
if (special->z - special->height > (toucher->z + toucher->height))
|
||||
return;
|
||||
}
|
||||
else*/
|
||||
if (toucher->momz < 0)
|
||||
{
|
||||
if (toucher->momz < 0) {
|
||||
if (toucher->z + toucher->momz > special->z + special->height)
|
||||
return;
|
||||
} else if (toucher->z > special->z + special->height)
|
||||
return;
|
||||
if (toucher->momz > 0) {
|
||||
if (toucher->z + toucher->height + toucher->momz < special->z)
|
||||
return;
|
||||
} else if (toucher->z + toucher->height < special->z)
|
||||
if (toucher->z + toucher->momz > special->z + special->height)
|
||||
return;
|
||||
}
|
||||
else if (toucher->z > special->z + special->height)
|
||||
return;
|
||||
|
||||
if (toucher->momz > 0)
|
||||
{
|
||||
if (toucher->z + toucher->height + toucher->momz < special->z)
|
||||
return;
|
||||
}
|
||||
else if (toucher->z + toucher->height < special->z)
|
||||
return;
|
||||
}
|
||||
|
||||
if (special->health <= 0)
|
||||
@@ -383,16 +379,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
player->kartstuff[k_roulettetype] = 2;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Eggbox snipe!
|
||||
if (special->type == MT_EGGMANITEM && special->health > 1)
|
||||
S_StartSound(toucher, sfx_bsnipe);
|
||||
#endif
|
||||
|
||||
{
|
||||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof, special->info->deathsound);
|
||||
}
|
||||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof, special->info->deathsound);
|
||||
|
||||
if (special->target && special->target->player)
|
||||
{
|
||||
@@ -475,8 +463,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
}
|
||||
else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, 1))
|
||||
{
|
||||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof, special->info->seesound);
|
||||
mobj_t *poof2 = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
S_StartSound(poof2, special->info->seesound);
|
||||
|
||||
// Karma fireworks
|
||||
for (i = 0; i < 5; i++)
|
||||
@@ -502,10 +490,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
}
|
||||
else if (special->target->player->kartstuff[k_comebackmode] == 2 && P_CanPickupItem(player, 2))
|
||||
{
|
||||
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
mobj_t *poof3 = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
|
||||
UINT8 ptadd = 1; // No WANTED bonus for tricking
|
||||
|
||||
S_StartSound(poof, special->info->seesound);
|
||||
S_StartSound(poof3, special->info->seesound);
|
||||
|
||||
if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1
|
||||
{
|
||||
@@ -583,10 +571,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
else
|
||||
K_SpinPlayer(player, special->target, 0, special, false);
|
||||
return;
|
||||
/*case MT_EERIEFOG:
|
||||
special->frame &= ~FF_TRANS80;
|
||||
special->frame |= FF_TRANS90;
|
||||
return;*/
|
||||
case MT_SMK_MOLE:
|
||||
if (special->target && !P_MobjWasRemoved(special->target))
|
||||
return;
|
||||
@@ -935,12 +919,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
player->flyangle = special->threshold;
|
||||
|
||||
player->speed = FixedMul(special->info->speed, special->scale);
|
||||
// Potentially causes axis transfer failures.
|
||||
// Also rarely worked properly anyway.
|
||||
//P_UnsetThingPosition(player->mo);
|
||||
//player->mo->x = special->x;
|
||||
//player->mo->y = special->y;
|
||||
//P_SetThingPosition(player->mo);
|
||||
toucher->z = special->z+(special->height/4);
|
||||
}
|
||||
else // More like a spring
|
||||
@@ -985,140 +963,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
}
|
||||
}
|
||||
return;
|
||||
/*case MT_NIGHTSSUPERLOOP:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
player->powers[pw_nights_superloop] = (UINT16)special->info->speed;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
players[i].powers[pw_nights_superloop] = (UINT16)special->info->speed;
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Super Paraloop"));
|
||||
}
|
||||
break;
|
||||
case MT_NIGHTSDRILLREFILL:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
player->drillmeter = special->info->speed;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
players[i].drillmeter = special->info->speed;
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Drill Refill"));
|
||||
}
|
||||
break;
|
||||
case MT_NIGHTSHELPER:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
{
|
||||
// A flicky orbits us now
|
||||
mobj_t *flickyobj = P_SpawnMobj(toucher->x, toucher->y, toucher->z + toucher->info->height, MT_NIGHTOPIANHELPER);
|
||||
P_SetTarget(&flickyobj->target, toucher);
|
||||
|
||||
player->powers[pw_nights_helper] = (UINT16)special->info->speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj_t *flickyobj;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].mo && players[i].pflags & PF_NIGHTSMODE) {
|
||||
players[i].powers[pw_nights_helper] = (UINT16)special->info->speed;
|
||||
flickyobj = P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_NIGHTOPIANHELPER);
|
||||
P_SetTarget(&flickyobj->target, players[i].mo);
|
||||
}
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Nightopian Helper"));
|
||||
}
|
||||
break;
|
||||
case MT_NIGHTSEXTRATIME:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
{
|
||||
player->nightstime += special->info->speed;
|
||||
player->startedtime += special->info->speed;
|
||||
P_RestoreMusic(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
{
|
||||
players[i].nightstime += special->info->speed;
|
||||
players[i].startedtime += special->info->speed;
|
||||
P_RestoreMusic(&players[i]);
|
||||
}
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Extra Time"));
|
||||
}
|
||||
break;
|
||||
case MT_NIGHTSLINKFREEZE:
|
||||
if (player->bot || !(player->pflags & PF_NIGHTSMODE))
|
||||
return;
|
||||
if (!G_IsSpecialStage(gamemap))
|
||||
{
|
||||
player->powers[pw_nights_linkfreeze] = (UINT16)special->info->speed;
|
||||
player->linktimer = 2*TICRATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE)
|
||||
{
|
||||
players[i].powers[pw_nights_linkfreeze] += (UINT16)special->info->speed;
|
||||
players[i].linktimer = 2*TICRATE;
|
||||
}
|
||||
if (special->info->deathsound != sfx_None)
|
||||
S_StartSound(NULL, special->info->deathsound);
|
||||
}
|
||||
|
||||
// CECHO showing you what this item is
|
||||
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
|
||||
{
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT);
|
||||
HU_SetCEchoDuration(4);
|
||||
HU_DoCEcho(M_GetText("\\\\\\\\\\\\\\\\Link Freeze"));
|
||||
}
|
||||
break;*/
|
||||
case MT_NIGHTSWING:
|
||||
if (G_IsSpecialStage(gamemap) && useNightsSS)
|
||||
{ // Pseudo-ring.
|
||||
@@ -1132,7 +976,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
break;
|
||||
case MT_HOOPCOLLIDE:
|
||||
// This produces a kind of 'domino effect' with the hoop's pieces.
|
||||
for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
|
||||
if (!midgamejoin)
|
||||
for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
|
||||
|
||||
i = 0;
|
||||
for (; special->type == MT_HOOP; special = special->hnext)
|
||||
{
|
||||
@@ -1464,7 +1310,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
}
|
||||
else
|
||||
{
|
||||
P_PlayRinglossSound(toucher);
|
||||
P_PlayRinglossSound(toucher, NULL);
|
||||
if (toucher->health > 10)
|
||||
toucher->health -= 10;
|
||||
else
|
||||
@@ -1510,23 +1356,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
|| special->z > toucher->z + (toucher->height*2/3))
|
||||
return; // Only go in the mouth
|
||||
|
||||
/* // SRB2kart - Can't drown.
|
||||
// Eaten by player!
|
||||
if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1)
|
||||
P_RestoreMusic(player);
|
||||
|
||||
if (player->powers[pw_underwater] < underwatertics + 1)
|
||||
player->powers[pw_underwater] = underwatertics + 1;
|
||||
*/
|
||||
|
||||
/*
|
||||
if (!player->climbing)
|
||||
{
|
||||
P_SetPlayerMobjState(toucher, S_PLAY_GASP);
|
||||
P_ResetPlayer(player);
|
||||
}
|
||||
*/
|
||||
|
||||
toucher->momx = toucher->momy = toucher->momz = 0;
|
||||
break;
|
||||
|
||||
@@ -1583,26 +1412,7 @@ void P_CheckTimeLimit(void)
|
||||
if (gameaction == ga_completed)
|
||||
return;
|
||||
|
||||
//Tagmode round end but only on the tic before the
|
||||
//XD_EXITLEVEL packet is received by all players.
|
||||
/*if (G_TagGametype())
|
||||
{
|
||||
if (leveltime == (timelimitintics + 1))
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator
|
||||
|| (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT))
|
||||
continue;
|
||||
|
||||
CONS_Printf(M_GetText("%s received double points for surviving the round.\n"), player_names[i]);
|
||||
P_AddPlayerScore(&players[i], players[i].score);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Optional tie-breaker for Match/CTF
|
||||
else*/ if (cv_overtime.value)
|
||||
if (cv_overtime.value)
|
||||
{
|
||||
INT32 playerarray[MAXPLAYERS];
|
||||
INT32 tempplayer = 0;
|
||||
@@ -1675,9 +1485,6 @@ void P_CheckTimeLimit(void)
|
||||
return;
|
||||
P_DoPlayerExit(&players[i]);
|
||||
}
|
||||
|
||||
/*if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);*/
|
||||
}
|
||||
|
||||
/** Checks if a player's score is over the pointlimit and the round should end.
|
||||
@@ -1699,127 +1506,27 @@ void P_CheckPointLimit(void)
|
||||
if (G_RaceGametype())
|
||||
return;
|
||||
|
||||
// pointlimit is nonzero, check if it's been reached by this player
|
||||
/*if (G_GametypeHasTeams())
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
// Just check both teams
|
||||
if ((UINT32)cv_pointlimit.value <= redscore || (UINT32)cv_pointlimit.value <= bluescore)
|
||||
{
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
}
|
||||
else*/
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
if ((UINT32)cv_pointlimit.value <= players[i].marescore)
|
||||
if ((UINT32)cv_pointlimit.value <= players[i].marescore)
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++) // AAAAA nested loop using the same iteration variable ;;
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++) // AAAAA nested loop using the same iteration variable ;;
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
if (players[i].exiting)
|
||||
return;
|
||||
P_DoPlayerExit(&players[i]);
|
||||
}
|
||||
|
||||
/*if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);*/
|
||||
return; // good thing we're leaving the function immediately instead of letting the loop get mangled!
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
if (players[i].exiting)
|
||||
return;
|
||||
P_DoPlayerExit(&players[i]);
|
||||
}
|
||||
|
||||
return; // good thing we're leaving the function immediately instead of letting the loop get mangled!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Checks for untagged remaining players in both tag derivitave modes.
|
||||
*If no untagged players remain, end the round.
|
||||
*Also serves as error checking if the only IT player leaves.*/
|
||||
/*void P_CheckSurvivors(void)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 survivors = 0;
|
||||
INT32 taggers = 0;
|
||||
INT32 spectators = 0;
|
||||
INT32 survivorarray[MAXPLAYERS];
|
||||
|
||||
if (!D_NumPlayers()) //no players in the game, no check performed.
|
||||
return;
|
||||
|
||||
for (i=0; i < MAXPLAYERS; i++) //figure out counts of taggers, survivors and spectators.
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
if (players[i].spectator)
|
||||
spectators++;
|
||||
else if (players[i].pflags & PF_TAGIT)
|
||||
taggers++;
|
||||
else if (!(players[i].pflags & PF_TAGGED))
|
||||
{
|
||||
survivorarray[survivors] = i;
|
||||
survivors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!taggers) //If there are no taggers, pick a survivor at random to be it.
|
||||
{
|
||||
// Exception for hide and seek. If a round has started and the IT player leaves, end the round.
|
||||
if (gametype == GT_HIDEANDSEEK && (leveltime >= (hidetime * TICRATE)))
|
||||
{
|
||||
CONS_Printf(M_GetText("The IT player has left the game.\n"));
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (survivors)
|
||||
{
|
||||
INT32 newtagger = survivorarray[P_RandomKey(survivors)];
|
||||
|
||||
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[newtagger]); // Tell everyone who is it!
|
||||
players[newtagger].pflags |= PF_TAGIT;
|
||||
|
||||
survivors--; //Get rid of the guy we just made IT.
|
||||
|
||||
//Yeah, we have an eligible tagger, but we may not have anybody for him to tag!
|
||||
//If there is only one guy waiting on the game to fill or spectators to enter game, don't bother.
|
||||
if (!survivors && (D_NumPlayers() - spectators) > 1)
|
||||
{
|
||||
CONS_Printf(M_GetText("All players have been tagged!\n"));
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//If we reach this point, no player can replace the one that was IT.
|
||||
//Unless it is one player waiting on a game, end the round.
|
||||
if ((D_NumPlayers() - spectators) > 1)
|
||||
{
|
||||
CONS_Printf(M_GetText("There are no players able to become IT.\n"));
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//If there are taggers, but no survivors, end the round.
|
||||
//Except when the tagger is by himself and the rest of the game are spectators.
|
||||
if (!survivors && (D_NumPlayers() - spectators) > 1)
|
||||
{
|
||||
CONS_Printf(M_GetText("All players have been tagged!\n"));
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
}*/
|
||||
|
||||
// Checks whether or not to end a race netgame.
|
||||
boolean P_CheckRacers(void)
|
||||
{
|
||||
@@ -1908,9 +1615,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
mobj_t *mo;
|
||||
int ms;
|
||||
|
||||
//if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL))
|
||||
// P_SetTarget(&target->tracer, inflictor);
|
||||
|
||||
if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6)
|
||||
sstimer = 6; // Just let P_Ticker take care of the rest.
|
||||
|
||||
@@ -1936,7 +1640,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL);
|
||||
target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL);
|
||||
target->health = 0; // This makes it easy to check if something's dead elsewhere.
|
||||
target->shadowscale = 0;
|
||||
|
||||
if (LUAh_MobjDeath(target, inflictor, source) || P_MobjWasRemoved(target))
|
||||
return;
|
||||
@@ -1960,7 +1663,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
K_KillBananaChain(target->target->hnext, inflictor, source);
|
||||
target->target->player->kartstuff[k_itemamount] = 0;
|
||||
}
|
||||
else
|
||||
else if (target->target->player->kartstuff[k_itemamount])
|
||||
target->target->player->kartstuff[k_itemamount]--;
|
||||
}
|
||||
else if ((target->type == MT_ORBINAUT_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) // orbit items
|
||||
@@ -1992,14 +1695,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
{
|
||||
if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording!
|
||||
G_StopMetalRecording();
|
||||
/*if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty
|
||||
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
|
||||
{ // Suicide penalty - Not in Kart
|
||||
if (target->player->score >= 50)
|
||||
target->player->score -= 50;
|
||||
else
|
||||
target->player->score = 0;
|
||||
}*/
|
||||
|
||||
target->flags2 &= ~MF2_DONTDRAW;
|
||||
}
|
||||
@@ -2016,85 +1711,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation
|
||||
}
|
||||
}
|
||||
|
||||
// Award Score Tails
|
||||
/*{ // Enemies shouldn't award points in Kart
|
||||
INT32 score = 0;
|
||||
|
||||
if (maptol & TOL_NIGHTS) // Enemies always worth 200, bosses don't do anything.
|
||||
{
|
||||
if ((target->flags & MF_ENEMY) && !(target->flags & (MF_MISSILE|MF_BOSS)))
|
||||
{
|
||||
score = 200;
|
||||
|
||||
if (source->player->bonustime)
|
||||
score *= 2;
|
||||
|
||||
// Also, add to the link.
|
||||
// I don't know if NiGHTS did this, but
|
||||
// Sonic Time Attacked did and it seems like a good enough incentive
|
||||
// to make people want to actually dash towards/paraloop enemies
|
||||
if (++source->player->linkcount > source->player->maxlink)
|
||||
source->player->maxlink = source->player->linkcount;
|
||||
source->player->linktimer = 2*TICRATE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target->flags & MF_BOSS)
|
||||
score = 1000;
|
||||
else if ((target->flags & MF_ENEMY) && !(target->flags & MF_MISSILE))
|
||||
{
|
||||
mobj_t *scoremobj;
|
||||
UINT32 scorestate = mobjinfo[MT_SCORE].spawnstate;
|
||||
|
||||
scoremobj = P_SpawnMobj(target->x, target->y, target->z + (target->height / 2), MT_SCORE);
|
||||
|
||||
// On ground? No chain starts.
|
||||
if (!source->player->powers[pw_invulnerability] && P_IsObjectOnGround(source))
|
||||
{
|
||||
source->player->scoreadd = 0;
|
||||
score = 100;
|
||||
}
|
||||
// Mario Mode has Mario-like chain point values
|
||||
else if (mariomode) switch (++source->player->scoreadd)
|
||||
{
|
||||
case 1: score = 100; break;
|
||||
case 2: score = 200; scorestate += 1; break;
|
||||
case 3: score = 400; scorestate += 5; break;
|
||||
case 4: score = 800; scorestate += 6; break;
|
||||
case 5: score = 1000; scorestate += 3; break;
|
||||
case 6: score = 2000; scorestate += 7; break;
|
||||
case 7: score = 4000; scorestate += 8; break;
|
||||
case 8: score = 8000; scorestate += 9; break;
|
||||
default: // 1up for a chain this long
|
||||
if (modeattacking) // but 1ups don't exist in record attack!
|
||||
{ // So we just go back to 10k points.
|
||||
score = 10000; scorestate += 4; break;
|
||||
}
|
||||
P_GivePlayerLives(source->player, 1);
|
||||
P_PlayLivesJingle(source->player);
|
||||
scorestate += 10;
|
||||
break;
|
||||
}
|
||||
// More Sonic-like point system
|
||||
else switch (++source->player->scoreadd)
|
||||
{
|
||||
case 1: score = 100; break;
|
||||
case 2: score = 200; scorestate += 1; break;
|
||||
case 3: score = 500; scorestate += 2; break;
|
||||
case 4: case 5: case 6: case 7: case 8: case 9:
|
||||
case 10: case 11: case 12: case 13: case 14:
|
||||
score = 1000; scorestate += 3; break;
|
||||
default: score = 10000; scorestate += 4; break;
|
||||
}
|
||||
|
||||
P_SetMobjState(scoremobj, scorestate);
|
||||
}
|
||||
}
|
||||
|
||||
P_AddPlayerScore(source->player, score);
|
||||
}*/
|
||||
}
|
||||
|
||||
// if a player avatar dies...
|
||||
@@ -2121,7 +1737,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
}
|
||||
target->player->playerstate = PST_DEAD;
|
||||
|
||||
if (cv_fading.value && cv_birdmusic.value && P_IsLocalPlayer(target->player))
|
||||
if (cv_birdmusic.value && cv_fading.value && P_IsLocalPlayer(target->player))
|
||||
{
|
||||
if (netgame || multiplayer)
|
||||
ms = cv_respawntime.value * 1000;
|
||||
@@ -2132,7 +1748,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
If the time spent with the music paused is less than half
|
||||
a second, continue playing the song (just mute it).
|
||||
*/
|
||||
if (( ms - cv_respawnfademusicout.value ) < 500)
|
||||
if ((ms - cv_respawnfademusicout.value) < 500)
|
||||
S_FadeMusic(0, cv_respawnfademusicout.value);
|
||||
else
|
||||
S_FadeOutStopMusic(cv_respawnfademusicout.value);
|
||||
@@ -2158,42 +1774,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
if (target->player == &players[displayplayers[3]])
|
||||
localaiming[3] = 0;
|
||||
|
||||
//tag deaths handled differently in suicide cases. Don't count spectators!
|
||||
/*if (G_TagGametype()
|
||||
&& !(target->player->pflags & PF_TAGIT) && (!source || !source->player) && !(target->player->spectator))
|
||||
{
|
||||
// if you accidentally die before you run out of time to hide, ignore it.
|
||||
// allow them to try again, rather than sitting the whole thing out.
|
||||
if (leveltime >= hidetime * TICRATE)
|
||||
{
|
||||
if (gametype == GT_TAG)//suiciding in survivor makes you IT.
|
||||
{
|
||||
target->player->pflags |= PF_TAGIT;
|
||||
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it!
|
||||
P_CheckSurvivors();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(target->player->pflags & PF_TAGGED))
|
||||
{
|
||||
//otherwise, increment the tagger's score.
|
||||
//in hide and seek, suiciding players are counted as found.
|
||||
INT32 w;
|
||||
|
||||
for (w=0; w < MAXPLAYERS; w++)
|
||||
{
|
||||
if (players[w].pflags & PF_TAGIT)
|
||||
P_AddPlayerScore(&players[w], 1);
|
||||
}
|
||||
|
||||
target->player->pflags |= PF_TAGGED;
|
||||
CONS_Printf(M_GetText("%s was found!\n"), player_names[target->player-players]);
|
||||
P_CheckSurvivors();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else*/ if (G_BattleGametype())
|
||||
if (G_BattleGametype())
|
||||
K_CheckBumpers();
|
||||
|
||||
target->player->kartstuff[k_pogospring] = 0;
|
||||
@@ -2608,26 +2189,6 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
||||
return false;
|
||||
}
|
||||
|
||||
// The tag occurs so long as you aren't shooting another tagger with friendlyfire on.
|
||||
/*if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT))
|
||||
{
|
||||
P_AddPlayerScore(source->player, 1); //award points to tagger.
|
||||
|
||||
if (gametype == GT_TAG) //survivor
|
||||
{
|
||||
player->pflags |= PF_TAGIT; //in survivor, the player becomes IT and helps hunt down the survivors.
|
||||
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[player-players]); // Tell everyone who is it!
|
||||
}
|
||||
else
|
||||
{
|
||||
player->pflags |= PF_TAGGED; //in hide and seek, the player is tagged and stays stationary.
|
||||
CONS_Printf(M_GetText("%s was found!\n"), player_names[player-players]); // Tell everyone who is it!
|
||||
}
|
||||
|
||||
//checks if tagger has tagged all players, if so, end round early.
|
||||
P_CheckSurvivors();
|
||||
}*/
|
||||
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
||||
// Check for a shield
|
||||
@@ -2645,7 +2206,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
||||
}
|
||||
else if (target->health > 1) // Ring loss
|
||||
{
|
||||
P_PlayRinglossSound(target);
|
||||
P_PlayRinglossSound(target, source);
|
||||
P_PlayerRingBurst(player, player->mo->health - 1);
|
||||
}
|
||||
|
||||
@@ -2666,15 +2227,6 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
|
||||
{
|
||||
player_t *player = target->player;
|
||||
|
||||
// You can't kill yourself, idiot... // Unless it's Mario kart. Which it is. In this mod. All the time.
|
||||
//if (source == target)
|
||||
// return false;
|
||||
|
||||
// In COOP/RACE/CHAOS, you can't hurt other players unless cv_friendlyfire is on
|
||||
// ...But in SRB2kart, you can!
|
||||
//if (!cv_friendlyfire.value && (G_RaceGametype()))
|
||||
// return false;
|
||||
|
||||
// Tag handling
|
||||
if (G_TagGametype())
|
||||
return P_TagDamage(target, inflictor, source, damage);
|
||||
@@ -2726,32 +2278,6 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
||||
|
||||
P_SetPlayerMobjState(player->mo, player->mo->info->deathstate);
|
||||
|
||||
/*if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, 1);
|
||||
}
|
||||
}
|
||||
if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, 1);
|
||||
}
|
||||
|
||||
// If the player was super, tell them he/she ain't so super nomore.
|
||||
if (gametype != GT_COOP && player->powers[pw_super])
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
|
||||
HU_SetCEchoFlags(0);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
|
||||
}*/
|
||||
|
||||
if (player->pflags & PF_TIMEOVER)
|
||||
{
|
||||
mobj_t *boom;
|
||||
@@ -2812,44 +2338,8 @@ void P_RemoveShield(player_t *player)
|
||||
player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK;
|
||||
}
|
||||
|
||||
/*
|
||||
static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) // SRB2kart - unused.
|
||||
{
|
||||
// Must do pain first to set flashing -- P_RemoveShield can cause damage
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
||||
P_RemoveShield(player);
|
||||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if (source && (source->type == MT_SPIKE || (source->type == MT_NULL && source->threshold == 43))) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
else
|
||||
S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss.
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, 25);
|
||||
}
|
||||
}
|
||||
if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, cv_match_scoring.value == 1 ? 25 : 50);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
{
|
||||
//const UINT8 scoremultiply = ((K_IsWantedPlayer(player) && !trapitem) : 2 ? 1);
|
||||
|
||||
if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])))
|
||||
{
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
@@ -2860,26 +2350,8 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
}
|
||||
|
||||
/*if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, scoremultiply);
|
||||
}
|
||||
|
||||
if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
|
||||
{
|
||||
P_PlayerFlagBurst(player, false);
|
||||
if (source && source->player)
|
||||
{
|
||||
// Award no points when players shoot each other when cv_friendlyfire is on.
|
||||
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
|
||||
P_AddPlayerScore(source->player, scoremultiply);
|
||||
}
|
||||
}*/
|
||||
|
||||
// Ring loss sound plays despite hitting spikes
|
||||
P_PlayRinglossSound(player->mo); // Ringledingle!
|
||||
P_PlayRinglossSound(player->mo, source); // Ringledingle!
|
||||
}
|
||||
|
||||
/** Damages an object, which may or may not be a player.
|
||||
@@ -3677,32 +3149,30 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
|
||||
P_SetTarget(&flag->target, player->mo);
|
||||
|
||||
// Flag text
|
||||
char plname[MAXPLAYERNAME+4];
|
||||
const char *flagtext;
|
||||
char flagcolor;
|
||||
|
||||
snprintf(plname, sizeof(plname), "%s%s%s",
|
||||
CTFTEAMCODE(player),
|
||||
player_names[player - players],
|
||||
CTFTEAMENDCODE(player));
|
||||
|
||||
if (type == MT_REDFLAG)
|
||||
{
|
||||
char plname[MAXPLAYERNAME+4];
|
||||
const char *flagtext;
|
||||
char flagcolor;
|
||||
|
||||
snprintf(plname, sizeof(plname), "%s%s%s",
|
||||
CTFTEAMCODE(player),
|
||||
player_names[player - players],
|
||||
CTFTEAMENDCODE(player));
|
||||
|
||||
if (type == MT_REDFLAG)
|
||||
{
|
||||
flagtext = M_GetText("Red flag");
|
||||
flagcolor = '\x85';
|
||||
}
|
||||
else
|
||||
{
|
||||
flagtext = M_GetText("Blue flag");
|
||||
flagcolor = '\x84';
|
||||
}
|
||||
|
||||
if (toss)
|
||||
CONS_Printf(M_GetText("%s tossed the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
|
||||
else
|
||||
CONS_Printf(M_GetText("%s dropped the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
|
||||
flagtext = M_GetText("Red flag");
|
||||
flagcolor = '\x85';
|
||||
}
|
||||
else
|
||||
{
|
||||
flagtext = M_GetText("Blue flag");
|
||||
flagcolor = '\x84';
|
||||
}
|
||||
|
||||
if (toss)
|
||||
CONS_Printf(M_GetText("%s tossed the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
|
||||
else
|
||||
CONS_Printf(M_GetText("%s dropped the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
|
||||
|
||||
player->gotflag = 0;
|
||||
|
||||
|
||||
+8
-5
@@ -70,6 +70,7 @@ extern thinker_t thinkercap;
|
||||
void P_InitThinkers(void);
|
||||
void P_AddThinker(thinker_t *thinker);
|
||||
void P_RemoveThinker(thinker_t *thinker);
|
||||
void P_UnlinkThinker(thinker_t *thinker);
|
||||
|
||||
//
|
||||
// P_USER
|
||||
@@ -143,6 +144,8 @@ extern consvar_t cv_tiltsmoothing;
|
||||
|
||||
extern consvar_t cv_actionmovie;
|
||||
|
||||
extern consvar_t cv_lookbackmom;
|
||||
|
||||
extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate;
|
||||
extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate;
|
||||
extern fixed_t t_cam3_dist, t_cam3_height, t_cam3_rotate;
|
||||
@@ -215,7 +218,7 @@ boolean P_PlayerMoving(INT32 pnum);
|
||||
void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range);
|
||||
|
||||
void P_PlayLivesJingle(player_t *player);
|
||||
void P_PlayRinglossSound(mobj_t *source);
|
||||
void P_PlayRinglossSound(mobj_t *source, mobj_t *damager);
|
||||
void P_PlayDeathSound(mobj_t *source);
|
||||
void P_PlayVictorySound(mobj_t *source);
|
||||
|
||||
@@ -239,19 +242,19 @@ void P_RespawnSpecials(void);
|
||||
|
||||
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
|
||||
|
||||
//mobj_t *P_SpawnShadowMobj(mobj_t * caster);
|
||||
mobj_t *P_SpawnShadowMobj(mobj_t * caster);
|
||||
|
||||
void P_RecalcPrecipInSector(sector_t *sector);
|
||||
void P_PrecipitationEffects(void);
|
||||
|
||||
void P_RemoveMobj(mobj_t *th);
|
||||
boolean P_MobjWasRemoved(mobj_t *th);
|
||||
boolean P_MobjWasRemoved(const mobj_t *th);
|
||||
void P_RemoveSavegameMobj(mobj_t *th);
|
||||
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
|
||||
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
|
||||
//void P_RunShields(void);
|
||||
void P_RunOverlays(void);
|
||||
//void P_RunShadows(void);
|
||||
void P_RunShadows(void);
|
||||
void P_MobjThinker(mobj_t *mobj);
|
||||
boolean P_RailThinker(mobj_t *mobj);
|
||||
void P_PushableThinker(mobj_t *mobj);
|
||||
@@ -288,7 +291,7 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype
|
||||
#define P_SpawnNameFinder(s,t) P_SPMAngle(s,t,s->angle,true,0)
|
||||
#endif
|
||||
void P_ColorTeamMissile(mobj_t *missile, player_t *source);
|
||||
SINT8 P_MobjFlip(mobj_t *mobj);
|
||||
SINT8 P_MobjFlip(const mobj_t *mobj);
|
||||
fixed_t P_GetMobjGravity(mobj_t *mo);
|
||||
FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type);
|
||||
|
||||
|
||||
+6
-86
@@ -319,78 +319,6 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void P_DoTailsCarry(player_t *sonic, player_t *tails)
|
||||
{
|
||||
INT32 p;
|
||||
fixed_t zdist; // z distance between the two players' bottoms
|
||||
|
||||
if ((tails->pflags & PF_CARRIED) && tails->mo->tracer == sonic->mo)
|
||||
return;
|
||||
if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo)
|
||||
return;
|
||||
if (tails->bot == 1)
|
||||
return;
|
||||
|
||||
if (sonic->pflags & PF_NIGHTSMODE)
|
||||
return;
|
||||
|
||||
if (sonic->mo->tracer && sonic->mo->tracer->type == MT_TUBEWAYPOINT
|
||||
&& !(sonic->pflags & PF_ROPEHANG))
|
||||
return; // don't steal players from zoomtubes!
|
||||
|
||||
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP))
|
||||
return; // Both should be in same gravity
|
||||
|
||||
if (tails->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
if (tails->mo->ceilingz - (tails->mo->z + tails->mo->height) < sonic->mo->height-FixedMul(2*FRACUNIT, sonic->mo->scale))
|
||||
return;
|
||||
}
|
||||
else if (tails->mo->z - tails->mo->floorz < sonic->mo->height-FixedMul(2*FRACUNIT, sonic->mo->scale))
|
||||
return; // No room to pick up this guy!
|
||||
|
||||
// Search in case another player is already being carried by this fox.
|
||||
for (p = 0; p < MAXPLAYERS; p++)
|
||||
if (playeringame[p] && players[p].mo
|
||||
&& players[p].pflags & PF_CARRIED && players[p].mo->tracer == tails->mo)
|
||||
return;
|
||||
|
||||
if (tails->mo->eflags & MFE_VERTICALFLIP)
|
||||
zdist = (sonic->mo->z + sonic->mo->height) - (tails->mo->z + tails->mo->height);
|
||||
else
|
||||
zdist = tails->mo->z - sonic->mo->z;
|
||||
|
||||
if (zdist <= sonic->mo->height + FixedMul(FRACUNIT, sonic->mo->scale)
|
||||
&& zdist > sonic->mo->height*2/3
|
||||
&& P_MobjFlip(tails->mo)*sonic->mo->momz <= 0)
|
||||
{
|
||||
// Why block opposing teams from tailsflying each other?
|
||||
// Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows.
|
||||
if (tails->spectator || sonic->spectator || G_RaceGametype()) // SRB2kart
|
||||
sonic->pflags &= ~PF_CARRIED;
|
||||
else
|
||||
{
|
||||
if (sonic-players == consoleplayer && botingame)
|
||||
//CV_SetValue(&cv_analog2, false);
|
||||
P_ResetPlayer(sonic);
|
||||
P_SetTarget(&sonic->mo->tracer, tails->mo);
|
||||
sonic->pflags |= PF_CARRIED;
|
||||
S_StartSound(sonic->mo, sfx_s3k4a);
|
||||
P_UnsetThingPosition(sonic->mo);
|
||||
sonic->mo->x = tails->mo->x;
|
||||
sonic->mo->y = tails->mo->y;
|
||||
P_SetThingPosition(sonic->mo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (sonic-players == consoleplayer && botingame)
|
||||
//CV_SetValue(&cv_analog2, true);
|
||||
sonic->pflags &= ~PF_CARRIED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// PIT_CheckThing
|
||||
//
|
||||
@@ -588,9 +516,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
// check for skulls slamming into things
|
||||
if (tmthing->flags2 & MF2_SKULLFLY)
|
||||
{
|
||||
/*if (tmthing->type == MT_EGGMOBILE) // Don't make Eggman stop!
|
||||
return true; // Let him RUN YOU RIGHT OVER. >:3
|
||||
else*/
|
||||
{
|
||||
// see if it went over / under
|
||||
if (tmthing->z > thing->z + thing->height)
|
||||
@@ -1676,7 +1601,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
||||
if (P_BoxOnLineSide(tmbbox, ld) != -1)
|
||||
return true;
|
||||
|
||||
if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag.
|
||||
if (tmthing->flags & MF_PAPERCOLLISION) // Caution! Turning whilst up against a wall will get you stuck. You probably shouldn't give the player this flag.
|
||||
{
|
||||
fixed_t cosradius, sinradius;
|
||||
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
|
||||
@@ -2245,6 +2170,9 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||
|
||||
floatok = false;
|
||||
|
||||
if (dedicated) // this crashes so don't even try it
|
||||
return false;
|
||||
|
||||
if (twodlevel)
|
||||
itsatwodlevel = true;
|
||||
else
|
||||
@@ -2474,14 +2402,6 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
else if (P_PlayerTouchingSectorSpecial(thing->player, 1, 12)
|
||||
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 12)
|
||||
maxstep = 0;
|
||||
|
||||
// Don't 'step up' while springing,
|
||||
// Only step up "if needed".
|
||||
/* // SRB2kart - don't need
|
||||
if (thing->state == &states[S_PLAY_SPRING]
|
||||
&& P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale))
|
||||
maxstep = 0;
|
||||
*/
|
||||
}
|
||||
|
||||
if (thing->type == MT_SKIM)
|
||||
@@ -4143,7 +4063,7 @@ static inline boolean PIT_GetSectors(line_t *ld)
|
||||
tmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] ||
|
||||
tmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] ||
|
||||
tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
|
||||
return true;
|
||||
return true;
|
||||
|
||||
if (P_BoxOnLineSide(tmbbox, ld) != -1)
|
||||
return true;
|
||||
@@ -4178,7 +4098,7 @@ static inline boolean PIT_GetPrecipSectors(line_t *ld)
|
||||
preciptmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] ||
|
||||
preciptmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] ||
|
||||
preciptmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
|
||||
return true;
|
||||
return true;
|
||||
|
||||
if (P_BoxOnLineSide(preciptmbbox, ld) != -1)
|
||||
return true;
|
||||
|
||||
+618
-600
File diff suppressed because it is too large.
Load diff
+17
-25
@@ -254,28 +254,25 @@ typedef enum
|
||||
// PRECIPITATION flags ?! ?! ?!
|
||||
//
|
||||
typedef enum {
|
||||
// Don't draw.
|
||||
PCF_INVISIBLE = 1,
|
||||
// Above pit.
|
||||
PCF_PIT = 2,
|
||||
// Above FOF.
|
||||
PCF_FOF = 4,
|
||||
// Above MOVING FOF (this means we need to keep floorz up to date...)
|
||||
PCF_MOVINGFOF = 8,
|
||||
// Is rain.
|
||||
PCF_RAIN = 16,
|
||||
// Ran the thinker this tic.
|
||||
PCF_THUNK = 32,
|
||||
PCF_INVISIBLE = 1, // Don't draw.
|
||||
PCF_PIT = 1<<1, // Above pit.
|
||||
PCF_FOF = 1<<2, // Above FOF.
|
||||
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
|
||||
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
|
||||
PCF_THUNK = 1<<5, // Ran the thinker this tic.
|
||||
} precipflag_t;
|
||||
// Map Object definition.
|
||||
typedef struct mobj_s
|
||||
{
|
||||
// List: thinker links.
|
||||
thinker_t thinker;
|
||||
|
||||
mobjtype_t type;
|
||||
const mobjinfo_t *info; // &mobjinfo[mobj->type]
|
||||
|
||||
// Info for drawing: position.
|
||||
fixed_t x, y, z;
|
||||
fixed_t old_x, old_y, old_z, old_floorz; // position interpolation
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
fixed_t old_x2, old_y2, old_z2;
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
@@ -345,9 +342,6 @@ typedef struct mobj_s
|
||||
struct mobj_s *hnext;
|
||||
struct mobj_s *hprev;
|
||||
|
||||
mobjtype_t type;
|
||||
const mobjinfo_t *info; // &mobjinfo[mobj->type]
|
||||
|
||||
INT32 health; // for player this is rings + 1
|
||||
|
||||
// Movement direction, movement generation (zig-zagging).
|
||||
@@ -398,11 +392,6 @@ typedef struct mobj_s
|
||||
|
||||
boolean resetinterp; // if true, some fields should not be interpolated (see R_InterpolateMobjState implementation)
|
||||
boolean colorized; // Whether the mobj uses the rainbow colormap
|
||||
|
||||
boolean haveshadow;
|
||||
fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius
|
||||
boolean whiteshadow; // Use white shadow, set to true by default for fullbright objects
|
||||
|
||||
boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left
|
||||
boolean rollmodel; // OpenGL: Should this model rotate?
|
||||
|
||||
@@ -431,9 +420,12 @@ typedef struct precipmobj_s
|
||||
// List: thinker links.
|
||||
thinker_t thinker;
|
||||
|
||||
mobjtype_t type;
|
||||
const mobjinfo_t *info; // &mobjinfo[mobj->type]
|
||||
|
||||
// Info for drawing: position.
|
||||
fixed_t x, y, z;
|
||||
fixed_t old_x, old_y, old_z, old_floorz; // position interpolation
|
||||
fixed_t old_x, old_y, old_z; // position interpolation
|
||||
fixed_t old_x2, old_y2, old_z2;
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
@@ -484,6 +476,7 @@ typedef struct precipmobj_s
|
||||
INT32 tics; // state tic counter
|
||||
state_t *state;
|
||||
INT32 flags; // flags from mobjinfo tables
|
||||
tic_t lastThink;
|
||||
} precipmobj_t;
|
||||
|
||||
typedef struct actioncache_s
|
||||
@@ -523,10 +516,9 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb
|
||||
boolean P_BossTargetPlayer(mobj_t *actor, boolean closest);
|
||||
boolean P_SupermanLook4Players(mobj_t *actor);
|
||||
void P_DestroyRobots(void);
|
||||
void P_SnowThinker(precipmobj_t *mobj);
|
||||
void P_RainThinker(precipmobj_t *mobj);
|
||||
boolean P_PrecipThinker(precipmobj_t *mobj);
|
||||
void P_NullPrecipThinker(precipmobj_t *mobj);
|
||||
void P_RemovePrecipMobj(precipmobj_t *mobj);
|
||||
void P_FreePrecipMobj(precipmobj_t *mobj);
|
||||
void P_SetScale(mobj_t *mobj, fixed_t newscale);
|
||||
void P_XYMovement(mobj_t *mo);
|
||||
void P_EmeraldManager(void);
|
||||
|
||||
+84
-229
@@ -95,6 +95,8 @@ INT32 numPolyObjects;
|
||||
// Polyobject Blockmap -- initialized in P_LoadBlockMap
|
||||
polymaplink_t **polyblocklinks;
|
||||
|
||||
static size_t *KnownPolySides;
|
||||
static size_t KnownPolySidesCount;
|
||||
|
||||
//
|
||||
// Static Data
|
||||
@@ -152,6 +154,36 @@ FUNCINLINE static ATTRINLINE void PolyObj_AddThinker(thinker_t *th)
|
||||
thinkercap.next = th;
|
||||
}
|
||||
|
||||
static void FreeSideLists(void)
|
||||
{
|
||||
free(KnownPolySides);
|
||||
KnownPolySides = NULL;
|
||||
KnownPolySidesCount = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// InitSideLists [RH]
|
||||
//
|
||||
// Group sides by vertex and collect side that are known to belong to a
|
||||
// polyobject so that they can be initialized fast.
|
||||
//==========================================================================
|
||||
static void InitSideLists(void)
|
||||
{
|
||||
size_t i;
|
||||
FreeSideLists();
|
||||
KnownPolySides = malloc(numsegs * sizeof(KnownPolySides[0]));
|
||||
for (i = 0; i < numsegs; i++)
|
||||
{
|
||||
if (segs[i].linedef &&
|
||||
(segs[i].linedef->special == POLYOBJ_START_LINE ||
|
||||
segs[i].linedef->special == POLYOBJ_EXPLICIT_LINE))
|
||||
{
|
||||
KnownPolySides[KnownPolySidesCount++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_PointInsidePolyobj
|
||||
//
|
||||
@@ -512,11 +544,12 @@ static void Polyobj_findExplicit(polyobj_t *po)
|
||||
size_t numSegItems = 0;
|
||||
size_t numSegItemsAlloc = 0;
|
||||
|
||||
size_t i;
|
||||
size_t i, ii;
|
||||
|
||||
// first loop: save off all segs with polyobject's id number
|
||||
for (i = 0; i < numsegs; ++i)
|
||||
for (ii = 0; ii < KnownPolySidesCount; ii++)
|
||||
{
|
||||
i = KnownPolySides[ii];
|
||||
INT32 polyID, parentID;
|
||||
|
||||
if (segs[i].linedef->special != POLYOBJ_EXPLICIT_LINE)
|
||||
@@ -566,7 +599,7 @@ static void Polyobj_findExplicit(polyobj_t *po)
|
||||
//
|
||||
static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
|
||||
{
|
||||
size_t i;
|
||||
size_t i, ii;
|
||||
polyobj_t *po = &PolyObjects[num];
|
||||
|
||||
// don't spawn a polyobject more than once
|
||||
@@ -590,8 +623,9 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
|
||||
// 1. Search segs for "line start" special with tag matching this
|
||||
// polyobject's id number. If found, iterate through segs which
|
||||
// share common vertices and record them into the polyobject.
|
||||
for (i = 0; i < numsegs; ++i)
|
||||
for (ii = 0; ii < KnownPolySidesCount; ii++)
|
||||
{
|
||||
i = KnownPolySides[ii];
|
||||
seg_t *seg = &segs[i];
|
||||
INT32 polyID, parentID;
|
||||
|
||||
@@ -1415,7 +1449,10 @@ static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings)
|
||||
{
|
||||
// update seg angles (used only by renderer)
|
||||
for (i = 0; i < po->segCount; ++i)
|
||||
{
|
||||
po->segs[i]->angle += delta;
|
||||
P_UpdateSegLightOffset(po->segs[i]);
|
||||
}
|
||||
|
||||
// update polyobject's angle
|
||||
po->angle += delta;
|
||||
@@ -1514,29 +1551,29 @@ void Polyobj_InitLevel(void)
|
||||
// the mobj_t pointers on a queue for use below.
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mobj_t *mo = (mobj_t *)th;
|
||||
|
||||
if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM ||
|
||||
mo->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM)
|
||||
{
|
||||
mobj_t *mo = (mobj_t *)th;
|
||||
++numPolyObjects;
|
||||
|
||||
if (mo->info->doomednum == POLYOBJ_SPAWN_DOOMEDNUM ||
|
||||
mo->info->doomednum == POLYOBJ_SPAWNCRUSH_DOOMEDNUM)
|
||||
{
|
||||
++numPolyObjects;
|
||||
qitem = malloc(sizeof(mobjqitem_t));
|
||||
memset(qitem, 0, sizeof(mobjqitem_t));
|
||||
qitem->mo = mo;
|
||||
M_QueueInsert(&(qitem->mqitem), &spawnqueue);
|
||||
}
|
||||
else if (mo->info->doomednum == POLYOBJ_ANCHOR_DOOMEDNUM)
|
||||
{
|
||||
++numAnchors;
|
||||
|
||||
qitem = malloc(sizeof(mobjqitem_t));
|
||||
memset(qitem, 0, sizeof(mobjqitem_t));
|
||||
qitem->mo = mo;
|
||||
M_QueueInsert(&(qitem->mqitem), &spawnqueue);
|
||||
}
|
||||
else if (mo->info->doomednum == POLYOBJ_ANCHOR_DOOMEDNUM)
|
||||
{
|
||||
++numAnchors;
|
||||
|
||||
qitem = malloc(sizeof(mobjqitem_t));
|
||||
memset(qitem, 0, sizeof(mobjqitem_t));
|
||||
qitem->mo = mo;
|
||||
M_QueueInsert(&(qitem->mqitem), &anchorqueue);
|
||||
}
|
||||
qitem = malloc(sizeof(mobjqitem_t));
|
||||
memset(qitem, 0, sizeof(mobjqitem_t));
|
||||
qitem->mo = mo;
|
||||
M_QueueInsert(&(qitem->mqitem), &anchorqueue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1550,6 +1587,9 @@ void Polyobj_InitLevel(void)
|
||||
for (i = 0; i < numPolyObjects; ++i)
|
||||
PolyObjects[i].first = PolyObjects[i].next = numPolyObjects;
|
||||
|
||||
// [RH] Make this faster
|
||||
InitSideLists();
|
||||
|
||||
// setup polyobjects
|
||||
for (i = 0; i < numPolyObjects; ++i)
|
||||
{
|
||||
@@ -1558,6 +1598,9 @@ void Polyobj_InitLevel(void)
|
||||
Polyobj_spawnPolyObj(i, qitem->mo, qitem->mo->spawnpoint->angle);
|
||||
}
|
||||
|
||||
// [RH] Don't need the side lists anymore
|
||||
FreeSideLists();
|
||||
|
||||
// move polyobjects to spawn points
|
||||
for (i = 0; i < numAnchors; ++i)
|
||||
{
|
||||
@@ -1571,39 +1614,6 @@ void Polyobj_InitLevel(void)
|
||||
Polyobj_linkToBlockmap(&PolyObjects[i]);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// haleyjd 02/22/06: temporary debug
|
||||
printf("DEBUG: numPolyObjects = %d\n", numPolyObjects);
|
||||
for (i = 0; i < numPolyObjects; ++i)
|
||||
{
|
||||
INT32 j;
|
||||
polyobj_t *po = &PolyObjects[i];
|
||||
|
||||
printf("polyobj %d:\n", i);
|
||||
printf("id = %d, first = %d, next = %d\n", po->id, po->first, po->next);
|
||||
printf("segCount = %d, numSegsAlloc = %d\n", po->segCount, po->numSegsAlloc);
|
||||
for (j = 0; j < po->segCount; ++j)
|
||||
printf("\tseg %d: %p\n", j, po->segs[j]);
|
||||
printf("numVertices = %d, numVerticesAlloc = %d\n", po->numVertices, po->numVerticesAlloc);
|
||||
for (j = 0; j < po->numVertices; ++j)
|
||||
{
|
||||
printf("\tvtx %d: (%d, %d) / orig: (%d, %d)\n",
|
||||
j, po->vertices[j]->x>>FRACBITS, po->vertices[j]->y>>FRACBITS,
|
||||
po->origVerts[j].x>>FRACBITS, po->origVerts[j].y>>FRACBITS);
|
||||
}
|
||||
printf("numLines = %d, numLinesAlloc = %d\n", po->numLines, po->numLinesAlloc);
|
||||
for (j = 0; j < po->numLines; ++j)
|
||||
printf("\tline %d: %p\n", j, po->lines[j]);
|
||||
printf("spawnSpot = (%d, %d)\n", po->spawnSpot.x >> FRACBITS, po->spawnSpot.y >> FRACBITS);
|
||||
printf("centerPt = (%d, %d)\n", po->centerPt.x >> FRACBITS, po->centerPt.y >> FRACBITS);
|
||||
printf("attached = %d, linked = %d, validcount = %d, isBad = %d\n",
|
||||
po->attached, po->linked, po->validcount, po->isBad);
|
||||
printf("blockbox: [%d, %d, %d, %d]\n",
|
||||
po->blockbox[BOXLEFT], po->blockbox[BOXRIGHT], po->blockbox[BOXBOTTOM],
|
||||
po->blockbox[BOXTOP]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// done with mobj queues
|
||||
M_QueueFree(&spawnqueue);
|
||||
M_QueueFree(&anchorqueue);
|
||||
@@ -1789,12 +1799,12 @@ void T_PolyObjMove(polymove_t *th)
|
||||
//
|
||||
void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
{
|
||||
mobj_t *mo2;
|
||||
mobj_t *target = NULL;
|
||||
mobj_t *waypoint = NULL;
|
||||
thinker_t *wp;
|
||||
mobj_t *mo2;
|
||||
fixed_t adjustx, adjusty, adjustz;
|
||||
fixed_t momx, momy, momz, dist;
|
||||
thinker_t *wp;
|
||||
INT32 start;
|
||||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||
polyobj_t *oldpo = po;
|
||||
@@ -1811,7 +1821,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
if (!po->thinker)
|
||||
po->thinker = &th->thinker;
|
||||
|
||||
// Find out target first.
|
||||
@@ -1826,11 +1836,14 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence && mo2->health == th->pointnum)
|
||||
{
|
||||
target = mo2;
|
||||
break;
|
||||
}
|
||||
if (mo2->threshold != th->sequence)
|
||||
continue;
|
||||
|
||||
if (mo2->health != th->pointnum)
|
||||
continue;
|
||||
|
||||
target = mo2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!target)
|
||||
@@ -1896,37 +1909,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "Looking for next waypoint...\n");
|
||||
|
||||
// Find next waypoint
|
||||
for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1)
|
||||
{
|
||||
if (mo2->health == target->health - 1)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo2->health == target->health + 1)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false);
|
||||
|
||||
if (!waypoint && th->wrap) // If specified, wrap waypoints
|
||||
{
|
||||
@@ -1936,35 +1919,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
th->stophere = true;
|
||||
}
|
||||
|
||||
for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1)
|
||||
{
|
||||
if (waypoint == NULL)
|
||||
waypoint = mo2;
|
||||
else if (mo2->health > waypoint->health)
|
||||
waypoint = mo2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo2->health == 0)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
waypoint = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence);
|
||||
}
|
||||
else if (!waypoint && th->comeback) // Come back to the start
|
||||
{
|
||||
@@ -1973,36 +1928,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||
if (!th->continuous)
|
||||
th->comeback = false;
|
||||
|
||||
for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1)
|
||||
{
|
||||
if (mo2->health == target->health - 1)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo2->health == target->health + 1)
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
waypoint = (th->direction == -1) ? P_GetPreviousWaypoint(target, false) : P_GetNextWaypoint(target, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2452,11 +2378,9 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
polyobj_t *po;
|
||||
polyobj_t *oldpo;
|
||||
polywaypoint_t *th;
|
||||
mobj_t *mo2;
|
||||
mobj_t *first = NULL;
|
||||
mobj_t *last = NULL;
|
||||
mobj_t *target = NULL;
|
||||
thinker_t *wp;
|
||||
INT32 start;
|
||||
|
||||
if (!(po = Polyobj_GetForNum(pwdata->polyObjNum)))
|
||||
@@ -2482,10 +2406,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
th->polyObjNum = pwdata->polyObjNum;
|
||||
th->speed = pwdata->speed;
|
||||
th->sequence = pwdata->sequence; // Used to specify sequence #
|
||||
if (pwdata->reverse)
|
||||
th->direction = -1;
|
||||
else
|
||||
th->direction = 1;
|
||||
th->direction = pwdata->reverse ? -1 : 1;
|
||||
|
||||
th->comeback = pwdata->comeback;
|
||||
th->continuous = pwdata->continuous;
|
||||
@@ -2493,44 +2414,8 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
th->stophere = false;
|
||||
|
||||
// Find the first waypoint we need to use
|
||||
for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1) // highest waypoint #
|
||||
{
|
||||
if (mo2->health == 0)
|
||||
last = mo2;
|
||||
else
|
||||
{
|
||||
if (first == NULL)
|
||||
first = mo2;
|
||||
else if (mo2->health > first->health)
|
||||
first = mo2;
|
||||
}
|
||||
}
|
||||
else // waypoint 0
|
||||
{
|
||||
if (mo2->health == 0)
|
||||
first = mo2;
|
||||
else
|
||||
{
|
||||
if (last == NULL)
|
||||
last = mo2;
|
||||
else if (mo2->health > last->health)
|
||||
last = mo2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
first = (th->direction == -1) ? P_GetLastWaypoint(th->sequence) : P_GetFirstWaypoint(th->sequence);
|
||||
last = (th->direction == -1) ? P_GetFirstWaypoint(th->sequence) : P_GetLastWaypoint(th->sequence);
|
||||
|
||||
if (!first)
|
||||
{
|
||||
@@ -2564,36 +2449,6 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
|
||||
|
||||
// Find the actual target movement waypoint
|
||||
target = first;
|
||||
/*for (wp = thinkercap.next; wp != &thinkercap; wp = wp->next)
|
||||
{
|
||||
if (wp->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)wp;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == th->sequence)
|
||||
{
|
||||
if (th->direction == -1) // highest waypoint #
|
||||
{
|
||||
if (mo2->health == first->health - 1)
|
||||
{
|
||||
target = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // waypoint 0
|
||||
{
|
||||
if (mo2->health == first->health + 1)
|
||||
{
|
||||
target = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (!target)
|
||||
{
|
||||
|
||||
+152
-118
@@ -107,7 +107,7 @@ static inline void P_UnArchivePlayer(void)
|
||||
//
|
||||
// P_NetArchivePlayers
|
||||
//
|
||||
static void P_NetArchivePlayers(void)
|
||||
static void P_NetArchivePlayers(boolean resending)
|
||||
{
|
||||
INT32 i, j;
|
||||
UINT16 flags;
|
||||
@@ -117,6 +117,9 @@ static void P_NetArchivePlayers(void)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (resending)
|
||||
WRITESINT8(save_p, (SINT8)adminplayers[i]);
|
||||
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
@@ -124,6 +127,9 @@ static void P_NetArchivePlayers(void)
|
||||
|
||||
// no longer send ticcmds, player name, skin, or color
|
||||
|
||||
if (resending)
|
||||
WRITESTRINGN(save_p, player_names[i], MAXPLAYERNAME);
|
||||
|
||||
WRITEANGLE(save_p, players[i].aiming);
|
||||
WRITEANGLE(save_p, players[i].awayviewaiming);
|
||||
WRITEINT32(save_p, players[i].awayviewtics);
|
||||
@@ -148,6 +154,13 @@ static void P_NetArchivePlayers(void)
|
||||
WRITEUINT16(save_p, players[i].flashpal);
|
||||
WRITEUINT16(save_p, players[i].flashcount);
|
||||
|
||||
if (resending)
|
||||
{
|
||||
WRITEUINT8(save_p, players[i].skincolor);
|
||||
WRITEINT32(save_p, players[i].skin);
|
||||
}
|
||||
|
||||
|
||||
WRITEUINT32(save_p, players[i].score);
|
||||
WRITEFIXED(save_p, players[i].dashspeed);
|
||||
WRITEINT32(save_p, players[i].dashtime);
|
||||
@@ -285,7 +298,7 @@ static void P_NetArchivePlayers(void)
|
||||
//
|
||||
// P_NetUnArchivePlayers
|
||||
//
|
||||
static void P_NetUnArchivePlayers(void)
|
||||
static void P_NetUnArchivePlayers(boolean resending)
|
||||
{
|
||||
INT32 i, j;
|
||||
UINT16 flags;
|
||||
@@ -295,6 +308,8 @@ static void P_NetUnArchivePlayers(void)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (resending)
|
||||
adminplayers[i] = (INT32)READSINT8(save_p);
|
||||
// Do NOT memset player struct to 0
|
||||
// other areas may initialize data elsewhere
|
||||
//memset(&players[i], 0, sizeof (player_t));
|
||||
@@ -305,6 +320,9 @@ static void P_NetUnArchivePlayers(void)
|
||||
// sending player names, skin and color should not be necessary at all!
|
||||
// (that data is handled in the server config now)
|
||||
|
||||
if (resending)
|
||||
READSTRINGN(save_p, player_names[i], MAXPLAYERNAME);
|
||||
|
||||
players[i].aiming = READANGLE(save_p);
|
||||
players[i].awayviewaiming = READANGLE(save_p);
|
||||
players[i].awayviewtics = READINT32(save_p);
|
||||
@@ -329,6 +347,12 @@ static void P_NetUnArchivePlayers(void)
|
||||
players[i].flashpal = READUINT16(save_p);
|
||||
players[i].flashcount = READUINT16(save_p);
|
||||
|
||||
if (resending)
|
||||
{
|
||||
players[i].skincolor = READUINT8(save_p);
|
||||
players[i].skin = READINT32(save_p);
|
||||
}
|
||||
|
||||
players[i].score = READUINT32(save_p);
|
||||
players[i].dashspeed = READFIXED(save_p); // dashing speed
|
||||
players[i].dashtime = READINT32(save_p); // dashing speed
|
||||
@@ -499,35 +523,16 @@ static void P_NetArchiveWorld(void)
|
||||
UINT8 *put;
|
||||
|
||||
// reload the map just to see difference
|
||||
mapsector_t *ms;
|
||||
mapsidedef_t *msd;
|
||||
maplinedef_t *mld;
|
||||
virtres_t* virt = vres_GetMap(lastloadedmaplumpnum);
|
||||
mapsector_t *ms = (mapsector_t*) vres_Find(virt, "SECTORS")->data;
|
||||
mapsidedef_t *msd = (mapsidedef_t*) vres_Find(virt, "SIDEDEFS")->data;
|
||||
maplinedef_t *mld = (maplinedef_t*) vres_Find(virt, "LINEDEFS")->data;
|
||||
const sector_t *ss = sectors;
|
||||
UINT8 diff, diff2;
|
||||
|
||||
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
||||
put = save_p;
|
||||
|
||||
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
|
||||
{ // HACK: Open wad file rather quickly so we can get the data from the relevant lumps
|
||||
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
#define retrieve_mapdata(d, f)\
|
||||
d = Z_Malloc((f)->size, PU_CACHE, NULL); \
|
||||
M_Memcpy(d, wadData + (f)->filepos, (f)->size)
|
||||
retrieve_mapdata(ms, fileinfo + ML_SECTORS);
|
||||
retrieve_mapdata(mld, fileinfo + ML_LINEDEFS);
|
||||
retrieve_mapdata(msd, fileinfo + ML_SIDEDEFS);
|
||||
#undef retrieve_mapdata
|
||||
Z_Free(wadData); // we're done with this now
|
||||
}
|
||||
else // phew it's just a WAD
|
||||
{
|
||||
ms = W_CacheLumpNum(lastloadedmaplumpnum+ML_SECTORS, PU_CACHE);
|
||||
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
|
||||
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
|
||||
}
|
||||
|
||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||
{
|
||||
diff = diff2 = 0;
|
||||
@@ -737,6 +742,7 @@ static void P_NetArchiveWorld(void)
|
||||
WRITEUINT16(put, 0xffff);
|
||||
R_ClearTextureNumCache(false);
|
||||
|
||||
vres_Free(virt);
|
||||
save_p = put;
|
||||
}
|
||||
|
||||
@@ -1874,7 +1880,7 @@ static void P_NetArchiveThinkers(void)
|
||||
continue;
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection
|
||||
else if (th->function.acp1 != P_RemoveThinkerDelayed) // wait garbage collection
|
||||
I_Error("unknown thinker type %p", th->function.acp1);
|
||||
#endif
|
||||
}
|
||||
@@ -1899,8 +1905,11 @@ mobj_t *P_FindNewPosition(UINT32 oldposition)
|
||||
continue;
|
||||
|
||||
mobj = (mobj_t *)th;
|
||||
if (mobj->mobjnum == oldposition)
|
||||
return mobj;
|
||||
|
||||
if (mobj->mobjnum != oldposition)
|
||||
continue;
|
||||
|
||||
return mobj;
|
||||
}
|
||||
CONS_Debug(DBG_GAMELOGIC, "mobj not found\n");
|
||||
return NULL;
|
||||
@@ -2899,12 +2908,13 @@ static void P_NetUnArchiveThinkers(void)
|
||||
for (currentthinker = thinkercap.next; currentthinker != &thinkercap;
|
||||
currentthinker = currentthinker->next)
|
||||
{
|
||||
if (currentthinker->function.acp1 == (actionf_p1)T_ExecutorDelay)
|
||||
{
|
||||
delay = (void *)currentthinker;
|
||||
if ((mobjnum = (UINT32)(size_t)delay->caller))
|
||||
delay->caller = P_FindNewPosition(mobjnum);
|
||||
}
|
||||
if (currentthinker->function.acp1 != (actionf_p1)T_ExecutorDelay)
|
||||
continue;
|
||||
|
||||
delay = (void *)currentthinker;
|
||||
|
||||
if ((mobjnum = (UINT32)(size_t)delay->caller))
|
||||
delay->caller = P_FindNewPosition(mobjnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3013,11 +3023,11 @@ static inline void P_FinishMobjs(void)
|
||||
for (currentthinker = thinkercap.next; currentthinker != &thinkercap;
|
||||
currentthinker = currentthinker->next)
|
||||
{
|
||||
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
{
|
||||
mobj = (mobj_t *)currentthinker;
|
||||
mobj->info = &mobjinfo[mobj->type];
|
||||
}
|
||||
if (currentthinker->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mobj = (mobj_t *)currentthinker;
|
||||
mobj->info = &mobjinfo[mobj->type];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3031,69 +3041,69 @@ static void P_RelinkPointers(void)
|
||||
for (currentthinker = thinkercap.next; currentthinker != &thinkercap;
|
||||
currentthinker = currentthinker->next)
|
||||
{
|
||||
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
if (currentthinker->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mobj = (mobj_t *)currentthinker;
|
||||
|
||||
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
|
||||
continue;
|
||||
|
||||
if (mobj->tracer)
|
||||
{
|
||||
mobj = (mobj_t *)currentthinker;
|
||||
|
||||
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
|
||||
continue;
|
||||
|
||||
if (mobj->tracer)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->tracer;
|
||||
mobj->tracer = NULL;
|
||||
if (!P_SetTarget(&mobj->tracer, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "tracer not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->target)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->target;
|
||||
mobj->target = NULL;
|
||||
if (!P_SetTarget(&mobj->target, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "target not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->hnext)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->hnext;
|
||||
mobj->hnext = NULL;
|
||||
if (!P_SetTarget(&mobj->hnext, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->hprev)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->hprev;
|
||||
mobj->hprev = NULL;
|
||||
if (!P_SetTarget(&mobj->hprev, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->capsule)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->capsule;
|
||||
mobj->player->capsule = NULL;
|
||||
if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->axis1)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->axis1;
|
||||
mobj->player->axis1 = NULL;
|
||||
if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->axis2)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->axis2;
|
||||
mobj->player->axis2 = NULL;
|
||||
if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->awayviewmobj)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->awayviewmobj;
|
||||
mobj->player->awayviewmobj = NULL;
|
||||
if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type);
|
||||
}
|
||||
temp = (UINT32)(size_t)mobj->tracer;
|
||||
mobj->tracer = NULL;
|
||||
if (!P_SetTarget(&mobj->tracer, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "tracer not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->target)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->target;
|
||||
mobj->target = NULL;
|
||||
if (!P_SetTarget(&mobj->target, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "target not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->hnext)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->hnext;
|
||||
mobj->hnext = NULL;
|
||||
if (!P_SetTarget(&mobj->hnext, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->hprev)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->hprev;
|
||||
mobj->hprev = NULL;
|
||||
if (!P_SetTarget(&mobj->hprev, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->capsule)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->capsule;
|
||||
mobj->player->capsule = NULL;
|
||||
if (!P_SetTarget(&mobj->player->capsule, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "capsule not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->axis1)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->axis1;
|
||||
mobj->player->axis1 = NULL;
|
||||
if (!P_SetTarget(&mobj->player->axis1, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "axis1 not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->axis2)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->axis2;
|
||||
mobj->player->axis2 = NULL;
|
||||
if (!P_SetTarget(&mobj->player->axis2, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "axis2 not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player && mobj->player->awayviewmobj)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->awayviewmobj;
|
||||
mobj->player->awayviewmobj = NULL;
|
||||
if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3242,19 +3252,25 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
|
||||
playeringame[consoleplayer] = true;
|
||||
}
|
||||
|
||||
static void P_NetArchiveMisc(void)
|
||||
static void P_NetArchiveMisc(boolean resending)
|
||||
{
|
||||
UINT32 pig = 0;
|
||||
INT32 i;
|
||||
|
||||
WRITEUINT32(save_p, ARCHIVEBLOCK_MISC);
|
||||
|
||||
if (resending)
|
||||
WRITEUINT32(save_p, gametic);
|
||||
|
||||
WRITEINT16(save_p, gamemap);
|
||||
if (gamestate != GS_LEVEL)
|
||||
WRITEINT16(save_p, GS_WAITINGPLAYERS); // nice hack to put people back into waitingplayers
|
||||
else
|
||||
WRITEINT16(save_p, gamestate);
|
||||
|
||||
if (resending)
|
||||
WRITEINT16(save_p, gametype);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
pig |= (playeringame[i] != 0)<<i;
|
||||
WRITEUINT32(save_p, pig);
|
||||
@@ -3337,14 +3353,18 @@ static void P_NetArchiveMisc(void)
|
||||
WRITEUINT8(save_p, 0x2e);
|
||||
}
|
||||
|
||||
FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(void)
|
||||
FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(boolean reloading)
|
||||
{
|
||||
UINT32 pig;
|
||||
INT32 i;
|
||||
UINT8 *old_save_p;
|
||||
|
||||
if (READUINT32(save_p) != ARCHIVEBLOCK_MISC)
|
||||
I_Error("Bad $$$.sav at archive block Misc");
|
||||
|
||||
if (reloading)
|
||||
gametic = READUINT32(save_p);
|
||||
|
||||
gamemap = READINT16(save_p);
|
||||
|
||||
// gamemap changed; we assume that its map header is always valid,
|
||||
@@ -3354,10 +3374,14 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(void)
|
||||
|
||||
// tell the sound code to reset the music since we're skipping what
|
||||
// normally sets this flag
|
||||
mapmusflags |= MUSIC_RELOADRESET;
|
||||
if (!reloading)
|
||||
mapmusflags |= MUSIC_RELOADRESET;
|
||||
|
||||
G_SetGamestate(READINT16(save_p));
|
||||
|
||||
if (reloading)
|
||||
gametype = READINT16(save_p);
|
||||
|
||||
pig = READUINT32(save_p);
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
@@ -3371,8 +3395,16 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(void)
|
||||
|
||||
encoremode = (boolean)READUINT8(save_p);
|
||||
|
||||
if (!P_SetupLevel(true))
|
||||
// FIXME: save_p should not be global!!!
|
||||
old_save_p = save_p;
|
||||
|
||||
if (!P_SetupLevel(true, reloading))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
save_p = old_save_p;
|
||||
|
||||
// get the time
|
||||
leveltime = READUINT32(save_p);
|
||||
@@ -3455,31 +3487,33 @@ void P_SaveGame(void)
|
||||
WRITEUINT8(save_p, 0x1d); // consistency marker
|
||||
}
|
||||
|
||||
void P_SaveNetGame(void)
|
||||
void P_SaveNetGame(boolean resending)
|
||||
{
|
||||
thinker_t *th;
|
||||
mobj_t *mobj;
|
||||
INT32 i = 1; // don't start from 0, it'd be confused with a blank pointer otherwise
|
||||
|
||||
CV_SaveNetVars(&save_p, false);
|
||||
P_NetArchiveMisc();
|
||||
P_NetArchiveMisc(resending);
|
||||
|
||||
// Assign the mobjnumber for pointer tracking
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
{
|
||||
mobj = (mobj_t *)th;
|
||||
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
|
||||
continue;
|
||||
mobj->mobjnum = i++;
|
||||
}
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mobj = (mobj_t *)th;
|
||||
|
||||
if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER)
|
||||
continue;
|
||||
|
||||
mobj->mobjnum = i++;
|
||||
}
|
||||
}
|
||||
|
||||
P_NetArchivePlayers();
|
||||
P_NetArchivePlayers(resending);
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
P_NetArchiveWorld();
|
||||
@@ -3514,12 +3548,12 @@ boolean P_LoadGame(INT16 mapoverride)
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean P_LoadNetGame(void)
|
||||
boolean P_LoadNetGame(boolean resending)
|
||||
{
|
||||
CV_LoadNetVars(&save_p);
|
||||
if (!P_NetUnArchiveMisc())
|
||||
if (!P_NetUnArchiveMisc(resending))
|
||||
return false;
|
||||
P_NetUnArchivePlayers();
|
||||
P_NetUnArchivePlayers(resending);
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
P_NetUnArchiveWorld();
|
||||
|
||||
+2
-2
@@ -22,9 +22,9 @@
|
||||
// These are the load / save game routines.
|
||||
|
||||
void P_SaveGame(void);
|
||||
void P_SaveNetGame(void);
|
||||
void P_SaveNetGame(boolean resending);
|
||||
boolean P_LoadGame(INT16 mapoverride);
|
||||
boolean P_LoadNetGame(void);
|
||||
boolean P_LoadNetGame(boolean resending);
|
||||
|
||||
mobj_t *P_FindNewPosition(UINT32 oldposition);
|
||||
|
||||
|
||||
+382
-733
File diff suppressed because it is too large.
Load diff
+6
-5
@@ -17,6 +17,9 @@
|
||||
#include "doomdata.h"
|
||||
#include "doomstat.h"
|
||||
#include "r_defs.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
extern SINT8 midgamejoin;
|
||||
|
||||
// map md5, sent to players via PT_SERVERINFO
|
||||
extern unsigned char mapmd5[16];
|
||||
@@ -30,6 +33,7 @@ extern boolean levelloading;
|
||||
extern UINT8 levelfadecol;
|
||||
|
||||
extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame
|
||||
extern virtres_t *curmapvirt;
|
||||
//
|
||||
// MAP used flats lookup table
|
||||
//
|
||||
@@ -55,11 +59,8 @@ extern size_t nummapthings;
|
||||
extern mapthing_t *mapthings;
|
||||
|
||||
void P_SetupLevelSky(INT32 skynum, boolean global);
|
||||
#ifdef SCANTHINGS
|
||||
void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
|
||||
#endif
|
||||
void P_LoadThingsOnly(void);
|
||||
boolean P_SetupLevel(boolean skipprecip);
|
||||
boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate);
|
||||
#ifdef HWRENDER
|
||||
void HWR_LoadLevel(void);
|
||||
#endif
|
||||
@@ -87,11 +88,11 @@ SINT8 P_PartialAddGetStage(void);
|
||||
|
||||
boolean P_RunSOC(const char *socfilename);
|
||||
void P_WriteThings(lumpnum_t lump);
|
||||
void P_UpdateSegLightOffset(seg_t *li);
|
||||
size_t P_PrecacheLevelFlats(void);
|
||||
void P_AllocMapHeader(INT16 i);
|
||||
|
||||
// Needed for NiGHTS
|
||||
void P_ReloadRings(void);
|
||||
void P_DeleteGrades(INT16 i);
|
||||
void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext);
|
||||
UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare);
|
||||
|
||||
+60
-12
@@ -27,11 +27,51 @@
|
||||
static pslope_t *slopelist = NULL;
|
||||
static UINT16 slopecount = 0;
|
||||
|
||||
// Calculate light
|
||||
static void P_UpdateSlopeLightOffset(pslope_t *slope)
|
||||
{
|
||||
const boolean ceiling = (slope->normal.z < 0);
|
||||
const UINT8 contrast = 8;
|
||||
|
||||
fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT;
|
||||
fixed_t zMul = FRACUNIT;
|
||||
angle_t slopeDir = ANGLE_MAX;
|
||||
fixed_t extralight = 0;
|
||||
|
||||
if (slope->normal.z == 0)
|
||||
{
|
||||
slope->lightOffset = 0;
|
||||
#ifdef HWRENDER
|
||||
slope->hwLightOffset = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
slopeDir = R_PointToAngle2(0, 0, abs(slope->normal.y), abs(slope->normal.x));
|
||||
if (ceiling == true)
|
||||
{
|
||||
slopeDir ^= ANGLE_180;
|
||||
}
|
||||
|
||||
zMul = min(FRACUNIT, abs(slope->zdelta)*3/2); // *3/2, to make 60 degree slopes match walls.
|
||||
contrastFixed = FixedMul(contrastFixed, zMul);
|
||||
extralight = -contrastFixed + FixedMul(FixedDiv(AngleFixed(slopeDir), ANGLE_90), (contrastFixed * 2));
|
||||
|
||||
// Between -2 and 2 for software, -8 and 8 for hardware
|
||||
slope->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
#ifdef HWRENDER
|
||||
slope->hwLightOffset = FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Calculate line normal
|
||||
void P_CalculateSlopeNormal(pslope_t *slope) {
|
||||
void P_CalculateSlopeNormal(pslope_t *slope)
|
||||
{
|
||||
slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT);
|
||||
slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), -slope->d.x);
|
||||
slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), -slope->d.y);
|
||||
|
||||
P_UpdateSlopeLightOffset(slope);
|
||||
}
|
||||
|
||||
// With a vertex slope that has its vertices set, configure relevant slope info
|
||||
@@ -89,18 +129,24 @@ static void P_ReconfigureVertexSlope(pslope_t *slope)
|
||||
slope->real_xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180;
|
||||
slope->real_zangle = InvAngle(R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta));
|
||||
|
||||
if (slope->normal.x == 0 && slope->normal.y == 0) { // Set some defaults for a non-sloped "slope"
|
||||
if (slope->normal.x == 0 && slope->normal.y == 0) // Set some defaults for a non-sloped "slope"
|
||||
{
|
||||
slope->zangle = slope->xydirection = 0;
|
||||
slope->zdelta = slope->d.x = slope->d.y = 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
slope->extent = extent;
|
||||
slope->xydirection = slope->real_xydirection;
|
||||
slope->zangle = slope->real_zangle;
|
||||
}
|
||||
|
||||
P_UpdateSlopeLightOffset(slope);
|
||||
}
|
||||
|
||||
// Recalculate dynamic slopes
|
||||
void P_RunDynamicSlopes(void) {
|
||||
void P_RunDynamicSlopes(void)
|
||||
{
|
||||
pslope_t *slope;
|
||||
|
||||
for (slope = slopelist; slope; slope = slope->next) {
|
||||
@@ -284,7 +330,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
origin.y = line->v1->y + (line->v2->y - line->v1->y)/2;
|
||||
|
||||
// For FOF slopes, make a special function to copy to the xy origin & direction relative to the position of the FOF on the map!
|
||||
if(frontfloor || frontceil)
|
||||
if (frontfloor || frontceil)
|
||||
{
|
||||
line->frontsector->hasslope = true; // Tell the software renderer that we're sloped
|
||||
|
||||
@@ -308,7 +354,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
|
||||
// TODO: We take origin and point 's xy values and translate them to the center of an FOF!
|
||||
|
||||
if(frontfloor)
|
||||
if (frontfloor)
|
||||
{
|
||||
fixed_t highest, lowest;
|
||||
size_t l;
|
||||
@@ -369,7 +415,8 @@ void P_SpawnSlope_Line(int linenum)
|
||||
|
||||
P_CalculateSlopeNormal(fslope);
|
||||
}
|
||||
if(frontceil)
|
||||
|
||||
if (frontceil)
|
||||
{
|
||||
fixed_t highest, lowest;
|
||||
size_t l;
|
||||
@@ -416,7 +463,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
P_CalculateSlopeNormal(cslope);
|
||||
}
|
||||
}
|
||||
if(backfloor || backceil)
|
||||
if (backfloor || backceil)
|
||||
{
|
||||
line->backsector->hasslope = true; // Tell the software renderer that we're sloped
|
||||
|
||||
@@ -439,7 +486,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
direction.x = -direction.x;
|
||||
direction.y = -direction.y;
|
||||
|
||||
if(backfloor)
|
||||
if (backfloor)
|
||||
{
|
||||
fixed_t highest, lowest;
|
||||
size_t l;
|
||||
@@ -484,7 +531,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||
|
||||
P_CalculateSlopeNormal(fslope);
|
||||
}
|
||||
if(backceil)
|
||||
if (backceil)
|
||||
{
|
||||
fixed_t highest, lowest;
|
||||
size_t l;
|
||||
@@ -634,7 +681,8 @@ pslope_t *P_SlopeById(UINT16 id)
|
||||
}
|
||||
|
||||
// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes
|
||||
void P_ResetDynamicSlopes(void) {
|
||||
void P_ResetDynamicSlopes(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
slopelist = NULL;
|
||||
@@ -934,4 +982,4 @@ void P_ButteredSlope(mobj_t *mo)
|
||||
P_Thrust(mo, mo->standingslope->xydirection, thrust);
|
||||
}
|
||||
|
||||
// EOF
|
||||
// EOF
|
||||
+75
-577
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -32,7 +32,7 @@ void P_InitPicAnims(void);
|
||||
void P_SetupLevelFlatAnims(void);
|
||||
|
||||
// at map load
|
||||
void P_SpawnSpecials(INT32 fromnetsave);
|
||||
void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate);
|
||||
|
||||
// every tic
|
||||
void P_UpdateSpecials(void);
|
||||
|
||||
+10
-9
@@ -84,10 +84,11 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
||||
{
|
||||
if (thing->player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
if (camera[i].chase)
|
||||
P_ResetCamera(thing->player, &camera[i]);
|
||||
|
||||
R_ResetViewInterpolation(i + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
// don't run in place after a teleport
|
||||
@@ -157,14 +158,14 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
|
||||
// move chasecam at new player location
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (thing->player == &players[displayplayers[i]])
|
||||
{
|
||||
localangle[i] = angle;
|
||||
if (camera[i].chase)
|
||||
P_ResetCamera(thing->player, &camera[i]);
|
||||
R_ResetViewInterpolation(i + 1);
|
||||
break;
|
||||
}
|
||||
if (thing->player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
localangle[i] = angle;
|
||||
if (camera[i].chase)
|
||||
P_ResetCamera(thing->player, &camera[i]);
|
||||
|
||||
R_ResetViewInterpolation(i + 1);
|
||||
}
|
||||
|
||||
// don't run in place after a teleport
|
||||
|
||||
+104
-280
@@ -18,10 +18,12 @@
|
||||
#include "z_zone.h"
|
||||
#include "s_sound.h"
|
||||
#include "st_stuff.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_polyobj.h"
|
||||
#include "m_random.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "k_director.h"
|
||||
#include "k_kart.h"
|
||||
#include "i_system.h"
|
||||
#include "r_main.h"
|
||||
@@ -32,6 +34,9 @@
|
||||
// Object place
|
||||
#include "m_cheat.h"
|
||||
|
||||
// Dynamic slopes
|
||||
#include "p_slopes.h"
|
||||
|
||||
tic_t leveltime;
|
||||
|
||||
//
|
||||
@@ -63,8 +68,6 @@ void Command_Numthinkers_f(void)
|
||||
CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n"));
|
||||
CONS_Printf(
|
||||
"\t1: P_MobjThinker\n"
|
||||
/*"\t2: P_RainThinker\n"
|
||||
"\t3: P_SnowThinker\n"*/
|
||||
"\t2: P_NullPrecipThinker\n"
|
||||
"\t3: T_Friction\n"
|
||||
"\t4: T_Pusher\n"
|
||||
@@ -80,14 +83,6 @@ void Command_Numthinkers_f(void)
|
||||
action = (actionf_p1)P_MobjThinker;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker");
|
||||
break;
|
||||
/*case 2:
|
||||
action = (actionf_p1)P_RainThinker;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker");
|
||||
break;
|
||||
case 3:
|
||||
action = (actionf_p1)P_SnowThinker;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker");
|
||||
break;*/
|
||||
case 2:
|
||||
action = (actionf_p1)P_NullPrecipThinker;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker");
|
||||
@@ -221,23 +216,41 @@ static thinker_t *currentthinker;
|
||||
// remove it, and set currentthinker to one node preceeding it, so
|
||||
// that the next step in P_RunThinkers() will get its successor.
|
||||
//
|
||||
void P_RemoveThinkerDelayed(void *pthinker)
|
||||
void P_RemoveThinkerDelayed(thinker_t *thinker)
|
||||
{
|
||||
thinker_t *thinker = pthinker;
|
||||
if (!thinker->references)
|
||||
{
|
||||
{
|
||||
/* Remove from main thinker list */
|
||||
thinker_t *next = thinker->next;
|
||||
/* Note that currentthinker is guaranteed to point to us,
|
||||
* and since we're freeing our memory, we had better change that. So
|
||||
* point it to thinker->prev, so the iterator will correctly move on to
|
||||
* thinker->prev->next = thinker->next */
|
||||
(next->prev = currentthinker = thinker->prev)->next = next;
|
||||
}
|
||||
R_DestroyLevelInterpolators(thinker);
|
||||
Z_Free(thinker);
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
if (thinker->next)
|
||||
thinker->next = NULL;
|
||||
else if (thinker->references) // Usually gets cleared up in one frame; what's going on here, then?
|
||||
CONS_Printf("Number of potentially faulty references: %d\n", thinker->references);
|
||||
#endif
|
||||
if (thinker->references)
|
||||
return;
|
||||
|
||||
/* Remove from main thinker list */
|
||||
thinker_t *next = thinker->next;
|
||||
/* Note that currentthinker is guaranteed to point to us,
|
||||
* and since we're freeing our memory, we had better change that. So
|
||||
* point it to thinker->prev, so the iterator will correctly move on to
|
||||
* thinker->prev->next = thinker->next */
|
||||
(next->prev = currentthinker = thinker->prev)->next = next;
|
||||
R_DestroyLevelInterpolators(thinker);
|
||||
Z_Free(thinker);
|
||||
}
|
||||
|
||||
//
|
||||
// P_UnlinkThinker()
|
||||
//
|
||||
// Actually removes thinker from the list and frees its memory.
|
||||
//
|
||||
void P_UnlinkThinker(thinker_t *thinker)
|
||||
{
|
||||
thinker_t *next = thinker->next;
|
||||
|
||||
I_Assert(thinker->references == 0);
|
||||
|
||||
(next->prev = thinker->prev)->next = next;
|
||||
Z_Free(thinker);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -255,7 +268,7 @@ void P_RemoveThinkerDelayed(void *pthinker)
|
||||
void P_RemoveThinker(thinker_t *thinker)
|
||||
{
|
||||
LUA_InvalidateUserdata(thinker);
|
||||
thinker->function.acp1 = P_RemoveThinkerDelayed;
|
||||
thinker->function.acp1 = (actionf_p1)P_RemoveThinkerDelayed;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -310,265 +323,76 @@ static inline void P_RunThinkers(void)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_DoAutobalanceTeams()
|
||||
//
|
||||
// Determine if the teams are unbalanced, and if so, move a player to the other team.
|
||||
//
|
||||
/*static void P_DoAutobalanceTeams(void)
|
||||
static inline void P_DeviceRumbleTick(void)
|
||||
{
|
||||
changeteam_union NetPacket;
|
||||
UINT16 usvalue;
|
||||
INT32 i=0;
|
||||
INT32 red=0, blue=0;
|
||||
INT32 redarray[MAXPLAYERS], bluearray[MAXPLAYERS];
|
||||
INT32 redflagcarrier = 0, blueflagcarrier = 0;
|
||||
INT32 totalred = 0, totalblue = 0;
|
||||
UINT8 i;
|
||||
|
||||
NetPacket.value.l = NetPacket.value.b = 0;
|
||||
memset(redarray, 0, sizeof(redarray));
|
||||
memset(bluearray, 0, sizeof(bluearray));
|
||||
|
||||
// Only do it if we have enough room in the net buffer to send it.
|
||||
// Otherwise, come back next time and try again.
|
||||
if (sizeof(usvalue) > GetFreeXCmdSize())
|
||||
if (I_NumJoys() == 0 || (cv_rumble[0].value == 0 && cv_rumble[1].value == 0 && cv_rumble[2].value == 0 && cv_rumble[3].value == 0))
|
||||
{
|
||||
return;
|
||||
|
||||
//We have to store the players in an array with the rest of their team.
|
||||
//We can then pick a random player to be forced to change teams.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && players[i].ctfteam)
|
||||
{
|
||||
if (players[i].ctfteam == 1)
|
||||
{
|
||||
if (!players[i].gotflag)
|
||||
{
|
||||
redarray[red] = i; //store the player's node.
|
||||
red++;
|
||||
}
|
||||
else
|
||||
redflagcarrier++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!players[i].gotflag)
|
||||
{
|
||||
bluearray[blue] = i; //store the player's node.
|
||||
blue++;
|
||||
}
|
||||
else
|
||||
blueflagcarrier++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
totalred = red + redflagcarrier;
|
||||
totalblue = blue + blueflagcarrier;
|
||||
|
||||
if ((abs(totalred - totalblue) > cv_autobalance.value))
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (totalred > totalblue)
|
||||
{
|
||||
i = M_RandomKey(red);
|
||||
NetPacket.packet.newteam = 2;
|
||||
NetPacket.packet.playernum = redarray[i];
|
||||
NetPacket.packet.verification = true;
|
||||
NetPacket.packet.autobalance = true;
|
||||
player_t *player = &players[displayplayers[i]];
|
||||
UINT16 low = 0;
|
||||
UINT16 high = 0;
|
||||
|
||||
usvalue = SHORT(NetPacket.value.l|NetPacket.value.b);
|
||||
SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue));
|
||||
}
|
||||
|
||||
if (totalblue > totalred)
|
||||
{
|
||||
i = M_RandomKey(blue);
|
||||
NetPacket.packet.newteam = 1;
|
||||
NetPacket.packet.playernum = bluearray[i];
|
||||
NetPacket.packet.verification = true;
|
||||
NetPacket.packet.autobalance = true;
|
||||
|
||||
usvalue = SHORT(NetPacket.value.l|NetPacket.value.b);
|
||||
SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_DoTeamscrambling()
|
||||
//
|
||||
// If a team scramble has been started, scramble one person from the
|
||||
// pre-made scramble array. Said array is created in TeamScramble_OnChange()
|
||||
//
|
||||
void P_DoTeamscrambling(void)
|
||||
{
|
||||
changeteam_union NetPacket;
|
||||
UINT16 usvalue;
|
||||
NetPacket.value.l = NetPacket.value.b = 0;
|
||||
|
||||
// Only do it if we have enough room in the net buffer to send it.
|
||||
// Otherwise, come back next time and try again.
|
||||
if (sizeof(usvalue) > GetFreeXCmdSize())
|
||||
return;
|
||||
|
||||
if (scramblecount < scrambletotal)
|
||||
{
|
||||
if (players[scrambleplayers[scramblecount]].ctfteam != scrambleteams[scramblecount])
|
||||
{
|
||||
NetPacket.packet.newteam = scrambleteams[scramblecount];
|
||||
NetPacket.packet.playernum = scrambleplayers[scramblecount];
|
||||
NetPacket.packet.verification = true;
|
||||
NetPacket.packet.scrambled = true;
|
||||
|
||||
usvalue = SHORT(NetPacket.value.l|NetPacket.value.b);
|
||||
SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue));
|
||||
}
|
||||
|
||||
scramblecount++; //Increment, and get to the next player when we come back here next time.
|
||||
}
|
||||
else
|
||||
CV_SetValue(&cv_teamscramble, 0);
|
||||
}
|
||||
|
||||
static inline void P_DoSpecialStageStuff(void)
|
||||
{
|
||||
boolean inwater = false;
|
||||
INT32 i;
|
||||
|
||||
// Can't drown in a special stage
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
if (!P_IsLocalPlayer(player))
|
||||
continue;
|
||||
|
||||
players[i].powers[pw_underwater] = players[i].powers[pw_spacetime] = 0;
|
||||
}
|
||||
if (G_GetDeviceForPlayer(i) == 0)
|
||||
continue;
|
||||
|
||||
if (sstimer < 15*TICRATE+6 && sstimer > 7 && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC))
|
||||
S_SpeedMusic(1.4f);
|
||||
if (!playeringame[displayplayers[i]] || player->spectator)
|
||||
continue;
|
||||
|
||||
if (sstimer < 7 && sstimer > 0) // The special stage time is up!
|
||||
{
|
||||
sstimer = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (player->mo == NULL)
|
||||
continue;
|
||||
|
||||
if (player->exiting)
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
players[i].exiting = raceexittime+1;
|
||||
players[i].pflags &= ~PF_GLIDING;
|
||||
}
|
||||
|
||||
if (i == consoleplayer)
|
||||
S_StartSound(NULL, sfx_lose);
|
||||
G_PlayerDeviceRumble(i, low, high, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
|
||||
S_SpeedMusic(1.0f);
|
||||
|
||||
stagefailed = true;
|
||||
}
|
||||
|
||||
if (sstimer > 1) // As long as time isn't up...
|
||||
{
|
||||
UINT32 ssrings = 0;
|
||||
// Count up the rings of all the players and see if
|
||||
// they've collected the required amount.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
{
|
||||
ssrings += (players[i].mo->health-1);
|
||||
|
||||
// If in water, deplete timer 6x as fast.
|
||||
if ((players[i].mo->eflags & MFE_TOUCHWATER)
|
||||
|| (players[i].mo->eflags & MFE_UNDERWATER))
|
||||
inwater = true;
|
||||
}
|
||||
|
||||
if (ssrings >= totalrings && totalrings > 0)
|
||||
if (player->kartstuff[k_spinouttimer])
|
||||
{
|
||||
// Halt all the players
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
{
|
||||
players[i].mo->momx = players[i].mo->momy = 0;
|
||||
players[i].exiting = raceexittime+1;
|
||||
}
|
||||
|
||||
sstimer = 0;
|
||||
|
||||
P_GiveEmerald(true);
|
||||
low = high = 65536 / 4;
|
||||
}
|
||||
else if (player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2)))
|
||||
{
|
||||
low = high = 65536 / 8;
|
||||
}
|
||||
else if ((player->kartstuff[k_offroad] && !player->kartstuff[k_hyudorotimer])
|
||||
&& P_IsObjectOnGround(player->mo) && player->speed != 0)
|
||||
{
|
||||
low = high = 65536 / 64;
|
||||
}
|
||||
else if (player->kartstuff[k_brakedrift])
|
||||
{
|
||||
low = 0;
|
||||
high = 65536 / 256;
|
||||
}
|
||||
|
||||
// Decrement the timer
|
||||
if (!objectplacing)
|
||||
{
|
||||
if (inwater)
|
||||
sstimer -= 6;
|
||||
else
|
||||
sstimer--;
|
||||
}
|
||||
if (low == 0 && high == 0)
|
||||
continue;
|
||||
|
||||
G_PlayerDeviceRumble(i, low, high, 57); // hack alert! i just dont want this think constantly resetting the rumble lol
|
||||
}
|
||||
}
|
||||
|
||||
static inline void P_DoTagStuff(void)
|
||||
void P_RunChaseCameras(void)
|
||||
{
|
||||
INT32 i;
|
||||
UINT8 i;
|
||||
|
||||
// tell the netgame who the initial IT person is.
|
||||
if (leveltime == TICRATE)
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (players[i].pflags & PF_TAGIT)
|
||||
{
|
||||
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[i]); // Tell everyone who is it!
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//increment survivor scores
|
||||
if (leveltime % TICRATE == 0 && leveltime > (hidetime * TICRATE))
|
||||
{
|
||||
INT32 participants = 0;
|
||||
|
||||
for (i=0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator)
|
||||
participants++;
|
||||
}
|
||||
|
||||
for (i=0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator && players[i].playerstate == PST_LIVE
|
||||
&& !(players[i].pflags & (PF_TAGIT|PF_TAGGED)))
|
||||
//points given is the number of participating players divided by two.
|
||||
P_AddPlayerScore(&players[i], participants/2);
|
||||
}
|
||||
if (camera[i].chase)
|
||||
P_MoveChaseCamera(&players[displayplayers[i]], &camera[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void P_DoCTFStuff(void)
|
||||
{
|
||||
// Automatic team balance for CTF and team match
|
||||
if (leveltime % (TICRATE * 5) == 0) //only check once per five seconds for the sake of CPU conservation.
|
||||
{
|
||||
// Do not attempt to autobalance and scramble teams at the same time.
|
||||
// Only the server should execute this. No verified admins, please.
|
||||
if ((cv_autobalance.value && !cv_teamscramble.value) && cv_allowteamchange.value && server)
|
||||
P_DoAutobalanceTeams();
|
||||
}
|
||||
|
||||
// Team scramble code for team match and CTF.
|
||||
if ((leveltime % (TICRATE/7)) == 0)
|
||||
{
|
||||
// If we run out of time in the level, the beauty is that
|
||||
// the Y_Ticker() team scramble code will pick it up.
|
||||
if (cv_teamscramble.value && server)
|
||||
P_DoTeamscrambling();
|
||||
}
|
||||
}*/
|
||||
|
||||
//
|
||||
// P_Ticker
|
||||
//
|
||||
@@ -581,13 +405,6 @@ void P_Ticker(boolean run)
|
||||
if (playeringame[i])
|
||||
++players[i].jointime;
|
||||
|
||||
if (run)
|
||||
{
|
||||
// Update old view state BEFORE ticking so resetting
|
||||
// the old interpolation state from game logic works.
|
||||
R_UpdateViewInterpolation();
|
||||
}
|
||||
|
||||
if (objectplacing)
|
||||
{
|
||||
if (OP_FreezeObjectplace())
|
||||
@@ -683,6 +500,10 @@ void P_Ticker(boolean run)
|
||||
|
||||
if (run)
|
||||
{
|
||||
// Dynamic slopeness
|
||||
if (midgamejoin) // only run here if we joined midgame to fix some desynchs
|
||||
P_RunDynamicSlopes();
|
||||
|
||||
PS_START_TIMING(ps_thinkertime);
|
||||
P_RunThinkers();
|
||||
PS_STOP_TIMING(ps_thinkertime);
|
||||
@@ -692,6 +513,12 @@ void P_Ticker(boolean run)
|
||||
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
|
||||
P_PlayerAfterThink(&players[i]);
|
||||
|
||||
// Apply rumble to local players
|
||||
if (!demo.playback)
|
||||
{
|
||||
P_DeviceRumbleTick();
|
||||
}
|
||||
|
||||
PS_START_TIMING(ps_lua_thinkframe_time);
|
||||
LUAh_ThinkFrame();
|
||||
PS_STOP_TIMING(ps_lua_thinkframe_time);
|
||||
@@ -701,7 +528,7 @@ void P_Ticker(boolean run)
|
||||
//P_RunShields();
|
||||
P_RunOverlays();
|
||||
|
||||
//P_RunShadows();
|
||||
P_RunShadows();
|
||||
|
||||
P_UpdateSpecials();
|
||||
P_RespawnSpecials();
|
||||
@@ -716,12 +543,6 @@ void P_Ticker(boolean run)
|
||||
if (!(modeattacking && !demo.playback) || leveltime >= starttime - TICRATE*4)
|
||||
timeinmap++;
|
||||
|
||||
/*if (G_TagGametype())
|
||||
P_DoTagStuff();
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
P_DoCTFStuff();*/
|
||||
|
||||
if (run)
|
||||
{
|
||||
if (countdowntimer && --countdowntimer <= 0)
|
||||
@@ -824,16 +645,15 @@ void P_Ticker(boolean run)
|
||||
PS_STOP_TIMING(ps_lua_postthinkframe_time);
|
||||
}
|
||||
|
||||
K_UpdateDirector();
|
||||
|
||||
// Always move the camera.
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (camera[i].chase)
|
||||
P_MoveChaseCamera(&players[displayplayers[i]], &camera[i], false);
|
||||
}
|
||||
P_RunChaseCameras();
|
||||
|
||||
if (run)
|
||||
{
|
||||
R_UpdateLevelInterpolators();
|
||||
R_UpdateViewInterpolation();
|
||||
|
||||
// Hack: ensure newview is assigned every tic.
|
||||
// Ensures view interpolation is T-1 to T in poor network conditions
|
||||
@@ -898,6 +718,10 @@ void P_PreTicker(INT32 frames)
|
||||
memcpy(&players[i].cmd, &temptic, sizeof(ticcmd_t));
|
||||
}
|
||||
|
||||
// Dynamic slopeness
|
||||
if (midgamejoin)
|
||||
P_RunDynamicSlopes();
|
||||
|
||||
P_RunThinkers();
|
||||
|
||||
// Run any "after all the other thinkers" stuff
|
||||
@@ -908,7 +732,7 @@ void P_PreTicker(INT32 frames)
|
||||
LUAh_ThinkFrame();
|
||||
|
||||
P_RunOverlays();
|
||||
//P_RunShadows();
|
||||
P_RunShadows();
|
||||
|
||||
P_UpdateSpecials();
|
||||
P_RespawnSpecials();
|
||||
|
||||
+2
-1
@@ -24,10 +24,11 @@ extern tic_t leveltime;
|
||||
void Command_Numthinkers_f(void);
|
||||
void Command_CountMobjs_f(void);
|
||||
|
||||
void P_RunChaseCameras(void);
|
||||
void P_Ticker(boolean run);
|
||||
void P_PreTicker(INT32 frames);
|
||||
void P_DoTeamscrambling(void);
|
||||
void P_RemoveThinkerDelayed(void *pthinker); //killed
|
||||
void P_RemoveThinkerDelayed(thinker_t *thinker);
|
||||
mobj_t *P_SetTarget(mobj_t **mo, mobj_t *target); // killough 11/98
|
||||
|
||||
#endif
|
||||
+156
-112
@@ -55,7 +55,6 @@
|
||||
#endif
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_light.h"
|
||||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
||||
@@ -500,44 +499,12 @@ void P_GivePlayerLives(player_t *player, INT32 numlives)
|
||||
// Transform into Super Sonic!
|
||||
void P_DoSuperTransformation(player_t *player, boolean giverings)
|
||||
{
|
||||
(void)player;
|
||||
(void)giverings;
|
||||
|
||||
return; // SRB2kart - this is not a thing we need
|
||||
player->powers[pw_super] = 1;
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
|
||||
{
|
||||
S_StopMusic();
|
||||
S_ChangeMusicInternal("supers", true);
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
|
||||
|
||||
// Transformation animation
|
||||
//P_SetPlayerMobjState(player->mo, S_PLAY_SUPERTRANS1);
|
||||
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
|
||||
if (giverings)
|
||||
{
|
||||
player->mo->health = 51;
|
||||
player->health = player->mo->health;
|
||||
}
|
||||
|
||||
// Just in case.
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC))
|
||||
{
|
||||
player->powers[pw_extralife] = 0;
|
||||
player->powers[pw_invulnerability] = 0;
|
||||
player->powers[pw_sneakers] = 0;
|
||||
}
|
||||
|
||||
if (gametype != GT_COOP)
|
||||
{
|
||||
HU_SetCEchoFlags(0);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va("%s\\is now super.\\\\\\\\", player_names[player-players]));
|
||||
}
|
||||
|
||||
P_PlayerFlagBurst(player, false);
|
||||
}
|
||||
|
||||
// Adds to the player's score
|
||||
void P_AddPlayerScore(player_t *player, UINT32 amount)
|
||||
{
|
||||
@@ -591,11 +558,30 @@ void P_PlayLivesJingle(player_t *player)
|
||||
}
|
||||
}
|
||||
|
||||
void P_PlayRinglossSound(mobj_t *source)
|
||||
void P_PlayRinglossSound(mobj_t *source, mobj_t *damager)
|
||||
{
|
||||
sfxenum_t key = P_RandomKey(2);
|
||||
|
||||
if (cv_kartvoices.value)
|
||||
S_StartSound(source, (mariomode) ? sfx_mario8 : sfx_khurt1 + key);
|
||||
{
|
||||
if (cv_karthitemdialog.value && source != damager && damager && damager->player && P_IsLocalPlayer(damager->player))
|
||||
{
|
||||
sfxenum_t sfx = sfx_khurt1 + key;
|
||||
|
||||
INT32 skinnum = -1;
|
||||
|
||||
// I HATE LOCALSKINS! I HATE LOCALSKINS! :AAAAAAAAAA:
|
||||
if (source->player)
|
||||
skinnum = source->player->skinlocal ? (source->player->localskin - 1) : source->player->skin;
|
||||
|
||||
if (skinnum >= 0)
|
||||
sfx = (source->player->skinlocal ? localskins : skins)[skinnum].soundsid[SKSKPAN1 + key];
|
||||
|
||||
S_StartSound(NULL, sfx);
|
||||
}
|
||||
else
|
||||
S_StartSound(source, (mariomode) ? sfx_mario8 : sfx_khurt1 + key);
|
||||
}
|
||||
else
|
||||
S_StartSound(source, sfx_slip);
|
||||
}
|
||||
@@ -795,20 +781,16 @@ void P_RestoreMusic(player_t *player)
|
||||
}
|
||||
|
||||
// Item - Grow
|
||||
if (wantedmus == 2 && cv_growmusic.value)
|
||||
if (wantedmus == 2 && cv_growmusic.value == 1)
|
||||
{
|
||||
S_ChangeMusicInternal("kgrow", true);
|
||||
|
||||
if (cv_birdmusic.value)
|
||||
S_SetRestoreMusicFadeInCvar(&cv_growmusicfade);
|
||||
S_SetRestoreMusicFadeInCvar(&cv_growmusicfade);
|
||||
}
|
||||
// Item - Invincibility
|
||||
else if (wantedmus == 1 && cv_supermusic.value)
|
||||
else if (wantedmus == 1 && cv_supermusic.value == 1)
|
||||
{
|
||||
S_ChangeMusicInternal("kinvnc", true);
|
||||
|
||||
if (cv_birdmusic.value)
|
||||
S_SetRestoreMusicFadeInCvar(&cv_invincmusicfade);
|
||||
S_SetRestoreMusicFadeInCvar(&cv_invincmusicfade);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -825,13 +807,12 @@ void P_RestoreMusic(player_t *player)
|
||||
else
|
||||
position = mapmusposition;
|
||||
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, position, 0,
|
||||
S_GetRestoreMusicFadeIn());
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, position, 0, S_GetRestoreMusicFadeIn());
|
||||
S_ClearRestoreMusicFadeInCvar();
|
||||
}
|
||||
else
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
|
||||
|
||||
mapmusresume = 0;
|
||||
}
|
||||
}
|
||||
@@ -2567,10 +2548,7 @@ static void P_MovePlayer(player_t *player)
|
||||
|
||||
static void P_DoZoomTube(player_t *player)
|
||||
{
|
||||
INT32 sequence;
|
||||
fixed_t speed;
|
||||
thinker_t *th;
|
||||
mobj_t *mo2;
|
||||
mobj_t *waypoint = NULL;
|
||||
fixed_t dist;
|
||||
boolean reverse;
|
||||
@@ -2586,8 +2564,6 @@ static void P_DoZoomTube(player_t *player)
|
||||
|
||||
speed = abs(player->speed);
|
||||
|
||||
sequence = player->mo->tracer->threshold;
|
||||
|
||||
// change slope
|
||||
dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z);
|
||||
|
||||
@@ -2619,26 +2595,7 @@ static void P_DoZoomTube(player_t *player)
|
||||
CONS_Debug(DBG_GAMELOGIC, "Looking for next waypoint...\n");
|
||||
|
||||
// Find next waypoint
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker) // Not a mobj thinker
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)th;
|
||||
|
||||
if (mo2->type != MT_TUBEWAYPOINT)
|
||||
continue;
|
||||
|
||||
if (mo2->threshold == sequence)
|
||||
{
|
||||
if ((reverse && mo2->health == player->mo->tracer->health - 1)
|
||||
|| (!reverse && mo2->health == player->mo->tracer->health + 1))
|
||||
{
|
||||
waypoint = mo2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
waypoint = reverse ? P_GetPreviousWaypoint(player->mo->tracer, false) : P_GetNextWaypoint(player->mo->tracer, false);
|
||||
|
||||
if (waypoint)
|
||||
{
|
||||
@@ -2989,12 +2946,19 @@ static void P_DeathThink(player_t *player)
|
||||
else
|
||||
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
||||
}
|
||||
|
||||
if (player->spectator)
|
||||
player->laptime[LAP_CUR] = 0;
|
||||
else
|
||||
player->laptime[LAP_CUR]++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
||||
}
|
||||
else
|
||||
{
|
||||
player->realtime = 0;
|
||||
if (player == &players[consoleplayer])
|
||||
curlap = 0;
|
||||
|
||||
player->laptime[LAP_CUR] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3051,29 +3015,93 @@ static CV_PossibleValue_t CV_CamSpeed[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0,
|
||||
static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {45, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t CV_CamRotate[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_cam_dist = {"cam_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam_height = {"cam_height", "50", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static void CV_PlayerCam1_OnChange(void)
|
||||
{
|
||||
if (gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
if (!playeringame[displayplayers[0]] || players[displayplayers[0]].spectator)
|
||||
return;
|
||||
|
||||
// dont do stuff when cam speeen at map start
|
||||
if (leveltime < starttime - TICRATE*4)
|
||||
return;
|
||||
|
||||
if (camera[displayplayers[0]].chase)
|
||||
P_ResetCamera(&players[displayplayers[0]], &camera[0]);
|
||||
}
|
||||
|
||||
static void CV_PlayerCam2_OnChange(void)
|
||||
{
|
||||
if (gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
if (!playeringame[displayplayers[1]] || players[displayplayers[1]].spectator)
|
||||
return;
|
||||
|
||||
// dont do stuff when cam speeen at map start
|
||||
if (leveltime < starttime - TICRATE*4)
|
||||
return;
|
||||
|
||||
if (camera[displayplayers[1]].chase)
|
||||
P_ResetCamera(&players[displayplayers[1]], &camera[1]);
|
||||
}
|
||||
|
||||
static void CV_PlayerCam3_OnChange(void)
|
||||
{
|
||||
if (gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
if (!playeringame[displayplayers[2]] || players[displayplayers[2]].spectator)
|
||||
return;
|
||||
|
||||
// dont do stuff when cam speeen at map start
|
||||
if (leveltime < starttime - TICRATE*4)
|
||||
return;
|
||||
|
||||
if (camera[displayplayers[2]].chase)
|
||||
P_ResetCamera(&players[displayplayers[2]], &camera[2]);
|
||||
}
|
||||
|
||||
static void CV_PlayerCam4_OnChange(void)
|
||||
{
|
||||
if (gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
if (!playeringame[displayplayers[3]] || players[displayplayers[3]].spectator)
|
||||
return;
|
||||
|
||||
// dont do stuff when cam speeen at map start
|
||||
if (leveltime < starttime - TICRATE*4)
|
||||
return;
|
||||
|
||||
if (camera[displayplayers[3]].chase)
|
||||
P_ResetCamera(&players[displayplayers[3]], &camera[3]);
|
||||
}
|
||||
|
||||
consvar_t cv_cam_dist = {"cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam_height = {"cam_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam_still = {"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam_speed = {"cam_speed", "0.4", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam_rotate = {"cam_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam_rotspeed = {"cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_cam2_dist = {"cam2_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam2_height = {"cam2_height", "50", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam2_dist = {"cam2_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam2_height = {"cam2_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam2_still = {"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam2_speed = {"cam2_speed", "0.4", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam2_rotate = {"cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam2_rotspeed = {"cam2_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_cam3_dist = {"cam3_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam3_height = {"cam3_height", "50", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam3_dist = {"cam3_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam3_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam3_height = {"cam3_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam3_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam3_still = {"cam3_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam3_speed = {"cam3_speed", "0.4", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam3_rotate = {"cam3_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate3_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam3_rotspeed = {"cam3_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_cam4_dist = {"cam4_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam4_height = {"cam4_height", "50", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam4_dist = {"cam4_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam4_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam4_height = {"cam4_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam4_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam4_still = {"cam4_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam4_speed = {"cam4_speed", "0.4", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_cam4_rotate = {"cam4_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate4_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -3085,6 +3113,9 @@ consvar_t cv_tiltsmoothing = {"tiltsmoothing", "32", CV_SAVE, CV_Natural, NULL,
|
||||
|
||||
consvar_t cv_actionmovie = {"actionmovie", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t lookbackmom_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Double"}, {0, NULL}};
|
||||
consvar_t cv_lookbackmom = {"cameralookbackmom", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
fixed_t t_cam_dist = -42;
|
||||
fixed_t t_cam_height = -42;
|
||||
fixed_t t_cam_rotate = -42;
|
||||
@@ -3900,6 +3931,16 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
{
|
||||
thiscam->momx = x - thiscam->x;
|
||||
thiscam->momy = y - thiscam->y;
|
||||
|
||||
// when looking back, camera's momentum
|
||||
// should inherit the momentum of the player
|
||||
// if value is 2, add extra
|
||||
if (cv_lookbackmom.value && lookback && lookbackdelay[num])
|
||||
{
|
||||
thiscam->momx += cv_lookbackmom.value*mo->momx;
|
||||
thiscam->momy += cv_lookbackmom.value*mo->momy;
|
||||
}
|
||||
|
||||
thiscam->momz = FixedMul(z - thiscam->z, camspeed/2);
|
||||
}
|
||||
|
||||
@@ -3959,6 +4000,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||
{
|
||||
P_MoveChaseCamera(player, thiscam, false);
|
||||
R_ResetViewInterpolation(num + 1);
|
||||
R_ResetViewInterpolation(num + 1);
|
||||
}
|
||||
|
||||
return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming);
|
||||
@@ -3989,7 +4031,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
||||
// Pressing fire assigns you to a team that needs players if allowed.
|
||||
// Partial code reproduction from p_tick.c autobalance code.
|
||||
else if (G_GametypeHasTeams())
|
||||
{
|
||||
{
|
||||
INT32 changeto = 0;
|
||||
INT32 z, numplayersred = 0, numplayersblue = 0;
|
||||
|
||||
@@ -4042,7 +4084,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
||||
}
|
||||
// Joining in game from firing.
|
||||
else
|
||||
{
|
||||
{
|
||||
if (player->mo)
|
||||
{
|
||||
P_RemoveMobj(player->mo);
|
||||
@@ -4207,11 +4249,7 @@ Quaketilt (player_t *player)
|
||||
INT32 delta = (INT32)( player->mo->angle - moma );
|
||||
fixed_t speed;
|
||||
|
||||
boolean sliptiding =
|
||||
(
|
||||
player->kartstuff[k_aizdriftstrat] != 0 &&
|
||||
player->kartstuff[k_drift] == 0
|
||||
);
|
||||
boolean sliptiding = player->kartstuff[k_drift] ? 0 : player->kartstuff[k_aizdriftstrat];
|
||||
|
||||
if (delta == (INT32)ANGLE_180)/* FUCK YOU HAVE A HACK */
|
||||
{
|
||||
@@ -4239,6 +4277,7 @@ Quaketilt (player_t *player)
|
||||
tilt = ANGLE_22h;
|
||||
lowb = 10*FRACUNIT;
|
||||
}
|
||||
lowb = FixedMul(lowb, player->mo->scale);
|
||||
moma = FixedMul(FixedDiv(delta, ANGLE_90), tilt);
|
||||
speed = abs( player->mo->momx + player->mo->momy );
|
||||
if (speed < lowb)
|
||||
@@ -4255,6 +4294,19 @@ DoABarrelRoll (player_t *player)
|
||||
angle_t slope;
|
||||
angle_t delta;
|
||||
|
||||
fixed_t smoothing;
|
||||
|
||||
if (player->exiting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_respawn])
|
||||
{
|
||||
player->tilt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->mo->standingslope)
|
||||
{
|
||||
slope = player->mo->standingslope->real_zangle;
|
||||
@@ -4279,26 +4331,16 @@ DoABarrelRoll (player_t *player)
|
||||
slope -= Quaketilt(player);
|
||||
}
|
||||
|
||||
delta = (INT32)( slope - player->tilt )/ cv_tiltsmoothing.value;
|
||||
delta = slope - player->tilt;
|
||||
smoothing = FixedDiv(AbsAngle(slope), ANGLE_45);
|
||||
|
||||
delta = FixedDiv(delta, cv_tiltsmoothing.value *
|
||||
FixedDiv(FRACUNIT, FRACUNIT + smoothing));
|
||||
|
||||
if (delta)
|
||||
player->tilt += delta;
|
||||
else
|
||||
player->tilt = slope;
|
||||
|
||||
if (cv_tilting.value)
|
||||
{
|
||||
player->viewrollangle = player->tilt;
|
||||
|
||||
if (cv_actionmovie.value)
|
||||
{
|
||||
player->viewrollangle += quake.roll;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->viewrollangle = 0;
|
||||
}
|
||||
player->tilt = slope;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -4310,11 +4352,6 @@ void P_PlayerThink(player_t *player)
|
||||
ticcmd_t *cmd;
|
||||
const size_t playeri = (size_t)(player - players);
|
||||
|
||||
player->lerp.aiming = player->aiming;
|
||||
player->lerp.awayviewaiming = player->awayviewaiming;
|
||||
player->lerp.frameangle = player->frameangle;
|
||||
player->lerp.viewrollangle = player->viewrollangle;
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (!player->mo)
|
||||
I_Error("p_playerthink: players[%s].mo == NULL", sizeu1(playeri));
|
||||
@@ -4540,12 +4577,19 @@ void P_PlayerThink(player_t *player)
|
||||
else
|
||||
curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
||||
}
|
||||
|
||||
if (player->spectator)
|
||||
player->laptime[LAP_CUR] = 0;
|
||||
else
|
||||
player->laptime[LAP_CUR]++; // This is too complicated to sync to realtime, just sorta hope for the best :V
|
||||
}
|
||||
else
|
||||
{
|
||||
player->realtime = 0;
|
||||
if (player == &players[consoleplayer])
|
||||
curlap = 0;
|
||||
|
||||
player->laptime[LAP_CUR] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4884,7 +4928,7 @@ void P_PlayerAfterThink(player_t *player)
|
||||
|
||||
#ifdef SECTORSPECIALSAFTERTHINK
|
||||
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
|
||||
player->onconveyor = 0;
|
||||
player->onconveyor = 0;
|
||||
// check special sectors : damage & secrets
|
||||
|
||||
if (!player->spectator)
|
||||
|
||||
+30
-45
@@ -259,22 +259,25 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||
else if (sec->heightsec != -1)
|
||||
{
|
||||
const sector_t *s = §ors[sec->heightsec];
|
||||
mobj_t *viewmobj = viewplayer->mo;
|
||||
mobj_t *pviewmobj = viewplayer->mo;
|
||||
INT32 heightsec;
|
||||
boolean underwater;
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (viewplayer == &players[displayplayers[i]] && camera[i].chase)
|
||||
{
|
||||
heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec;
|
||||
break;
|
||||
}
|
||||
if (viewplayer != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
if (!camera[i].chase)
|
||||
continue;
|
||||
|
||||
heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i > splitscreen && viewmobj)
|
||||
heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec;
|
||||
if (i > splitscreen && pviewmobj)
|
||||
heightsec = R_PointInSubsector(pviewmobj->x, pviewmobj->y)->sector->heightsec;
|
||||
else
|
||||
return sec;
|
||||
|
||||
@@ -420,17 +423,8 @@ static void R_AddLine(seg_t *line)
|
||||
return;
|
||||
|
||||
// big room fix
|
||||
|
||||
if (cv_pointoangleexor64.value)
|
||||
{
|
||||
angle1 = R_PointToAngle64(line->v1->x, line->v1->y);
|
||||
angle2 = R_PointToAngle64(line->v2->x, line->v2->y);
|
||||
}
|
||||
else
|
||||
{
|
||||
angle1 = R_PointToAngleEx(viewx, viewy, line->v1->x, line->v1->y);
|
||||
angle2 = R_PointToAngleEx(viewx, viewy, line->v2->x, line->v2->y);
|
||||
}
|
||||
angle1 = R_PointToAngle64(line->v1->x, line->v1->y);
|
||||
angle2 = R_PointToAngle64(line->v2->x, line->v2->y);
|
||||
|
||||
curline = line;
|
||||
|
||||
@@ -638,16 +632,8 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
|
||||
check = checkcoord[boxpos];
|
||||
|
||||
// big room fix
|
||||
if (cv_pointoangleexor64.value)
|
||||
{
|
||||
angle1 = R_PointToAngle64(bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
|
||||
angle2 = R_PointToAngle64(bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle1 = R_PointToAngleEx(viewx, viewy, bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
|
||||
angle2 = R_PointToAngleEx(viewx, viewy, bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
|
||||
}
|
||||
angle1 = R_PointToAngle64(bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
|
||||
angle2 = R_PointToAngle64(bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
|
||||
|
||||
if ((signed)angle1 < (signed)angle2)
|
||||
{
|
||||
@@ -907,11 +893,11 @@ static void R_Subsector(size_t num)
|
||||
{
|
||||
sector_t *controlSec = §ors[rover->secnum];
|
||||
|
||||
if (controlSec->moved == true)
|
||||
{
|
||||
anyMoved = true;
|
||||
break;
|
||||
}
|
||||
if (controlSec->moved != true)
|
||||
continue;
|
||||
|
||||
anyMoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1088,10 +1074,10 @@ static void R_Subsector(size_t num)
|
||||
{
|
||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic,
|
||||
polysec->lightlevel, polysec->floor_xoffs, polysec->floor_yoffs,
|
||||
polysec->floorpic_angle-po->angle,
|
||||
NULL, NULL, po
|
||||
, NULL // will ffloors be slopable eventually?
|
||||
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floor_xoffs, polysec->floor_yoffs,
|
||||
polysec->floorpic_angle-po->angle,
|
||||
(light == -1 ? frontsector->extra_colormap : frontsector->lightlist[light].extra_colormap), NULL, po
|
||||
,NULL // will ffloors be slopable eventually?
|
||||
, R_NoEncore(polysec, false));
|
||||
|
||||
ffloor[numffloors].height = polysec->floorheight;
|
||||
@@ -1111,12 +1097,11 @@ static void R_Subsector(size_t num)
|
||||
&& polysec->ceilingheight <= ceilingcenterz
|
||||
&& (viewz > polysec->ceilingheight))
|
||||
{
|
||||
light = R_GetPlaneLight(frontsector, polysec->ceilingheight, viewz < polysec->ceilingheight);
|
||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
|
||||
polysec->lightlevel, polysec->ceiling_xoffs, polysec->ceiling_yoffs,
|
||||
polysec->ceilingpic_angle-po->angle,
|
||||
NULL, NULL, po
|
||||
, NULL // will ffloors be slopable eventually?
|
||||
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle,
|
||||
(light == -1 ? frontsector->extra_colormap : frontsector->lightlist[light].extra_colormap), NULL, po
|
||||
,NULL // will ffloors be slopable eventually?
|
||||
, R_NoEncore(polysec, true));
|
||||
|
||||
ffloor[numffloors].polyobj = po;
|
||||
@@ -1160,7 +1145,7 @@ static void R_Subsector(size_t num)
|
||||
{
|
||||
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
|
||||
if (!line->polyseg) // ignore segs that belong to polyobjects
|
||||
R_AddLine(line);
|
||||
R_AddLine(line);
|
||||
line++;
|
||||
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
|
||||
}
|
||||
@@ -1222,7 +1207,7 @@ void R_Prep3DFloors(sector_t *sector)
|
||||
rover->lastlight = 0;
|
||||
if (!(rover->flags & FF_EXISTS) || (rover->flags & FF_NOSHADE
|
||||
&& !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES)))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight;
|
||||
|
||||
|
||||
Loaded 100 of 134 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user