mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-27 11:00:37 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20282ffa56 | ||
|
|
ff4987cc81 | ||
|
|
80a22ca2ed | ||
|
|
51ca0a06a7 | ||
|
|
010794418c | ||
|
|
51b5b2571a | ||
|
|
182a677337 | ||
|
|
17f6c25bc7 | ||
|
|
31d19cb0f6 | ||
|
|
6c65bba279 | ||
|
|
8ae15be0de | ||
|
|
11fb5ee2af | ||
|
|
b68992e55e | ||
|
|
007a7681eb | ||
|
|
7d4cdac52c | ||
|
|
916f38e1b2 | ||
|
|
39ae88a2ab | ||
|
|
24f82e8e36 | ||
|
|
247d09a09d | ||
|
|
030b291af1 | ||
|
|
9d0a5faed3 | ||
|
|
261b15851f | ||
|
|
2929bd82a5 | ||
|
|
4939927975 | ||
|
|
f9ef6733b9 | ||
|
|
de08fe7ca3 | ||
|
|
482536ff1c | ||
|
|
3089cc8bc3 | ||
|
|
a307450e17 | ||
|
|
50cfc7e5ad | ||
|
|
5b82cc4f11 | ||
|
|
a83a76da95 | ||
|
|
2e4759ab1f | ||
|
|
af056d7646 | ||
|
|
46e57f0a1f | ||
|
|
fe5473bc85 | ||
|
|
1a03288144 | ||
|
|
0c2326480b | ||
|
|
24f3b3bc93 | ||
|
|
459aa89ca2 | ||
|
|
ec8eaacc69 | ||
|
|
84f55f627e | ||
|
|
a30f78e834 | ||
|
|
d22cda594f | ||
|
|
8cfa909b73 | ||
|
|
86a6dd020f | ||
|
|
556133fa11 | ||
|
|
4001de1dde | ||
|
|
7a57a25c58 | ||
|
|
d95cdcc142 | ||
|
|
d2a967e577 | ||
|
|
84adaa07e0 | ||
|
|
2efeb7e972 | ||
|
|
b9655e3f19 | ||
|
|
dce004ef13 | ||
|
|
b9f1530eec | ||
|
|
9b15b27f28 | ||
|
|
ff2e64a742 | ||
|
|
4e38b803fb | ||
|
|
9825e1e6f2 | ||
|
|
b278f2eafa | ||
|
|
25912079db | ||
|
|
b1753df1ed | ||
|
|
03143d1341 | ||
|
|
843b49d56b | ||
|
|
00644e7605 | ||
|
|
93814bd05b | ||
|
|
438ed2c0ea | ||
|
|
0310475957 | ||
|
|
435bfe1271 | ||
|
|
7ca532f0e4 | ||
|
|
8c3997f13b | ||
|
|
d8ae1ce6b9 | ||
|
|
5cb1e5de84 | ||
|
|
7fd2aff17b | ||
|
|
b9f3ee867b | ||
|
|
f16b992a97 | ||
|
|
9ba5710412 | ||
|
|
7e6854f96b | ||
|
|
aa25ef6c68 | ||
|
|
9db1076603 | ||
|
|
7b39218af5 | ||
|
|
ba5b2adf94 | ||
|
|
ded7d941ea | ||
|
|
09ed4e4a1d | ||
|
|
9b3aaa0f87 | ||
|
|
a274325f43 | ||
|
|
b0da0b8321 | ||
|
|
a241ea20fa | ||
|
|
f8d5a5ecd2 | ||
|
|
f20b47ebc0 | ||
|
|
de10ab8df3 | ||
|
|
47c7c5a5e3 | ||
|
|
80ada3225d | ||
|
|
a1745829b2 | ||
|
|
b2853465ed | ||
|
|
c89091b4cd | ||
|
|
e5beb0d9b9 | ||
|
|
80ab513d76 | ||
|
|
854136d85b | ||
|
|
25c417187b | ||
|
|
e3e9328ba3 | ||
|
|
3cc0c41b7b | ||
|
|
697013bbbf | ||
|
|
0080d4b9a8 | ||
|
|
8c391ef880 | ||
|
|
e6d3ca32f4 | ||
|
|
fab78f933e | ||
|
|
5cd7d89e72 | ||
|
|
15e8146306 | ||
|
|
250f1d090e | ||
|
|
03c5864034 | ||
|
|
07b7f10912 | ||
|
|
0e1837db31 | ||
|
|
070fe17473 | ||
|
|
ba607a0aad | ||
|
|
2b38a0f48e | ||
|
|
a1fb3b283c | ||
|
|
12e85aba45 | ||
|
|
44fe18fef1 | ||
|
|
28de2543ec | ||
|
|
4435984b81 | ||
|
|
1435489a43 | ||
|
|
3d20b3a232 | ||
|
|
97543622bf | ||
|
|
a9374f068b | ||
|
|
d80e9d80e7 | ||
|
|
4f757445c4 | ||
|
|
2749ab92b2 | ||
|
|
011bee9f33 | ||
|
|
1b86e60548 | ||
|
|
23e01fc1a7 | ||
|
|
2c9c80d7bc | ||
|
|
5146b1f36b | ||
|
|
bc81fe78b2 | ||
|
|
4de1b7c73b | ||
|
|
3c8c4e9f97 | ||
|
|
c366c10530 | ||
|
|
6f5106803d | ||
|
|
55a6b7956a | ||
|
|
911d1f1706 | ||
|
|
56fba733f3 | ||
|
|
a3c65ef7e4 | ||
|
|
73bc196592 | ||
|
|
8487099264 | ||
|
|
bdcd0dbd56 | ||
|
|
3c2600648c | ||
|
|
f1abfeced6 | ||
|
|
99bce5a11a | ||
|
|
ab5a3604bf | ||
|
|
fab7d8539c | ||
|
|
0347a5ca0b | ||
|
|
42ad1cb41c | ||
|
|
64e3c18fb9 | ||
|
|
7e113359b3 | ||
|
|
467802c466 | ||
|
|
ce1b3aaee9 | ||
|
|
1a53bdd584 | ||
|
|
5521e7654d | ||
|
|
73716dd624 | ||
|
|
840d23dcac | ||
|
|
525a0c7c82 | ||
|
|
46c35057fb | ||
|
|
6d03b9763a | ||
|
|
9eaecb0a2a | ||
|
|
c274af839e | ||
|
|
f9232840e4 | ||
|
|
3ea40fda82 | ||
|
|
c357c2614a | ||
|
|
efed6d0eac | ||
|
|
244220f031 | ||
|
|
7ce87575bc | ||
|
|
401cfeda65 | ||
|
|
a45a8c7742 | ||
|
|
c80b360918 | ||
|
|
8514ef6ef8 | ||
|
|
9b1dc34ea1 | ||
|
|
f5490321e7 | ||
|
|
1f4393e3b2 | ||
|
|
8aa6a16a27 | ||
|
|
286f553a54 | ||
|
|
f0ec50e37b | ||
|
|
c1ee0332e3 | ||
|
|
d2737f2b40 | ||
|
|
0d501ec38a | ||
|
|
d39e6421fe | ||
|
|
c2125947ab | ||
|
|
953a33a6ff | ||
|
|
883e7884c4 | ||
|
|
508903c3b1 | ||
|
|
9116063d3f | ||
|
|
e2a0d2d01e | ||
|
|
5343949254 | ||
|
|
c17454b124 | ||
|
|
4f8dc5dc2a | ||
|
|
0fea47bb69 | ||
|
|
47665fcd70 | ||
|
|
968b073338 | ||
|
|
03582bb59a | ||
|
|
149d3ce2fc | ||
|
|
fe5e151d89 | ||
|
|
06a7341eda | ||
|
|
456ed42e14 | ||
|
|
2337f93df8 | ||
|
|
ad675b05ac | ||
|
|
44f6de9524 | ||
|
|
e25605b898 | ||
|
|
919d14e329 | ||
|
|
8fc64cd1b1 | ||
|
|
028a7d6125 | ||
|
|
60b9a6e2e0 | ||
|
|
9ad515335a | ||
|
|
7593ea53f9 | ||
|
|
07374ba1ed | ||
|
|
2deba01a5f | ||
|
|
3daee90b5b | ||
|
|
c4ba60afbd | ||
|
|
81e9ce10cd | ||
|
|
c4738966fe | ||
|
|
0eedc4e2f8 | ||
|
|
14f9368575 | ||
|
|
394546dee7 | ||
|
|
e86e5c0d80 | ||
|
|
e0b5a62c4f | ||
|
|
7fb42cf655 | ||
|
|
819f6bcf71 | ||
|
|
ad47f8855b | ||
|
|
a50102ef52 | ||
|
|
0b2a0634f5 | ||
|
|
8ea32fee31 | ||
|
|
f0571385d5 | ||
|
|
83318af532 | ||
|
|
860c9b33ef | ||
|
|
ecbd6ae282 | ||
|
|
3ec799d150 | ||
|
|
72715c1a85 | ||
|
|
16d262f6ee | ||
|
|
49850940d6 | ||
|
|
e634fb5022 | ||
|
|
c0726f0634 | ||
|
|
91dc3e5884 | ||
|
|
ba2c3ed5fd | ||
|
|
161f7e3313 | ||
|
|
f2f7afadef | ||
|
|
0898bffb43 | ||
|
|
99dc7bf7f2 | ||
|
|
64acea9018 | ||
|
|
8e05347ba0 | ||
|
|
07e90d37ee | ||
|
|
71bd04e5b2 | ||
|
|
95510279ed | ||
|
|
f1502833b2 | ||
|
|
e6448697d3 | ||
|
|
5a96d6dd96 | ||
|
|
8d6b3d0bd8 | ||
|
|
1fd0cd097f | ||
|
|
421126db38 | ||
|
|
7258a2e972 | ||
|
|
df66ab0339 | ||
|
|
c49d0c7afa | ||
|
|
421b3d6375 | ||
|
|
11ef489225 | ||
|
|
e1da6797c5 | ||
|
|
430c7d1a57 | ||
|
|
d3794c0dd9 | ||
|
|
eef1368083 | ||
|
|
6dfefa04f5 | ||
|
|
8b17d81545 | ||
|
|
ec58ca0f13 | ||
|
|
3fd87f90a2 | ||
|
|
9f268b0f6a | ||
|
|
f857116f75 | ||
|
|
ea78d96bc3 | ||
|
|
0be9e69833 | ||
|
|
8171641e3a | ||
|
|
ee6014a30f | ||
|
|
16c22a3ee5 | ||
|
|
571e48fecf | ||
|
|
973d7c5f34 | ||
|
|
a1c5ca288a | ||
|
|
e330d00565 | ||
|
|
6feeb21e21 | ||
|
|
bb5cf24d5f | ||
|
|
0dda70cca1 | ||
|
|
5e83e03e33 | ||
|
|
d2b3f6c12b | ||
|
|
f5af33b181 | ||
|
|
0da1ed8764 | ||
|
|
8aa6f29c4c | ||
|
|
1b7a4442d3 | ||
|
|
a163df993c | ||
|
|
2787007b9d | ||
|
|
cea2c178b5 | ||
|
|
77a9cd5a9a | ||
|
|
ec3259271e | ||
|
|
ae02abba3b | ||
|
|
bf960f6f32 | ||
|
|
66a1087099 | ||
|
|
c1a431f857 | ||
|
|
dac5279a59 | ||
|
|
a175ea27d7 | ||
|
|
ddac42e21e | ||
|
|
34535ad415 | ||
|
|
c0597e441c | ||
|
|
04b66684dd | ||
|
|
244a2e66f9 | ||
|
|
55b737e730 | ||
|
|
059dacf2a7 | ||
|
|
41f7003747 | ||
|
|
64ba900511 | ||
|
|
e371b4bbd3 | ||
|
|
aa44150525 | ||
|
|
3572be718a | ||
|
|
a56d74814b | ||
|
|
8d41b58635 | ||
|
|
e80f326ee6 | ||
|
|
c5bd64912a | ||
|
|
8a808b616e | ||
|
|
91bb2f2e0b | ||
|
|
aa4e6a0651 | ||
|
|
8e9ff2b289 | ||
|
|
d53ab8540e | ||
|
|
7b133e5b2f | ||
|
|
2b72959935 | ||
|
|
82d0b62631 | ||
|
|
7205e27c8c | ||
|
|
c8d1248d86 | ||
|
|
845e4556ef | ||
|
|
a92bfbde40 | ||
|
|
999b6409b3 | ||
|
|
0ae0be4047 | ||
|
|
fc7029c271 | ||
|
|
307ee117bd | ||
|
|
087d28eb9a | ||
|
|
1deea345bc | ||
|
|
e0fa706f6c | ||
|
|
cf794d2b95 | ||
|
|
391e82bb92 | ||
|
|
83a44b3158 | ||
|
|
8cd0e6c5bf | ||
|
|
619ab00035 | ||
|
|
4ded5c3380 | ||
|
|
85fa2185f8 | ||
|
|
ab39259bbe | ||
|
|
9bf2065d18 | ||
|
|
ceb121d588 | ||
|
|
e7dbc25ca0 | ||
|
|
7386784765 | ||
|
|
9062952539 | ||
|
|
9f0a479c3b | ||
|
|
517b9296dc | ||
|
|
3ca09613e1 | ||
|
|
ba931cbedf | ||
|
|
090b354b23 | ||
|
|
dd30bfde15 | ||
|
|
477735cb3d | ||
|
|
38599f2181 | ||
|
|
bd794fb286 | ||
|
|
ce34b78113 | ||
|
|
b8a87dc6ea | ||
|
|
7bdc30936c | ||
|
|
9e635a7207 | ||
|
|
e5626378ef | ||
|
|
73921c116d | ||
|
|
d4b98ef9dd | ||
|
|
40318f052a | ||
|
|
a130f45c62 | ||
|
|
e687d97660 | ||
|
|
e4a0406fc2 | ||
|
|
ef18c389be | ||
|
|
85099801ab | ||
|
|
3472657f92 | ||
|
|
c197513ff3 | ||
|
|
9dca77c2cf | ||
|
|
f08a7fa21e | ||
|
|
2df56c810d | ||
|
|
8c6098f730 | ||
|
|
1462d4f8d9 | ||
|
|
5bd49304d7 | ||
|
|
f52d648d6f | ||
|
|
987af7eb81 | ||
|
|
f313b6a058 | ||
|
|
99b989bb63 | ||
|
|
7ebbba6ce5 | ||
|
|
c2a6db15a6 | ||
|
|
aa58bcf948 | ||
|
|
fa5b030522 | ||
|
|
3e44049abf | ||
|
|
94c501e71b | ||
|
|
484b2a8900 | ||
|
|
e8ff4fb9a7 | ||
|
|
b89e10fd5c | ||
|
|
d86ea606eb | ||
|
|
2135be12b8 | ||
|
|
ae5d51f2e9 | ||
|
|
6eaf25ff80 | ||
|
|
17c371c15e | ||
|
|
13febc125e | ||
|
|
b0f26acc18 | ||
|
|
8ffa5f15e6 | ||
|
|
f6bcc1ab86 | ||
|
|
a4d6442526 | ||
|
|
b7fac3a5b0 | ||
|
|
64ebf3ed05 | ||
|
|
9933612607 | ||
|
|
22ff072b54 | ||
|
|
73b0a84ad0 | ||
|
|
7b03f953bf | ||
|
|
367d6ff6fc | ||
|
|
ca61fde54b | ||
|
|
f739588c73 | ||
|
|
ce02d782c4 | ||
|
|
a498b11e20 | ||
|
|
ffa5a91cd2 | ||
|
|
ae680ffd5d | ||
|
|
4c17d12fc6 | ||
|
|
0259f1a251 | ||
|
|
04708aeb67 | ||
|
|
a47eb1653e | ||
|
|
10fda39430 | ||
|
|
b2be03cce3 | ||
|
|
84ecf838d4 | ||
|
|
c115796137 | ||
|
|
7e054c8beb | ||
|
|
e8df36998e | ||
|
|
0cc558f757 | ||
|
|
5c9bc074f4 | ||
|
|
d89175ebc8 | ||
|
|
727eb71995 | ||
|
|
3d48c00902 | ||
|
|
963318264c | ||
|
|
d9123799d6 | ||
|
|
6562bcb164 | ||
|
|
4fa8af3b30 | ||
|
|
3f4be4f8ef | ||
|
|
09c7badf4f | ||
|
|
7b9b371cf6 | ||
|
|
25e44e7a45 | ||
|
|
51374729d3 | ||
|
|
5a19f7f574 | ||
|
|
40ac8a1557 | ||
|
|
ca42a3e08e | ||
|
|
3a04357b71 | ||
|
|
078223c1b6 | ||
|
|
3fe7cbf725 | ||
|
|
d6059e42ba | ||
|
|
02c1fbe4fc | ||
|
|
6f8fee47f2 | ||
|
|
6c247b300e | ||
|
|
3627760748 | ||
|
|
f3affb3d4c | ||
|
|
a86ed01ba3 | ||
|
|
d40755eb7c | ||
|
|
ce7599cb02 | ||
|
|
68bf89c522 | ||
|
|
0c5b57ee05 | ||
|
|
69a10da52c | ||
|
|
ab534623c4 | ||
|
|
ae4ea14b35 | ||
|
|
ea3c48af02 | ||
|
|
9df0c023ed | ||
|
|
a5259ebc05 | ||
|
|
add59ad12a | ||
|
|
53eecb4d4c | ||
|
|
77fb47451c | ||
|
|
80ae39c2a7 | ||
|
|
118ce0d550 | ||
|
|
dfd9afceba | ||
|
|
6f7eb93645 | ||
|
|
a5268cbd24 | ||
|
|
c732ed66b2 | ||
|
|
10981f706f | ||
|
|
d61218d7e2 | ||
|
|
615032bc25 | ||
|
|
ea70be07a2 | ||
|
|
1884d3d23c | ||
|
|
3f036cca5e | ||
|
|
3e02fe340b | ||
|
|
50d62f1505 | ||
|
|
60511ace99 | ||
|
|
aef54d05ae | ||
|
|
15633626fe | ||
|
|
d43b60c818 | ||
|
|
7941524aad | ||
|
|
3aa4a6157c | ||
|
|
fc9cf41557 | ||
|
|
527131e513 | ||
|
|
b79163f998 | ||
|
|
121aaa164a | ||
|
|
2522559a04 | ||
|
|
cf61471b2d | ||
|
|
9ebdc6a238 | ||
|
|
0c65f5dab3 |
No files matched your search
@@ -27,19 +27,6 @@ jobs:
|
||||
name: "Building for platform linux-${{matrix.architecture.name}}"
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
# container:
|
||||
# image: ubuntu:22.04
|
||||
# volumes:
|
||||
# - ${{github.workspace}}:${{github.workspace}}
|
||||
#
|
||||
# steps:
|
||||
# - name: Install required packages
|
||||
# run: apt update && apt install -y clang-15 cmake ninja-build flex bison git
|
||||
#
|
||||
# - name: Install required cross-platform packages (${{ matrix.architecture.triple }})
|
||||
# if: matrix.architecture.name != 'amd64'
|
||||
# run: apt install -y gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
|
||||
|
||||
steps:
|
||||
- name: Settings
|
||||
working-directory: ${{github.workspace}}
|
||||
@@ -54,22 +41,18 @@ jobs:
|
||||
- name: Install required cross-platform packages (${{ matrix.architecture.triple }})
|
||||
if: matrix.architecture.name != 'amd64'
|
||||
run: sudo apt install -y gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
echo Using triple: ${{ matrix.architecture.triple }}
|
||||
mkdir -p thirdparties && cd thirdparties
|
||||
git clone --depth 1 --single-branch --branch SDL2 https://github.com/libsdl-org/SDL.git
|
||||
cmake -B SDL-build \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/SDL-install' \
|
||||
./SDL
|
||||
cmake --build SDL-build --config Release
|
||||
cmake --install SDL-build
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: sdl2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: "-DCMAKE_C_COMPILER=clang
|
||||
-DCMAKE_CXX_COMPILER=clang++
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }}
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }}"
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -84,9 +67,7 @@ jobs:
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
|
||||
-DSDL2_DIR='${{github.workspace}}/thirdparties/SDL-install/lib/cmake/SDL2' \
|
||||
-DWITH_CLIENT=1" >> $GITHUB_ENV
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
@@ -111,7 +92,7 @@ jobs:
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
cp '${{github.workspace}}/thirdparties/SDL-install/lib/libSDL2.so' '${{github.workspace}}/install'
|
||||
cp '${{steps.sdl.outputs.prefix}}/lib/libSDL2.so' '${{github.workspace}}/install'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@@ -138,14 +119,19 @@ jobs:
|
||||
run: |
|
||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
|
||||
|
||||
- name: Install required packages
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: sdl2-latest
|
||||
build-type: Release
|
||||
cmake-arguments: "-A ${{ matrix.architecture.config }}"
|
||||
|
||||
- name: Install Flex/Bison
|
||||
working-directory: ${{github.workspace}}
|
||||
run: |
|
||||
mkdir thirdparties && cd thirdparties
|
||||
git clone --depth 1 --single-branch --branch SDL2 https://github.com/libsdl-org/SDL.git
|
||||
cmake -B SDL-build -A ${{ matrix.architecture.config }} -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/SDL-install' ./SDL
|
||||
cmake --build SDL-build --config Release --parallel
|
||||
cmake --install SDL-build
|
||||
git clone --depth 1 --single-branch --branch v2.5.25 https://github.com/lexxmark/winflexbison.git
|
||||
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
|
||||
cmake --build winflexbison-build --config Release --parallel
|
||||
@@ -161,13 +147,9 @@ jobs:
|
||||
--log-level=VERBOSE `
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
|
||||
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
|
||||
-DCMAKE_C_COMPILER=clang `
|
||||
-DCMAKE_CXX_COMPILER=clang++ `
|
||||
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
|
||||
-DSDL2_DIR='${{github.workspace}}/thirdparties/SDL-install/cmake' `
|
||||
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
|
||||
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe' `
|
||||
-DWITH_CLIENT=1".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
|
||||
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}
|
||||
@@ -192,7 +174,7 @@ jobs:
|
||||
# Install to the directory defined in CMAKE_INSTALL_PREFIX
|
||||
run: |
|
||||
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
Copy-Item "${{github.workspace}}/thirdparties/SDL-install/bin/*.dll" -Destination "${{github.workspace}}/install"
|
||||
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
||||
@@ -43,6 +43,13 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Setup SDL
|
||||
- name: Set up SDL
|
||||
id: sdl
|
||||
uses: libsdl-org/setup-sdl@main
|
||||
with:
|
||||
version: sdl2-latest
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
|
||||
@@ -18,6 +18,9 @@ jobs:
|
||||
|
||||
deploy_all:
|
||||
strategy:
|
||||
# Set the maximum number of parallel jobs to 1, to avoid a race-condition
|
||||
# while creating a new release
|
||||
max-parallel: 1
|
||||
matrix:
|
||||
target_os: [
|
||||
'linux-amd64',
|
||||
|
||||
+10
-6
@@ -12,6 +12,7 @@ endif()
|
||||
|
||||
|
||||
set(TARGET_BASE_GAME "main")
|
||||
set(CMAKE_DEBUG_POSTFIX "-dbg")
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
@@ -21,6 +22,10 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
add_compile_options(-Wno-pointer-bool-conversion)
|
||||
endif()
|
||||
|
||||
if(DEBUG_MEMORY)
|
||||
add_definitions(-D_DEBUG_MEM)
|
||||
endif()
|
||||
|
||||
IF("${TARGET_ARCH}" STREQUAL "i386")
|
||||
set(TARGET_ARCH_SUFFIX "x86")
|
||||
ELSE()
|
||||
@@ -40,7 +45,6 @@ ELSE()
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(TARGET_CONFIG_SUFFIX "-dbg")
|
||||
add_definitions(-D_DEBUG)
|
||||
|
||||
#if(UNIX)
|
||||
@@ -48,8 +52,6 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
# set(CMAKE_ENABLE_EXPORTS ON)
|
||||
# message(STATUS "Enabling exports on Unix for backtrace")
|
||||
#endif()
|
||||
ELSE()
|
||||
set(TARGET_CONFIG_SUFFIX "")
|
||||
ENDIF()
|
||||
|
||||
# Common stuff
|
||||
@@ -73,7 +75,8 @@ target_link_libraries(omohaaded PRIVATE syslib)
|
||||
target_link_libraries(omohaaded PRIVATE qcommon qcommon_standalone)
|
||||
# Gamespy dependency
|
||||
target_include_directories(omohaaded PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server")
|
||||
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
|
||||
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(omohaaded PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
|
||||
if (MSVC)
|
||||
target_link_options(omohaaded PRIVATE "/MANIFEST:NO")
|
||||
@@ -82,7 +85,7 @@ endif()
|
||||
|
||||
INSTALL(TARGETS omohaaded DESTINATION "./")
|
||||
|
||||
if (WITH_CLIENT)
|
||||
if (NOT BUILD_NO_CLIENT)
|
||||
## Client app
|
||||
|
||||
add_subdirectory("code/renderer")
|
||||
@@ -103,7 +106,8 @@ if (WITH_CLIENT)
|
||||
|
||||
### Gamespy dependency
|
||||
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib" "code/jpeg-8c")
|
||||
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
|
||||
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(openmohaa PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
|
||||
target_link_libraries(openmohaa PRIVATE jpeg8)
|
||||
if (USE_OPENAL)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
## Current State
|
||||
|
||||
OpenMoHAA is still in its early days. The singleplayer part is not working correctly, the current usage is multiplayer.
|
||||
OpenMoHAA is still under development. The single-player campaign is not yet functional due to AI not being fully implemented, and due to the script engine having a few issues. But the `training` map can be played from start to end. The current focus is on multiplayer.
|
||||
|
||||
## Running
|
||||
|
||||
@@ -37,53 +37,64 @@ https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=ms
|
||||
|
||||
You can now start a local OpenMOHAA server or play on a server.
|
||||
|
||||
To play expansions, append to the executable `+set com_target_game 1` for Spearhead, and `+set com_target_game 2` for Breakthrough. On windows you can make a shortcut.
|
||||
**Medal of Honor: Allied Assault Spearhead** and **Medal of Honor: Allied Assault Breakthrough** are supported in OpenMoHAA using the `com_target_game` variable. To play an expansion, append the following command-line arguments to the executable:
|
||||
|
||||
- `+set com_target_game 1` for Spearhead (mohaas/mohta)
|
||||
- `+set com_target_game 2` for Breakthrough (mohaab/mohtt)
|
||||
|
||||
On Windows, you can create a shortcut to OpenMoHAA with these command-line arguments.
|
||||
The default value of `com_target_game` is 0 for the base game.
|
||||
|
||||
With `com_target_game`, OpenMoHAA will support the network protocol accordingly
|
||||
|
||||
### Playing with bots
|
||||
|
||||
OpenMoHAA has a basic bot system that emulates real players. The maximum number of bots is defined by the `sv_maxbots` variable, and the number of initial bots is defined by the `sv_numbots` variable. Bots can also be added or removed using the `addbot` and `removebot` commands.
|
||||
|
||||
This feature is a great way to test the gameplay and mods.
|
||||
|
||||
## Builds
|
||||
|
||||
### Server
|
||||
|
||||
The server version can successfully be built.
|
||||
Some stuff are not working as intended, such as Actor or Vehicle. These systems are both almost fully implemented, but not really in stable state.
|
||||
The server version can be built successfully, but some features are not functional. For example, the Actor and Vehicle systems are almost fully implemented, but they are not yet stable. This means that they may not work as expected and could cause crashes.
|
||||
|
||||
Overall the server part and the game module are almost fully implemented, but the stability may vary, there may be some minor bugs and crashes.
|
||||
Overall, the server and the fgame components are almost fully implemented, but they may not be completely stable. There could be some minor bugs (and rare crashes), but the game should be playable.
|
||||
|
||||
### Client
|
||||
|
||||
The client version of OpenMoHAA is partially implemented and not stable currently. The cgame module is partially implemented as well, but is compatible with the original MOH:AA game. Credits to **Heavy Metal: F.A.K.K. 2**'s SDK for the cgame module.
|
||||
The client version of OpenMoHAA has undergone partial implementation, with the cgame module being nearly completed. Credits to the SDK of **Heavy Metal: F.A.K.K. 2** both the cgame and fgame modules.
|
||||
|
||||
Here is the current working state for each part of the engine:
|
||||
The current operational status for each component is as follow:
|
||||
|
||||
| Part name | Full | Almost | Half | Early | Bad | Not working | Comment |
|
||||
| Component | Full | Almost | Half | Early | Bad | Not working | Comment |
|
||||
|-------------------------|------|--------|------|-------|-----|-------------|-------------------------------------------------------------------|
|
||||
| Audio | | | | | x | | Very basic implementation from Quake III |
|
||||
| CG Module | | x | | | | | Missing FX, Marks and decals |
|
||||
| Client | | | x | | | | Missing GameSpy, server list, binds, map picker, ... |
|
||||
| Client | | x | | | | | Missing GameSpy, server list, binds, map picker, ... |
|
||||
| Collision | x | | | | | | |
|
||||
| Model/TIKI/Skeletor | x | | | | | | |
|
||||
| Renderer | | | | x | | | Missing ghost, marks, sphere lights, sky portal, sun flare, swipe |
|
||||
| Renderer | | x | | | | | Missing ghost, marks, sphere lights, sky portal, sun flare, swipe |
|
||||
| Server | | x | | | | | Probably a few bugs remaining |
|
||||
| Server module (fgame) | | x | | | | | Actor, vehicle, and few gameplay bugs |
|
||||
| UI | | | | x | | | Has core features only (menu, widgets, console, hud, urc loading) |
|
||||
|
||||
**Medal of Honor: Allied Assault Spearhead** and **Medal of Honor: Allied Assault Breakthrough** are supported in OpenMoHAA with the `com_target_game` variable. See the **Running** section for the usage.
|
||||
| UI | | | x | | | | Has core features only (menu, widgets, console, hud, urc loading) |
|
||||
|
||||
## Compiling
|
||||
|
||||
OpenMoHAA supports both x86 and x64 architectures, and although the target platform is Windows, it still can be compiled for other platforms, and even other architectures.
|
||||
OpenMoHAA supports any architecture, thanks to the CMake build system and cross-platform code/libraries. While the most common little-Endian architectures (arm, aarch64, x86, x86_64) have been tested and confirmed to work, big-Endian architectures should be supported as well; however, they remain untested.
|
||||
|
||||
These are the tools required for all platforms :
|
||||
The following tools are required for all platforms:
|
||||
- CMake >= 3.5
|
||||
- Flex and Bison (currently not used)
|
||||
- A C++11 compiler is required.
|
||||
- Flex and Bison
|
||||
- A C++11 compiler is also required.
|
||||
|
||||
The installation directory can be set to MOHAA directory.
|
||||
The installation directory can be set to the MOHAA directory.
|
||||
|
||||
The client build can be built by adding `-DWITH_CLIENT=1` to the CMake command line. This will compile the cgame module and the full app with rendering, ui and sound suppport, alongside the dedicated server version.
|
||||
By default, the build will produce both the client and dedicated server versions. The client build can be excluded by appending `-DBUILD_NO_CLIENT=1` to the CMake command-line arguments. Using this parameter will result in only the server portion being built.
|
||||
|
||||
### Linux
|
||||
|
||||
These are the tools required on Unix :
|
||||
These are the tools required on Linux :
|
||||
- Clang >= 3.3 or GCC >= 4.8.1
|
||||
|
||||
**clang-3.5** and **gcc-4.8.5** should work (tested on Ubuntu 16.04). Use the latest possible version of those compilers.
|
||||
@@ -95,19 +106,24 @@ SDL2 library is required (libsdl2-dev).
|
||||
Example with **CMake**, **clang-15** and **ninja-build** installed:
|
||||
```sh
|
||||
mkdir .cmake && cd .cmake
|
||||
cmake -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 -DWITH_CLIENT=1 -G Ninja
|
||||
cmake -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 -G Ninja
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
Visual Studio (2019 or 2022) is generally preferred.
|
||||
|
||||
Flex and Bison can be downloaded from here: https://github.com/lexxmark/winflexbison/releases/tag/v2.5.25
|
||||
|
||||
Append `-DFLEX_EXECUTABLE=...\win_flex.exe -DBISON_EXECUTABLE=...\win_bison.exe` to the CMake command-line to use the package from the link above.
|
||||
|
||||
## Screenshots
|
||||
|
||||
| | |
|
||||
|-------------------------------------------------------------------------------|-----------------------------------------------------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
| | |
|
||||
|-------------------------------------------------------------------------------|----------------------------------------------------------------------|
|
||||
|  |  |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
|
||||
## Third party
|
||||
@@ -116,20 +132,14 @@ Visual Studio (2019 or 2022) is generally preferred.
|
||||
|
||||
http://www.libsdl.org/
|
||||
|
||||
download Source code, compile
|
||||
|
||||
### OpenAL
|
||||
|
||||
https://www.openal.org/ download OpenAL soft source
|
||||
|
||||
run cmake on OpenAL, compile
|
||||
https://www.openal.org/
|
||||
|
||||
### LibMAD
|
||||
|
||||
http://www.underbit.com/products/mad/
|
||||
|
||||
download source code, compile
|
||||
|
||||
### cURL
|
||||
|
||||
https://curl.se/
|
||||
|
||||
+24
-16
@@ -1,36 +1,44 @@
|
||||
set(archdetect_c_code "
|
||||
#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||
#error cmake_ARCH x86
|
||||
# error cmake_ARCH x86
|
||||
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
|
||||
#error cmake_ARCH x86_64
|
||||
# error cmake_ARCH x86_64
|
||||
#elif defined(__ppc64__) || defined(__powerpc64__)
|
||||
#error cmake_ARCH ppc64
|
||||
# error cmake_ARCH ppc64
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__)
|
||||
#error cmake_ARCH ppc
|
||||
# error cmake_ARCH ppc
|
||||
#elif defined __s390__
|
||||
#error cmake_ARCH s390
|
||||
# error cmake_ARCH s390
|
||||
#elif defined __s390x__
|
||||
#error cmake_ARCH s390x
|
||||
# error cmake_ARCH s390x
|
||||
#elif defined __ia64__
|
||||
#error cmake_ARCH ia64
|
||||
# error cmake_ARCH ia64
|
||||
#elif defined __e2k__
|
||||
# error cmake_ARCH e2k
|
||||
#elif defined __alpha__
|
||||
#error cmake_ARCH alpha
|
||||
# error cmake_ARCH alpha
|
||||
#elif defined __sparc__
|
||||
#error cmake_ARCH sparc
|
||||
# error cmake_ARCH sparc
|
||||
#elif defined __arm__ || defined (_M_ARM)
|
||||
#error cmake_ARCH arm
|
||||
# error cmake_ARCH arm
|
||||
#elif defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
|
||||
#error cmake_ARCH aarch64
|
||||
# error cmake_ARCH aarch64
|
||||
#elif defined __cris__
|
||||
#error cmake_ARCH cris
|
||||
# error cmake_ARCH cris
|
||||
#elif defined __hppa__
|
||||
#error cmake_ARCH hppa
|
||||
# error cmake_ARCH hppa
|
||||
#elif defined __mips__
|
||||
#error cmake_ARCH mips
|
||||
# error cmake_ARCH mips
|
||||
#elif defined __sh__
|
||||
#error cmake_ARCH sh
|
||||
# error cmake_ARCH sh
|
||||
#elif defined __riscv
|
||||
# if __UINTPTR_MAX__ == __UINT64_MAX__
|
||||
# error cmake_ARCH riscv64
|
||||
# else
|
||||
# error cmake_ARCH riscv
|
||||
# endif
|
||||
#else
|
||||
#error cmake_ARCH unknown
|
||||
# error cmake_ARCH unknown
|
||||
#endif
|
||||
|
||||
")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(fgame)
|
||||
project(cgame)
|
||||
|
||||
# Shared source files for modules
|
||||
set(SOURCES_SHARED
|
||||
@@ -28,13 +28,13 @@ target_compile_features(cgame PUBLIC c_variadic_macros)
|
||||
target_link_libraries(cgame PUBLIC qcommon)
|
||||
|
||||
set_target_properties(cgame PROPERTIES PREFIX "${TARGET_PLATFORM_PREFIX}")
|
||||
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
|
||||
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(cgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
|
||||
|
||||
INSTALL(
|
||||
TARGETS cgame
|
||||
DESTINATION "${TARGET_BASE_GAME}"
|
||||
ARCHIVE EXCLUDE_FROM_ALL
|
||||
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
|
||||
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_archive.h"
|
||||
|
||||
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void CG_SaveStateToBuffer(void** out, int svsTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void CG_LoadStateToBuffer(void* state, int size, int svsTime)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void CG_ArchiveStringContainer(MemArchiver& archiver, Container<str>* container)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void CG_ArchiveTikiPointer(MemArchiver& archiver, dtiki_t** pTiki)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// DESCRIPTION:
|
||||
// Memory archiver
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "../qcommon/container.h"
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
class MemArchiver {
|
||||
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void CG_SaveStateToBuffer(void** out, int svsTime);
|
||||
void CG_LoadStateToBuffer(void* state, int size, int svsTime);
|
||||
|
||||
#ifdef __cplusplus
|
||||
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime);
|
||||
void CG_ArchiveStringContainer(MemArchiver& archiver, Container<str>* container);
|
||||
void CG_ArchiveTikiPointer(MemArchiver& archiver, dtiki_t** pTiki);
|
||||
void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle);
|
||||
void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle);
|
||||
void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -4316,7 +4316,7 @@ void ClientGameCommandManager::UpdateEmitter(
|
||||
VectorCopy(current_entity->origin, m_spawnthing->linked_origin);
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
VectorMA(m_spawnthing->linked_origin, ori.origin[i], current_entity->axis[i], m_spawnthing->linked_origin);
|
||||
VectorMA(m_spawnthing->linked_origin, ori.origin[i], current_entity->axis[j], m_spawnthing->linked_origin);
|
||||
}
|
||||
MatrixMultiply(ori.axis, current_entity->axis, m_spawnthing->linked_axis);
|
||||
}
|
||||
@@ -4548,6 +4548,11 @@ void ClientGameCommandManager::FreeAllTempModels(void)
|
||||
}
|
||||
}
|
||||
|
||||
void ClientGameCommandManager::FreeSomeTempModels(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
//===============
|
||||
// FreeAllEmitters
|
||||
//===============
|
||||
@@ -4564,6 +4569,11 @@ void CG_RestartCommandManager()
|
||||
commandManager.FreeAllTempModels();
|
||||
}
|
||||
|
||||
void CG_CleanUpTempModels()
|
||||
{
|
||||
commandManager.FreeSomeTempModels();
|
||||
}
|
||||
|
||||
//=================
|
||||
// CG_ProcessInitCommands
|
||||
//=================
|
||||
|
||||
@@ -883,6 +883,7 @@ public:
|
||||
spawnthing_t *InitializeSpawnthing(spawnthing_t *ep);
|
||||
void SpawnEffect(int count, spawnthing_t *sp);
|
||||
void FreeAllTempModels(void);
|
||||
void FreeSomeTempModels(void);
|
||||
void RestartAllEmitters(void);
|
||||
|
||||
void InitializeTempModels(void);
|
||||
|
||||
@@ -110,8 +110,8 @@ void CG_ScoresDown_f(void)
|
||||
void CG_ScoresUp_f(void)
|
||||
{
|
||||
if (cgs.gametype == GT_SINGLE_PLAYER) {
|
||||
if (!cg.scoresRequestTime) {
|
||||
cg.scoresRequestTime = cg.time;
|
||||
if (cg.scoresRequestTime) {
|
||||
cg.scoresRequestTime = 0;
|
||||
CG_SetDesiredObjectiveAlpha(0.0f);
|
||||
}
|
||||
|
||||
|
||||
+11
-10
@@ -687,10 +687,11 @@ void CG_DrawObjectives()
|
||||
|
||||
iCurrentObjective = atoi(CG_ConfigString(CS_CURRENT_OBJECTIVE));
|
||||
fTimeDelta = cg.ObjectivesAlphaTime - cg.time;
|
||||
if (fTimeDelta > 0.0) {
|
||||
cg.ObjectivesCurrentAlpha = cg.ObjectivesDesiredAlpha;
|
||||
if (fTimeDelta > 0) {
|
||||
cg.ObjectivesCurrentAlpha =
|
||||
(cg.ObjectivesBaseAlpha - cg.ObjectivesDesiredAlpha) * sin(fTimeDelta * 0.0062831854)
|
||||
+ cg.ObjectivesCurrentAlpha;
|
||||
(cg.ObjectivesBaseAlpha - cg.ObjectivesDesiredAlpha) * sin(fTimeDelta / (M_PI * 50.f + 2.f))
|
||||
+ cg.ObjectivesDesiredAlpha;
|
||||
}
|
||||
|
||||
if (cg.ObjectivesCurrentAlpha < 0.02) {
|
||||
@@ -702,12 +703,12 @@ void CG_DrawObjectives()
|
||||
iNumLines[i] = 0;
|
||||
|
||||
for (ii = 0; ii < MAX_STRING_CHARS; ii++) {
|
||||
if (cg.Objectives[i].text[ii] == 10) {
|
||||
if (cg.Objectives[i].text[ii] == '\n') {
|
||||
iTotalNumLines++;
|
||||
iNumLines[ii]++;
|
||||
iNumLines[i]++;
|
||||
} else if (!cg.Objectives[i].text[ii]) {
|
||||
iTotalNumLines++;
|
||||
iNumLines[ii]++;
|
||||
iNumLines[i]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -740,17 +741,17 @@ void CG_DrawObjectives()
|
||||
for (i = 0; i < MAX_OBJECTIVES; ++i) {
|
||||
qhandle_t hBoxShader;
|
||||
|
||||
if ((cg.Objectives[i].flags & 1) || !cg.Objectives[i].flags) {
|
||||
if ((cg.Objectives[i].flags & OBJ_FLAG_HIDDEN) || !cg.Objectives[i].flags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((cg.Objectives[i].flags & 2) != 0) {
|
||||
if ((cg.Objectives[i].flags & OBJ_FLAG_CURRENT) != 0) {
|
||||
vColor[0] = 1.0;
|
||||
vColor[1] = 1.0;
|
||||
vColor[2] = 1.0;
|
||||
vColor[3] = cg.ObjectivesCurrentAlpha;
|
||||
hBoxShader = cgs.media.uncheckedBoxShader;
|
||||
} else if ((cg.Objectives[i].flags & 4) != 0) {
|
||||
} else if ((cg.Objectives[i].flags & OBJ_FLAG_COMPLETED) != 0) {
|
||||
vColor[0] = 0.75;
|
||||
vColor[1] = 0.75;
|
||||
vColor[2] = 0.75;
|
||||
@@ -763,7 +764,7 @@ void CG_DrawObjectives()
|
||||
vColor[3] = cg.ObjectivesCurrentAlpha;
|
||||
hBoxShader = cgs.media.uncheckedBoxShader;
|
||||
}
|
||||
if (i == iCurrentObjective && (cg.Objectives[i].flags & 4) == 0) {
|
||||
if (i == iCurrentObjective && !(cg.Objectives[i].flags & OBJ_FLAG_COMPLETED)) {
|
||||
vColor[0] = 1.0;
|
||||
vColor[1] = 1.0;
|
||||
vColor[2] = 0.0;
|
||||
|
||||
@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// cg_ents.c -- present snapshot entities, happens every single frame
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_radar.h"
|
||||
|
||||
/*
|
||||
==========================================================================
|
||||
@@ -551,7 +552,10 @@ void CG_AddCEntity(centity_t *cent)
|
||||
break;
|
||||
case ET_PLAYER:
|
||||
CG_Player(cent);
|
||||
CG_Splash(cent);
|
||||
CG_Splash(cent);
|
||||
CG_ModelAnim(cent, qfalse);
|
||||
CG_UpdateRadarClient(cent);
|
||||
break;
|
||||
case ET_ITEM:
|
||||
CG_ModelAnim(cent, qfalse);
|
||||
break;
|
||||
@@ -666,7 +670,6 @@ void CG_GetOrigin(centity_t *cent, vec3_t origin)
|
||||
parent = cgi.R_GetRenderEntity(cent->currentState.parent);
|
||||
|
||||
if (!parent) {
|
||||
cgi.DPrintf("CG_GetOrigin: Could not find parent entity\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -341,7 +341,9 @@ extern "C" {
|
||||
|
||||
// misc
|
||||
crain_t rain;
|
||||
clientInfo_t clientinfo[MAX_CLIENTS];
|
||||
clientInfo_t clientinfo[MAX_CLIENTS];
|
||||
radarClient_t radars[MAX_CLIENTS];
|
||||
qhandle_t radarShaders[2];
|
||||
} cg_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -519,6 +521,7 @@ extern "C" {
|
||||
void CG_EndTiki(dtiki_t *tiki);
|
||||
qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *curTiki);
|
||||
void CG_RestartCommandManager();
|
||||
void CG_CleanUpTempModels();
|
||||
qboolean CG_ProcessEntityCommands(int frame, int anim, int entnum, refEntity_t *ent, centity_t *cent);
|
||||
void CG_ClientCommands(refEntity_t *ent, centity_t *cent, int slot);
|
||||
float RandomizeRange(float start, float end);
|
||||
|
||||
@@ -25,6 +25,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_parsemsg.h"
|
||||
#include "cg_archive.h"
|
||||
#include "cg_radar.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
@@ -677,6 +679,11 @@ clientGameExport_t *GetCGameAPI(void)
|
||||
cge.CG_GetObjectiveAlpha = CG_GetObjectiveAlpha;
|
||||
cge.CG_WeaponCommandButtonBits = CG_WeaponCommandButtonBits;
|
||||
cge.CG_CheckCaptureKey = CG_CheckCaptureKey;
|
||||
cge.CG_ReadNonPVSClient = CG_ReadNonPVSClient;
|
||||
cge.CG_UpdateRadar = CG_UpdateRadar;
|
||||
cge.CG_SaveStateToBuffer = CG_SaveStateToBuffer;
|
||||
cge.CG_LoadStateToBuffer = CG_LoadStateToBuffer;
|
||||
cge.CG_CleanUpTempModels = CG_CleanUpTempModels;
|
||||
|
||||
// FIXME
|
||||
//cge.profStruct = NULL;
|
||||
|
||||
@@ -477,6 +477,24 @@ void CG_PredictPlayerState(void)
|
||||
}
|
||||
|
||||
cg_pmove.noFootsteps = (cgs.dmflags & DF_NO_FOOTSTEPS) > 0;
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
// Leaning while moving is allowed in mohta and mohtt only with a specific dm flag bit set
|
||||
cg_pmove.alwaysAllowLean = (cgs.dmflags & DF_ALLOW_LEAN_MOVEMENT) ? qtrue : qfalse;
|
||||
|
||||
cg_pmove.leanMax = 45.f;
|
||||
cg_pmove.leanAdd = 6.f;
|
||||
cg_pmove.leanRecoverSpeed = 8.5f;
|
||||
cg_pmove.leanSpeed = 2.f;
|
||||
} else {
|
||||
cg_pmove.alwaysAllowLean = qtrue;
|
||||
|
||||
cg_pmove.leanMax = 40.f;
|
||||
cg_pmove.leanAdd = 10.f;
|
||||
cg_pmove.leanRecoverSpeed = 15.f;
|
||||
cg_pmove.leanSpeed = 4.f;
|
||||
}
|
||||
|
||||
cg_pmove.protocol = cg_protocol;
|
||||
|
||||
// save the state before the pmove so we can detect transitions
|
||||
oldPlayerState = cg.predicted_player_state;
|
||||
|
||||
+16
-6
@@ -23,8 +23,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
// DESCRIPTION:
|
||||
// client game public interfaces
|
||||
|
||||
#ifndef __CG_PUBLIC_H__
|
||||
#define __CG_PUBLIC_H__
|
||||
#pragma once
|
||||
|
||||
#include "../renderercommon/tr_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -67,7 +68,7 @@ extern "C" {
|
||||
typedef struct stopWatch_s {
|
||||
int iStartTime;
|
||||
int iEndTime;
|
||||
|
||||
int eType;
|
||||
} stopWatch_t;
|
||||
|
||||
typedef struct AliasList_s AliasList_t;
|
||||
@@ -283,7 +284,6 @@ functions exported to the main executable
|
||||
qhandle_t (*R_SpawnEffectModel)(const char *name, vec3_t pos, vec3_t axis[3]);
|
||||
qhandle_t (*R_RegisterServerModel)(const char *name);
|
||||
void (*R_UnregisterServerModel)(qhandle_t hModel);
|
||||
qhandle_t (*R_RegisterSkin)(const char *name);
|
||||
qhandle_t (*R_RegisterShader)(const char *name);
|
||||
qhandle_t (*R_RegisterShaderNoMip)(const char *name);
|
||||
void (*R_AddRefEntityToScene)(const refEntity_t *ent, int parentEntityNumber);
|
||||
@@ -419,9 +419,12 @@ functions exported to the main executable
|
||||
);
|
||||
void (*UI_DeleteScoreBoardItems)(int maxIndex);
|
||||
void (*UI_ToggleDMMessageConsole)(int consoleMode);
|
||||
void (*CL_InitRadar)(radarClient_t* radars, qhandle_t* shaders, int clientNum); // Added in 2.0
|
||||
dtiki_t *(*TIKI_FindTiki)(const char *path);
|
||||
void (*LoadResource)(const char *name);
|
||||
void (*FS_CanonicalFilename)(char *name);
|
||||
void (*CL_RestoreSavedCgameState)();
|
||||
void (*CL_ClearSavedCgameState)();
|
||||
|
||||
cvar_t *fsDebug;
|
||||
hdelement_t *HudDrawElements;
|
||||
@@ -491,6 +494,15 @@ functions exported to the main executable
|
||||
int (*CG_WeaponCommandButtonBits)();
|
||||
int (*CG_CheckCaptureKey)(int key, qboolean down, unsigned int time);
|
||||
|
||||
//
|
||||
// Added in 2.0
|
||||
//
|
||||
void (*CG_ReadNonPVSClient)(radarUnpacked_t* radarUnpacked);
|
||||
void (*CG_UpdateRadar)();
|
||||
void (*CG_SaveStateToBuffer)(void** out, int svsTime);
|
||||
void (*CG_LoadStateToBuffer)(void** state, int size, int svsTime);
|
||||
void (*CG_CleanUpTempModels)();
|
||||
|
||||
// FIXME
|
||||
//prof_cgame_t* profStruct;
|
||||
|
||||
@@ -510,5 +522,3 @@ functions exported to the main executable
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __CG_PUBLIC_H__
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "cg_local.h"
|
||||
#include "cg_radar.h"
|
||||
|
||||
void CG_InitRadar()
|
||||
{
|
||||
int i;
|
||||
|
||||
cg.radarShaders[0] = cgi.R_RegisterShader("textures/hud/radar_allies.tga");
|
||||
cg.radarShaders[1] = cgi.R_RegisterShader("textures/hud/radar_axis.tga");
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
cg.radars[i].time = 0;
|
||||
cg.radars[i].lastSpeakTime = 0;
|
||||
}
|
||||
|
||||
cgi.CL_InitRadar(cg.radars, cg.radarShaders, cg.snap->ps.clientNum);
|
||||
}
|
||||
|
||||
bool CG_InTeamGame(centity_t *ent)
|
||||
{
|
||||
return ent->currentState.solid && cg.clientinfo[ent->currentState.number].team;
|
||||
}
|
||||
|
||||
bool CG_SameTeam(centity_t *ent)
|
||||
{
|
||||
return cg.clientinfo[ent->currentState.number].team == cg.clientinfo[cg.snap->ps.clientNum].team;
|
||||
}
|
||||
|
||||
bool CG_IsTeamGame()
|
||||
{
|
||||
return cgs.gametype >= GT_TEAM;
|
||||
}
|
||||
|
||||
bool CG_ValidRadarClient(centity_t *ent)
|
||||
{
|
||||
if (!cg.snap) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (!CG_IsTeamGame()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CG_InTeamGame(&cg_entities[cg.snap->ps.clientNum])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CG_InTeamGame(ent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CG_SameTeam(ent);
|
||||
}
|
||||
|
||||
int CG_RadarIcon()
|
||||
{
|
||||
switch (cg.clientinfo[cg.snap->ps.clientNum].team)
|
||||
{
|
||||
case TEAM_ALLIES:
|
||||
return 0;
|
||||
default:
|
||||
case TEAM_AXIS:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void CG_UpdateRadarClient(centity_t* ent)
|
||||
{
|
||||
radarClient_t* radar;
|
||||
|
||||
radar = &cg.radars[ent->currentState.number];
|
||||
if (!CG_ValidRadarClient(ent)) {
|
||||
radar->time = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
radar->time = cg.time;
|
||||
radar->teamShader = CG_RadarIcon();
|
||||
if (cg.snap->ps.clientNum == ent->currentState.number)
|
||||
{
|
||||
radar->origin[0] = cg.refdef.vieworg[0];
|
||||
radar->origin[1] = cg.refdef.vieworg[1];
|
||||
radar->axis[0] = cg.refdef.viewaxis[0][0];
|
||||
radar->axis[1] = cg.refdef.viewaxis[0][1];
|
||||
VectorNormalize2D(radar->axis);
|
||||
}
|
||||
else
|
||||
{
|
||||
float axis[2];
|
||||
|
||||
radar->origin[0] = ent->currentState.origin[0];
|
||||
radar->origin[1] = ent->currentState.origin[1];
|
||||
YawToAxis(ent->currentState.angles[1], axis);
|
||||
|
||||
radar->axis[0] = axis[0];
|
||||
radar->axis[1] = axis[1];
|
||||
VectorNormalize2D(radar->axis);
|
||||
}
|
||||
}
|
||||
|
||||
void CG_ReadNonPVSClient(radarUnpacked_t* radarUnpacked)
|
||||
{
|
||||
radarClient_t* radar;
|
||||
float axis[2];
|
||||
|
||||
if (!CG_ValidRadarClient(&cg_entities[radarUnpacked->clientNum])) {
|
||||
return;
|
||||
}
|
||||
|
||||
radar = &cg.radars[radarUnpacked->clientNum];
|
||||
radar->time = cg.time;
|
||||
radar->teamShader = CG_RadarIcon();
|
||||
// copy origin
|
||||
radar->origin[0] = radarUnpacked->x;
|
||||
radar->origin[1] = radarUnpacked->y;
|
||||
// copy yaw
|
||||
YawToAxis(radarUnpacked->yaw, axis);
|
||||
radar->axis[0] = axis[0];
|
||||
radar->axis[1] = axis[1];
|
||||
VectorNormalize2D(radar->axis);
|
||||
}
|
||||
|
||||
void CG_UpdateRadar()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if (cg.radars[i].time)
|
||||
{
|
||||
if (!CG_ValidRadarClient(&cg_entities[i])) {
|
||||
cg.radars[i].time = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CG_RadarClientSpeaks(int num)
|
||||
{
|
||||
if (!CG_ValidRadarClient(&cg_entities[num])) {
|
||||
return;
|
||||
}
|
||||
|
||||
cg.radars[num].lastSpeakTime = cg.time;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// DESCRIPTION:
|
||||
// Radar client
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cg_local.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void CG_InitRadar();
|
||||
void CG_UpdateRadarClient(centity_t* ent);
|
||||
void CG_ReadNonPVSClient(radarUnpacked_t* radarUnpacked);
|
||||
void CG_UpdateRadar();
|
||||
void CG_RadarClientSpeaks(int num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+21
-14
@@ -241,6 +241,13 @@ static void CG_Stopwatch_f()
|
||||
|
||||
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
|
||||
cgi.stopWatch->iStartTime = atoi(cgi.Argv(1));
|
||||
|
||||
if (cgi.Argc() > 3) {
|
||||
cgi.stopWatch->eType = atoi(cgi.Argv(3));
|
||||
} else {
|
||||
// Normal stop watch
|
||||
cgi.stopWatch->eType = SWT_NORMAL;
|
||||
}
|
||||
} else {
|
||||
// The base game has it wrong
|
||||
cgi.stopWatch->iStartTime = 1000 * atoi(cgi.Argv(1));
|
||||
@@ -291,19 +298,19 @@ static void CG_ServerCommand(void)
|
||||
}
|
||||
return;
|
||||
} else if (!strcmp(cmd, "printdeathmsg")) {
|
||||
const char *s1, *s2, *s3, *s4, *s5;
|
||||
const char *s1, *s2, * attackerName, * victimName, *type;
|
||||
const char *result1, *result2;
|
||||
int hudColor;
|
||||
|
||||
result1 = NULL;
|
||||
result2 = NULL;
|
||||
s1 = cgi.Argv(1);
|
||||
s2 = cgi.Argv(2);
|
||||
s3 = cgi.Argv(3);
|
||||
s4 = cgi.Argv(4);
|
||||
s5 = cgi.Argv(5);
|
||||
s1 = cgi.Argv(1);
|
||||
s2 = cgi.Argv(2);
|
||||
attackerName = cgi.Argv(3);
|
||||
victimName = cgi.Argv(4);
|
||||
type = cgi.Argv(5);
|
||||
|
||||
if (*s5 == tolower(*s5)) {
|
||||
if (*type == tolower(*type)) {
|
||||
hudColor = 4;
|
||||
} else {
|
||||
hudColor = 5;
|
||||
@@ -315,16 +322,16 @@ static void CG_ServerCommand(void)
|
||||
if (*s2 != 'x') {
|
||||
result2 = cgi.LV_ConvertString(s2);
|
||||
}
|
||||
if (tolower(*s5) == 's') {
|
||||
cgi.Printf("%c%s %s\n", hudColor, s4, result1);
|
||||
} else if (tolower(*s5) == 'p') {
|
||||
if (tolower(*type) == 's') {
|
||||
cgi.Printf("%c%s %s\n", hudColor, victimName, result1);
|
||||
} else if (tolower(*type) == 'p') {
|
||||
if (*s2 == 'x') {
|
||||
cgi.Printf("%c%s %s %s\n", hudColor, s4, result1, s3);
|
||||
cgi.Printf("%c%s %s %s\n", hudColor, victimName, result1, attackerName);
|
||||
} else {
|
||||
cgi.Printf("%c%s %s %s%s\n", hudColor, s4, result1, s3, result2);
|
||||
cgi.Printf("%c%s %s %s%s\n", hudColor, victimName, result1, attackerName, result2);
|
||||
}
|
||||
} else if (tolower(*s5) == 'w') {
|
||||
cgi.Printf("%c%s %s\n", hudColor, s4, result1);
|
||||
} else if (tolower(*type) == 'w') {
|
||||
cgi.Printf("%c%s %s\n", hudColor, victimName, result1);
|
||||
} else {
|
||||
cgi.Printf("%s", cgi.Argv(1));
|
||||
}
|
||||
|
||||
@@ -161,6 +161,9 @@ void CG_SetInitialSnapshot(snapshot_t *snap)
|
||||
cgi.MUSIC_UpdateMood(snap->ps.current_music_mood, snap->ps.fallback_music_mood);
|
||||
cgi.MUSIC_UpdateVolume(snap->ps.music_volume, snap->ps.music_volume_fade_time);
|
||||
cgi.S_SetReverb(snap->ps.reverb_type, snap->ps.reverb_level);
|
||||
|
||||
CG_InitRadar();
|
||||
cgi.CL_RestoreSavedCgameState();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -287,6 +287,7 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
|
||||
pSource->lastOrigin = pSource->newOrigin;
|
||||
|
||||
if (pSource->flags & 0x800) {
|
||||
trace.allsolid = qfalse;
|
||||
CG_ClipMoveToEntities(
|
||||
pSource->newOrigin, vec3_origin, vec3_origin, pSource->newOrigin, -1, MASK_VOLUMETRIC_SMOKE, &trace, qfalse
|
||||
);
|
||||
|
||||
@@ -19,5 +19,4 @@ target_link_libraries(omohclient INTERFACE gcd)
|
||||
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
|
||||
|
||||
add_subdirectory("../libmad-0.15.1b" "./libmad")
|
||||
target_link_libraries(omohclient INTERFACE libmad)
|
||||
target_include_directories(omohclient INTERFACE "../libmad-0.15.1b")
|
||||
target_link_libraries(omohclient INTERFACE libmad)
|
||||
@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include "client.h"
|
||||
#include "cl_ui.h"
|
||||
#include "cl_uiradar.h"
|
||||
#include "../qcommon/tiki.h"
|
||||
#include "../qcommon/localization.h"
|
||||
#include "../qcommon/bg_compat.h"
|
||||
@@ -540,6 +541,29 @@ void CL_StartLocalSound(const char* soundName, qboolean forceLoad) {
|
||||
S_StartLocalSound(soundName, qfalse );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_RestoreSavedCgameState
|
||||
====================
|
||||
*/
|
||||
void CL_RestoreSavedCgameState() {
|
||||
if (cls.savedCgameState) {
|
||||
cge->CG_LoadStateToBuffer(&cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_ClearSavedCgameState
|
||||
====================
|
||||
*/
|
||||
void CL_ClearSavedCgameState() {
|
||||
if (cls.savedCgameState) {
|
||||
cls.savedCgameState = NULL;
|
||||
cls.savedCgameStateSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_InitCGameDLL
|
||||
@@ -745,11 +769,14 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
|
||||
cgi->UI_SetScoreBoardItem = UI_SetScoreBoardItem;
|
||||
cgi->UI_DeleteScoreBoardItems = UI_DeleteScoreBoardItems;
|
||||
cgi->UI_ToggleDMMessageConsole = UI_ToggleDMConsole;
|
||||
cgi->CL_InitRadar = CL_InitRadar;
|
||||
|
||||
cgi->TIKI_FindTiki = TIKI_FindTiki;
|
||||
|
||||
cgi->LoadResource = UI_LoadResource;
|
||||
cgi->FS_CanonicalFilename = FS_CanonicalFilename;
|
||||
cgi->CL_RestoreSavedCgameState = CL_RestoreSavedCgameState;
|
||||
cgi->CL_ClearSavedCgameState = CL_ClearSavedCgameState;
|
||||
|
||||
cgi->fsDebug = fs_debug;
|
||||
cgi->HudDrawElements = cls.HudDrawElements;
|
||||
@@ -904,8 +931,6 @@ qboolean CL_GameCommand( void ) {
|
||||
return cge->CG_ConsoleCommand();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_CGameRendering
|
||||
@@ -920,6 +945,10 @@ void CL_CGameRendering( stereoFrame_t stereo ) {
|
||||
cge->CG_DrawActiveFrame( cl.serverTime, cl.serverTime - cl.oldServerTime, stereo, clc.demoplaying );
|
||||
|
||||
cl.oldServerTime = cl.serverTime;
|
||||
//
|
||||
// Let cgame clean up temp models
|
||||
//
|
||||
cge->CG_CleanUpTempModels();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1095,16 +1124,14 @@ void CL_SetCGameTime( void ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
//if( ( cl.snap.snapFlags ^ lastSnapFlags ) & SNAPFLAG_SERVERCOUNT ) {
|
||||
// CL_ServerRestarted();
|
||||
//} else {
|
||||
|
||||
if( ( cl.snap.snapFlags ^ lastSnapFlags ) & SNAPFLAG_SERVERCOUNT ) {
|
||||
CL_ServerRestarted();
|
||||
} else {
|
||||
if( cl.snap.serverTime < cl.oldFrameServerTime ) {
|
||||
assert( 0 );
|
||||
Com_Error( ERR_DROP, "cl.snap.serverTime < cl.oldFrameServerTime" );
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
cl.oldFrameServerTime = cl.snap.serverTime;
|
||||
|
||||
|
||||
@@ -1051,8 +1051,8 @@ void CL_InitInput( void ) {
|
||||
Cmd_AddCommand("-leanleft", IN_LeanLeftUp);
|
||||
Cmd_AddCommand("+leanright", IN_LeanRightDown);
|
||||
Cmd_AddCommand("-leanright", IN_LeanRightUp);
|
||||
Cmd_AddCommand("+speed", IN_SpeedUp);
|
||||
Cmd_AddCommand("-speed", IN_SpeedDown);
|
||||
Cmd_AddCommand("+speed", IN_SpeedDown);
|
||||
Cmd_AddCommand("-speed", IN_SpeedUp);
|
||||
Cmd_AddCommand("+button0", IN_Button0Down);
|
||||
Cmd_AddCommand("-button0", IN_Button0Up);
|
||||
Cmd_AddCommand("+button1", IN_Button1Down);
|
||||
|
||||
@@ -1153,7 +1153,7 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_guimouse || key <= K_MOUSE3 || key > K_JOY1)
|
||||
if (!in_guimouse || key <= K_MWHEELUP || key > K_JOY1)
|
||||
{
|
||||
// keys can still be used for bound actions
|
||||
if (down && (key <= K_BACKSPACE || key == K_MOUSE4) &&
|
||||
|
||||
+15
-1
@@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "cl_ui.h"
|
||||
#include "../qcommon/tiki.h"
|
||||
#include "../qcommon/cm_terrain.h"
|
||||
#include "../qcommon/localization.h"
|
||||
#include "../sys/sys_local.h"
|
||||
#ifdef USE_RENDERER_DLL
|
||||
#include "../sys/sys_loadlib.h"
|
||||
@@ -102,6 +103,9 @@ cvar_t *cl_inGameVideo;
|
||||
cvar_t *cl_serverStatusResendTime;
|
||||
cvar_t *cl_trn;
|
||||
cvar_t *cl_langamerefreshstatus;
|
||||
cvar_t *cl_radar_icon_size;
|
||||
cvar_t *cl_radar_speak_time;
|
||||
cvar_t *cl_radar_blink_time;
|
||||
|
||||
cvar_t *cl_lanForcePackets;
|
||||
|
||||
@@ -816,6 +820,11 @@ void CL_MapLoading( qboolean flush, const char *pszMapName ) {
|
||||
UI_ClearState();
|
||||
UI_ForceMenuOff(false);
|
||||
|
||||
if (!flush) {
|
||||
// Don't do anything if it's not flushingb
|
||||
return;
|
||||
}
|
||||
|
||||
if (pszMapName) {
|
||||
// if we are already connected to the local host, stay connected
|
||||
if (clc.state >= CA_CONNECTED && !Q_stricmp(cls.servername, "localhost")) {
|
||||
@@ -1398,7 +1407,8 @@ void CL_Rcon_f( void ) {
|
||||
message[1] = -1;
|
||||
message[2] = -1;
|
||||
message[3] = -1;
|
||||
message[4] = 0;
|
||||
message[4] = 2; // direction
|
||||
message[5] = 0;
|
||||
|
||||
Q_strcat (message, MAX_RCON_MESSAGE, "rcon ");
|
||||
|
||||
@@ -2796,6 +2806,7 @@ void CL_InitRef( void ) {
|
||||
ri.Printf = CL_RefPrintf;
|
||||
ri.Error = Com_Error;
|
||||
ri.Milliseconds = CL_ScaledMilliseconds;
|
||||
ri.LV_ConvertString = Sys_LV_CL_ConvertString;
|
||||
ri.Malloc = CL_RefMalloc;
|
||||
ri.Free = Z_Free;
|
||||
ri.Clear = CL_RefClear;
|
||||
@@ -3239,6 +3250,9 @@ void CL_Init( void ) {
|
||||
cl_motdString = Cvar_Get( "cl_motdString", "", CVAR_ROM );
|
||||
|
||||
cl_langamerefreshstatus = Cvar_Get( "cl_langamerefreshstatus", "Ready", 0 );
|
||||
cl_radar_icon_size = Cvar_Get("cl_radar_icon_size", "10", CVAR_ARCHIVE);
|
||||
cl_radar_speak_time = Cvar_Get("cl_radar_speak_time", "3", CVAR_ARCHIVE);
|
||||
cl_radar_blink_time = Cvar_Get("cl_radar_blink_time", "0.333", CVAR_ARCHIVE);
|
||||
cg_gametype = Cvar_Get( "cg_gametype", "0", 0 );
|
||||
|
||||
cl_lanForcePackets = Cvar_Get ("cl_lanForcePackets", "1", CVAR_ARCHIVE);
|
||||
|
||||
@@ -194,6 +194,69 @@ void CL_ParsePacketEntities( msg_t *msg, clSnapshot_t *oldframe, clSnapshot_t *n
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_UnpackNonPVSClient
|
||||
|
||||
Unpack info about non-visible client.
|
||||
================
|
||||
*/
|
||||
qboolean CL_UnpackNonPVSClient(int* packed, radarUnpacked_t* unpacked) {
|
||||
int x, y;
|
||||
int yaw;
|
||||
qboolean bValid;
|
||||
float range;
|
||||
|
||||
unpacked->clientNum = *packed & (MAX_CLIENTS - 1);
|
||||
if (unpacked->clientNum == cl.snap.ps.clientNum) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
x = ((*packed >> 6) & 0x7F) - (MAX_CLIENTS - 1);
|
||||
y = ((*packed >> 13) & 0x7F) - (MAX_CLIENTS - 1);
|
||||
yaw = (*packed >> 20) & 0x1F;
|
||||
bValid = (*packed >> 25) & 1;
|
||||
|
||||
if (com_radar_range && com_radar_range->value) {
|
||||
range = com_radar_range->value;
|
||||
} else {
|
||||
range = 0;
|
||||
}
|
||||
|
||||
unpacked->x = x * range / 63.f;
|
||||
unpacked->y = y * range / 63.f;
|
||||
|
||||
if (!bValid)
|
||||
{
|
||||
unpacked->x = x * range / 63.f * 1024;
|
||||
unpacked->y = y * range / 63.f * 1024;
|
||||
}
|
||||
|
||||
unpacked->yaw = yaw * 11.25f;
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ReadNonPVSClient
|
||||
|
||||
Reads packed info about non-visible client.
|
||||
================
|
||||
*/
|
||||
void CL_ReadNonPVSClient(int radarInfo) {
|
||||
radarUnpacked_t unpacked;
|
||||
|
||||
if (!cge) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CL_UnpackNonPVSClient(&radarInfo, &unpacked)) {
|
||||
unpacked.x += cl.snap.ps.origin[0];
|
||||
unpacked.y += cl.snap.ps.origin[1];
|
||||
cge->CG_ReadNonPVSClient(&unpacked);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
@@ -332,6 +395,9 @@ void CL_ParseSnapshot( msg_t *msg ) {
|
||||
}
|
||||
|
||||
cl.newSnapshots = qtrue;
|
||||
|
||||
// read radar info about invisible clients
|
||||
CL_ReadNonPVSClient(cl.snap.ps.radarInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3732,6 +3732,7 @@ CL_FillUIImports
|
||||
void CL_FillUIImports( void ) {
|
||||
uii.Rend_DrawBox = re.DrawBox;
|
||||
uii.Rend_DrawPicStretched = re.DrawStretchPic;
|
||||
uii.Rend_DrawPicStretched2 = re.DrawStretchPic2;
|
||||
uii.Rend_DrawPicTiled = re.DrawTilePic;
|
||||
uii.Rend_GetShaderHeight = re.GetShaderHeight;
|
||||
uii.Rend_GetShaderWidth = re.GetShaderWidth;
|
||||
@@ -5274,6 +5275,10 @@ void CL_InitializeUI( void ) {
|
||||
UI_LoadInventory_f();
|
||||
UI_CreateScoreboard();
|
||||
|
||||
// New since mohta
|
||||
// Version number
|
||||
Cvar_Set("game_version", va("v%s", com_target_version->string));
|
||||
|
||||
// Add all commands
|
||||
Cmd_AddCommand( "pushmenu", UI_PushMenu_f );
|
||||
Cmd_AddCommand( "pushmenu_sp", UI_PushMenuSP_f );
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef struct {
|
||||
//
|
||||
extern cvar_t* ui_health_start;
|
||||
extern cvar_t* ui_health_end;
|
||||
extern cvar_t* sound_overlay;
|
||||
|
||||
//
|
||||
// initialization
|
||||
@@ -66,6 +67,7 @@ void UI_ForceMenuOff( bool force );
|
||||
void UI_PushMenu( const char *name );
|
||||
void UI_ForceMenu( const char *name );
|
||||
qboolean UI_BindActive( void );
|
||||
void UI_SetReturnMenuToCurrent(void);
|
||||
void UI_ActivateView3D( void );
|
||||
void UI_MenuEscape( const char *name );
|
||||
void UI_CreateScoreboard( void );
|
||||
|
||||
@@ -20,7 +20,22 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// cl_uiradar.cpp: draw teammates
|
||||
// since 2.0
|
||||
|
||||
#include "cl_uiradar.h"
|
||||
#include "client.h"
|
||||
|
||||
radarClient_t* g_radarClients;
|
||||
qhandle_t* g_radarShaders;
|
||||
int g_radarClientNum;
|
||||
|
||||
void CL_InitRadar(radarClient_t* radars, qhandle_t* shaders, int clientNum)
|
||||
{
|
||||
g_radarClients = radars;
|
||||
g_radarShaders = shaders;
|
||||
g_radarClientNum = clientNum;
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( UIWidget, UIRadar, NULL )
|
||||
{
|
||||
@@ -30,5 +45,123 @@ CLASS_DECLARATION( UIWidget, UIRadar, NULL )
|
||||
UIRadar::UIRadar()
|
||||
{
|
||||
m_fRadius = 32.f;
|
||||
g_radarClients = NULL;
|
||||
}
|
||||
|
||||
UIRadar::~UIRadar()
|
||||
{
|
||||
}
|
||||
|
||||
void UIRadar::Draw(void)
|
||||
{
|
||||
radarClient_t* radar;
|
||||
float inv;
|
||||
float iconSize;
|
||||
int blinkTime, speakTime;
|
||||
float origin[2], axis[2];
|
||||
float halfScale;
|
||||
int i;
|
||||
|
||||
if (!g_radarClients) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cl.snap.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_radarClientNum < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
cge->CG_UpdateRadar();
|
||||
|
||||
radar = &g_radarClients[g_radarClientNum];
|
||||
if (!radar->time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (com_radar_range && com_radar_range->value > 0) {
|
||||
inv = 1.f / com_radar_range->value;
|
||||
} else {
|
||||
inv = 0;
|
||||
}
|
||||
|
||||
if (cl_radar_icon_size->value > 0) {
|
||||
iconSize = cl_radar_icon_size->value;
|
||||
} else {
|
||||
iconSize = 0;
|
||||
}
|
||||
|
||||
axis[0] = radar->axis[0];
|
||||
axis[1] = radar->axis[1];
|
||||
origin[0] = radar->origin[0];
|
||||
origin[1] = radar->origin[1];
|
||||
blinkTime = cl_radar_blink_time->value * 1000;
|
||||
speakTime = cl_radar_speak_time->value * 1000;
|
||||
|
||||
if (blinkTime < 100) blinkTime = 100;
|
||||
|
||||
halfScale = iconSize * 0.5f;
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
float delta[2];
|
||||
float newOrg[2];
|
||||
float screenOrg[2];
|
||||
float length;
|
||||
|
||||
radar = &g_radarClients[i];
|
||||
if (i == g_radarClientNum) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!g_radarClients[i].time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cl.snap.serverTime - radar->time >= 5000) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (radar->lastSpeakTime) {
|
||||
int delta = cl.snap.serverTime - radar->lastSpeakTime;
|
||||
// make the icon blink
|
||||
if (delta >= 0 && delta < speakTime && ((delta / blinkTime) % 2) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
radar->lastSpeakTime = 0;
|
||||
delta[0] = radar->origin[0] - origin[0];
|
||||
delta[1] = radar->origin[1] - origin[1];
|
||||
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv;
|
||||
newOrg[1] = (delta[0] * axis[1] + delta[1] * -axis[0]) * inv;
|
||||
length = VectorLength2D(newOrg);
|
||||
|
||||
if (length > 1)
|
||||
{
|
||||
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv * (1.f / length);
|
||||
newOrg[1] = (delta[0] * axis[1] + delta[1] * -axis[0]) * inv * (1.f / length);
|
||||
}
|
||||
|
||||
screenOrg[0] = -((halfScale * (1.141f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width));
|
||||
screenOrg[1] = -((halfScale * (1.141f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height));
|
||||
|
||||
uii.Rend_DrawPicStretched2(
|
||||
screenOrg[0],
|
||||
screenOrg[1],
|
||||
m_vVirtualScale[0] * iconSize,
|
||||
m_vVirtualScale[1] * iconSize,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
radar->axis[0] * axis[0] - (-radar->axis[1] * axis[1]),
|
||||
radar->axis[0] * axis[1] + (-radar->axis[1] * axis[0]),
|
||||
g_radarShaders[radar->teamShader]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "../uilib/uiwidget.h"
|
||||
#include "../cgame/cg_public.h"
|
||||
|
||||
class UIRadar : public UIWidget {
|
||||
public:
|
||||
@@ -28,7 +29,12 @@ public:
|
||||
|
||||
public:
|
||||
UIRadar();
|
||||
~UIRadar();
|
||||
|
||||
void Draw(void) override;
|
||||
|
||||
private:
|
||||
float m_fRadius;
|
||||
};
|
||||
|
||||
void CL_InitRadar(radarClient_t* radars, qhandle_t* shaders, int clientNum);
|
||||
+1110
-16
File diff suppressed because it is too large.
Load diff
@@ -20,20 +20,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __CL_UISERVERLIST_H__
|
||||
#define __CL_UISERVERLIST_H__
|
||||
#pragma once
|
||||
|
||||
class UIFAKKServerList : public UIListCtrl {
|
||||
protected:
|
||||
// need a new struct instead of gamespy
|
||||
void *m_serverList;
|
||||
struct GServerListImplementation *m_serverList[2];
|
||||
bool m_bHasList;
|
||||
bool m_bLANListing;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( UIFAKKServerList );
|
||||
|
||||
bool m_bGettingList;
|
||||
bool m_bGettingList[2];
|
||||
bool m_bUpdatingList;
|
||||
|
||||
protected:
|
||||
@@ -54,5 +53,3 @@ public:
|
||||
void Draw( void ) override;
|
||||
void SortByColumn( int column ) override;
|
||||
};
|
||||
|
||||
#endif /* __CL_UISERVERLIST_H__ */
|
||||
+82
-13
@@ -30,6 +30,15 @@ CLASS_DECLARATION( UIWidget, View3D, NULL )
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#define MAX_SUBTITLES 4
|
||||
|
||||
cvar_t* subs[MAX_SUBTITLES];
|
||||
cvar_t* teams[MAX_SUBTITLES];
|
||||
float fadeTime[MAX_SUBTITLES];
|
||||
float subLife[MAX_SUBTITLES];
|
||||
float alpha[MAX_SUBTITLES];
|
||||
char oldStrings[MAX_SUBTITLES][2048];
|
||||
|
||||
View3D::View3D()
|
||||
{
|
||||
// set as transparent
|
||||
@@ -66,7 +75,22 @@ void View3D::DrawLetterbox
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
float frac;
|
||||
vec4_t col;
|
||||
|
||||
col[0] = col[1] = col[2] = 0;
|
||||
col[3] = 1;
|
||||
|
||||
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
|
||||
if (frac > 0.0) {
|
||||
m_letterbox_active = true;
|
||||
re.SetColor(col);
|
||||
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
re.DrawBox(0.0, m_screenframe.size.height - m_screenframe.size.height * frac, m_screenframe.size.width, m_screenframe.size.height);
|
||||
} else {
|
||||
m_letterbox_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::DrawFades
|
||||
@@ -75,7 +99,14 @@ void View3D::DrawFades
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
if (cl.snap.ps.blend[3] > 0) {
|
||||
re.SetColor(cl.snap.ps.blend);
|
||||
if (cl.snap.ps.stats[STAT_ADDFADE]) {
|
||||
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
} else {
|
||||
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::Draw2D
|
||||
@@ -200,7 +231,7 @@ void View3D::DrawProf
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
// Normal empty function
|
||||
}
|
||||
|
||||
void View3D::PrintSound
|
||||
@@ -215,7 +246,7 @@ void View3D::PrintSound
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::DrawSoundOverlay
|
||||
@@ -224,7 +255,13 @@ void View3D::DrawSoundOverlay
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
setFont("verdana-14");
|
||||
m_font->setColor(UWhite);
|
||||
|
||||
if (sound_overlay->integer) {
|
||||
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
|
||||
Cvar_Set("sound_overlay", "0");
|
||||
}
|
||||
}
|
||||
|
||||
void View3D::CenterPrint
|
||||
@@ -233,7 +270,7 @@ void View3D::CenterPrint
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::LocationPrint
|
||||
@@ -242,7 +279,7 @@ void View3D::LocationPrint
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::OnActivate
|
||||
@@ -287,7 +324,7 @@ void View3D::DrawSubtitleOverlay
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void View3D::ClearCenterPrint
|
||||
@@ -296,7 +333,7 @@ void View3D::ClearCenterPrint
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_printfadetime = 0.0;
|
||||
}
|
||||
|
||||
void View3D::UpdateCenterPrint
|
||||
@@ -306,7 +343,17 @@ void View3D::UpdateCenterPrint
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_printstring = s;
|
||||
|
||||
if (s[0] == '@') {
|
||||
m_print_mat = uWinMan.RegisterShader(s + 1);
|
||||
} else {
|
||||
m_print_mat = NULL;
|
||||
}
|
||||
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_locationprint = qfalse;
|
||||
}
|
||||
|
||||
void View3D::UpdateLocationPrint
|
||||
@@ -318,7 +365,12 @@ void View3D::UpdateLocationPrint
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
m_printstring = s;
|
||||
m_printalpha = alpha;
|
||||
m_printfadetime = 4000.0;
|
||||
m_x_coord = x;
|
||||
m_y_coord = y;
|
||||
m_locationprint = qtrue;
|
||||
}
|
||||
|
||||
qboolean View3D::LetterboxActive
|
||||
@@ -330,13 +382,30 @@ qboolean View3D::LetterboxActive
|
||||
return m_letterbox_active;
|
||||
}
|
||||
|
||||
float avWidth = 0.0;
|
||||
|
||||
void View3D::InitSubtitle
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
float totalWidth;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
|
||||
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
|
||||
strcpy(oldStrings[i], subs[i]->string);
|
||||
fadeTime[i] = 4000.0;
|
||||
subLife[i] = 4000.0;
|
||||
}
|
||||
|
||||
totalWidth = 0.0;
|
||||
for (char j = 'A'; j <= 'Z'; j++) {
|
||||
totalWidth += m_font->getCharWidth(j);
|
||||
}
|
||||
|
||||
avWidth = totalWidth / 26.0;
|
||||
}
|
||||
|
||||
void View3D::FrameInitialized
|
||||
@@ -370,6 +439,6 @@ void ConsoleView::Draw
|
||||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
@@ -437,6 +437,9 @@ extern cvar_t *cl_inGameVideo;
|
||||
|
||||
extern cvar_t *cl_lanForcePackets;
|
||||
extern cvar_t *cl_langamerefreshstatus;
|
||||
extern cvar_t *cl_radar_icon_size;
|
||||
extern cvar_t *cl_radar_speak_time;
|
||||
extern cvar_t *cl_radar_blink_time;
|
||||
extern cvar_t *cl_autoRecordDemo;
|
||||
|
||||
extern cvar_t *cl_r_fullscreen;
|
||||
@@ -570,6 +573,7 @@ void CL_FavoriteServers_f( void );
|
||||
void CL_Ping_f( void );
|
||||
void CL_SaveShot_f( void );
|
||||
void CL_Dialog_f( void );
|
||||
void CL_ServerRestarted( void );
|
||||
qboolean CL_UpdateVisiblePings_f( int source );
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int iFlags;
|
||||
char szName[64];
|
||||
} soundSfx_t;
|
||||
|
||||
typedef struct {
|
||||
qboolean bPlaying;
|
||||
int iStatus;
|
||||
soundSfx_t sfx;
|
||||
int iEntNum;
|
||||
int iEntChannel;
|
||||
float vOrigin[3];
|
||||
float fVolume;
|
||||
int iBaseRate;
|
||||
float fNewPitchMult;
|
||||
float fMinDist;
|
||||
float fMaxDist;
|
||||
int iStartTime;
|
||||
int iTime;
|
||||
int iNextCheckObstructionTime;
|
||||
int iEndTime;
|
||||
int iFlags;
|
||||
int iOffset;
|
||||
int iLoopCount;
|
||||
} channelbasesavegame_t;
|
||||
|
||||
typedef struct {
|
||||
channelbasesavegame_t Channels[MAX_CHANNELS];
|
||||
} soundsystemsavegame_t;
|
||||
|
||||
void S_ChannelFree_Callback(channel_t* v);
|
||||
void S_LoadData(soundsystemsavegame_t* pSave);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../snd_local.h"
|
||||
|
||||
void S_Init2()
|
||||
@@ -90,11 +112,16 @@ void S_StopSound(int entnum, int channel)
|
||||
S_IsSoundPlaying
|
||||
=================
|
||||
*/
|
||||
int S_IsSoundPlaying(int channelNumber, const char* name)
|
||||
qboolean S_IsSoundPlaying(int channelNumber, const char* name)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
STUB();
|
||||
return 0;
|
||||
channel_t* v;
|
||||
if (channelNumber >= MAX_CHANNELS) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
v = &s_channels[channelNumber];
|
||||
|
||||
return v->thesfx ? qtrue : qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -379,4 +406,20 @@ void S_FadeSound(float fTime)
|
||||
|
||||
void S_TriggeredMusic_PlayIntroMusic() {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
}
|
||||
|
||||
void callbackServer(int entnum, int channel_number, const char* name) {
|
||||
if (com_sv_running->integer) {
|
||||
SV_SoundCallback(entnum, channel_number, name);
|
||||
}
|
||||
}
|
||||
|
||||
void S_ChannelFree_Callback(channel_t* v) {
|
||||
if (v->entnum & S_FLAG_DO_CALLBACK) {
|
||||
callbackServer(v->entnum & ~S_FLAG_DO_CALLBACK, v - s_channels, v->thesfx->soundName);
|
||||
}
|
||||
}
|
||||
|
||||
void S_LoadData(soundsystemsavegame_t* pSave) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -46,7 +68,7 @@ void S_StopSound(int entnum, int channel);
|
||||
float S_GetSoundTime(sfxHandle_t handle);
|
||||
void S_SetGlobalAmbientVolumeLevel(float volume);
|
||||
void S_SetReverb(int reverb_type, float reverb_level);
|
||||
int S_IsSoundPlaying(int channelNumber, const char* name);
|
||||
qboolean S_IsSoundPlaying(int channelNumber, const char* name);
|
||||
|
||||
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t velocity, qboolean use_listener);
|
||||
void S_FadeSound(float fTime);
|
||||
|
||||
@@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "snd_codec.h"
|
||||
|
||||
// includes for the MP3 codec
|
||||
#include <mad.h>
|
||||
#include "../libmad-0.15.1b/synth.h"
|
||||
|
||||
#define MP3_SAMPLE_WIDTH 2
|
||||
#define MP3_PCMSAMPLES_PERSLICE 32
|
||||
|
||||
@@ -181,6 +181,7 @@ void S_Base_SoundList( void ) {
|
||||
|
||||
|
||||
void S_ChannelFree(channel_t *v) {
|
||||
S_ChannelFree_Callback(v);
|
||||
v->thesfx = NULL;
|
||||
*(channel_t **)v = freelist;
|
||||
freelist = (channel_t*)v;
|
||||
|
||||
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// snd_local.h -- private sound definations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
@@ -275,6 +276,8 @@ qboolean S_AL_Init( soundInterface_t *si );
|
||||
void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE], int snd_vol, channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset );
|
||||
#endif
|
||||
|
||||
#include "new/snd_local_new.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -16,7 +16,14 @@ set(SOURCES_SHARED
|
||||
"../qcommon/str.cpp"
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SOURCES_GAME "./*.c*" "../parser/*.c*" "../script/*.c*")
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
SOURCES_GAME
|
||||
"./*.c*"
|
||||
"../script/*.c*"
|
||||
"../parser/generated/*.c*"
|
||||
"../parser/parsetree.cpp"
|
||||
)
|
||||
|
||||
add_library(fgame SHARED ${SOURCES_GAME})
|
||||
|
||||
@@ -44,13 +51,13 @@ target_compile_features(fgame PUBLIC c_variadic_macros)
|
||||
target_link_libraries(fgame PUBLIC qcommon)
|
||||
|
||||
set_target_properties(fgame PROPERTIES PREFIX "${TARGET_PLATFORM_PREFIX}")
|
||||
set_target_properties(fgame PROPERTIES OUTPUT_NAME "game${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
|
||||
set_target_properties(fgame PROPERTIES OUTPUT_NAME "game${TARGET_ARCH_SUFFIX}")
|
||||
set_target_properties(fgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
|
||||
|
||||
INSTALL(
|
||||
TARGETS fgame
|
||||
DESTINATION "${TARGET_BASE_GAME}"
|
||||
ARCHIVE EXCLUDE_FROM_ALL
|
||||
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
|
||||
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "DrivableVehicleTandem.h"
|
||||
|
||||
// FIXME: unimplemented
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,460 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "entity.h"
|
||||
#include "animate.h"
|
||||
|
||||
typedef enum {
|
||||
CONTROLLER_ALLIES,
|
||||
CONTROLLER_AXIS,
|
||||
CONTROLLER_DRAW
|
||||
} eController;
|
||||
|
||||
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
|
||||
#define PT_SPAWNFLAG_TARGET_RANDOM 4
|
||||
#define PT_SPAWNFLAG_TURN_ON 8
|
||||
#define PT_SPAWNFLAG_SET_YAW 16
|
||||
#define PT_SPAWNFLAG_SET_ROLL 32
|
||||
#define PT_SPAWNFLAG_TARGET_PLAYER 64
|
||||
#define PT_SPAWNFLAG_HIDDEN 128
|
||||
|
||||
void ClearProjectileTargets();
|
||||
|
||||
class ProjectileTarget : public Entity
|
||||
{
|
||||
private:
|
||||
int m_iTarget;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileTarget);
|
||||
|
||||
ProjectileTarget();
|
||||
|
||||
void EventSetId(Event *ev);
|
||||
int GetTarget() const;
|
||||
};
|
||||
|
||||
#define MAX_PROJECTILE_GENERATOR_TARGETS 16
|
||||
|
||||
class ProjectileGenerator : public Animate
|
||||
{
|
||||
protected:
|
||||
int m_iId;
|
||||
int m_iCycles;
|
||||
float m_fMinDuration;
|
||||
float m_fMaxDuration;
|
||||
int m_iMinNumShots;
|
||||
int m_iMaxNumShots;
|
||||
float m_fMinDelay;
|
||||
float m_fMaxDelay;
|
||||
float m_fAccuracy;
|
||||
str m_sLaunchSound;
|
||||
bool m_bFireOnStartUp;
|
||||
qboolean m_bIsDonut;
|
||||
float m_fArcDonut;
|
||||
float m_fMinDonut;
|
||||
float m_fMaxDonut;
|
||||
float m_fCycleTime;
|
||||
float m_fShotsPerSec;
|
||||
float m_fCurrentTime;
|
||||
int m_iTargetIndex;
|
||||
float m_fLastShotTime;
|
||||
int m_iAnimSlot;
|
||||
bool m_bIsTurnedOn;
|
||||
int m_iCurrentCycle;
|
||||
Entity *m_pTarget;
|
||||
Container<ProjectileTarget *> m_projectileTargets;
|
||||
Entity *m_pCurrent;
|
||||
Vector m_vTargetOrg;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileGenerator);
|
||||
|
||||
ProjectileGenerator();
|
||||
|
||||
virtual void SetupNextCycle();
|
||||
virtual void BeginCycle(Event *ev);
|
||||
virtual void TickCycle(Event *ev);
|
||||
virtual void EndCycle(Event *ev);
|
||||
|
||||
bool ShouldStartOn() const;
|
||||
bool ShouldHideModel() const;
|
||||
bool ShouldPlayFireSound() const;
|
||||
|
||||
void EventIsTurnedOn(Event *ev);
|
||||
void EventGetTargetEntity(Event *ev);
|
||||
void EventLaunchSound(Event *ev);
|
||||
void SetTarget(Event *ev);
|
||||
void OnInitialize(Event *ev);
|
||||
void TurnOff(Event *ev);
|
||||
void TurnOn(Event *ev);
|
||||
bool ShouldTargetRandom() const;
|
||||
void ChooseTarget();
|
||||
|
||||
void GetLocalTargets();
|
||||
bool ShouldTargetPlayer() const;
|
||||
void GetTargetPos(Entity *target);
|
||||
void EventAccuracy(Event *ev);
|
||||
void EventMaxDelay(Event *ev);
|
||||
void EventMinDelay(Event *ev);
|
||||
void EventFireOnStartUp(Event *ev);
|
||||
void EventMaxNumShots(Event *ev);
|
||||
void EventMinNumShots(Event *ev);
|
||||
void EventCycles(Event *ev);
|
||||
void EventMaxDuration(Event *ev);
|
||||
void EventMinDuration(Event *ev);
|
||||
void SetWeaponModel(Event *ev);
|
||||
void EventSetId(Event* ev);
|
||||
void EventmaxDonut(Event* ev);
|
||||
void EventminDonut(Event* ev);
|
||||
void EventarcDonut(Event* ev);
|
||||
void EventisDonut(Event* ev);
|
||||
virtual bool Attack(int count);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ProjectileGenerator_Projectile : public ProjectileGenerator
|
||||
{
|
||||
private:
|
||||
str m_sProjectileModel;
|
||||
str m_sPreImpactSound;
|
||||
float m_fImpactSoundTime;
|
||||
float m_fImpactSoundProbability;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileGenerator_Projectile);
|
||||
|
||||
ProjectileGenerator_Projectile();
|
||||
|
||||
void SetPreImpactSoundProbability(Event *ev);
|
||||
void SetPreImpactSoundTime(Event *ev);
|
||||
void SetPreImpactSound(Event *ev);
|
||||
void PlayPreImpactSound(Event *ev);
|
||||
void SetProjectileModel(Event *ev);
|
||||
|
||||
bool Attack(int count) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ProjectileGenerator_Gun : public ProjectileGenerator
|
||||
{
|
||||
private:
|
||||
float m_fBulletRange;
|
||||
float m_fBulletDamage;
|
||||
int m_iBulletCount;
|
||||
Vector m_vBulletSpread;
|
||||
int m_iTracerFrequency;
|
||||
int m_iBulletLarge;
|
||||
qboolean m_bFakeBullets;
|
||||
int m_iMeansOfDeath;
|
||||
float m_fBulletThroughWood;
|
||||
float m_fBulletThroughMetal;
|
||||
float m_iBulletKnockback;
|
||||
int m_iAttackCount;
|
||||
float m_fFireDelay;
|
||||
float m_fTracerSpeed;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileGenerator_Gun);
|
||||
|
||||
ProjectileGenerator_Gun();
|
||||
|
||||
void SetFireDelay(Event *ev);
|
||||
void SetMeansOfDeath(Event *ev);
|
||||
void SetBulletThroughWood(Event *ev);
|
||||
void SetBulletThroughMetal(Event *ev);
|
||||
void SetBulletKnockback(Event *ev);
|
||||
void SetTracerSpeed(Event *ev);
|
||||
void SetBulletLarge(Event *ev);
|
||||
void SetFakeBullets(Event *ev);
|
||||
void SetBulletCount(Event *ev);
|
||||
void SetBulletDamage(Event *ev);
|
||||
void SetTracerFrequency(Event *ev);
|
||||
void SetBulletSpread(Event *ev);
|
||||
void SetBulletRange(Event *ev);
|
||||
|
||||
bool Attack(int count) override;
|
||||
void TickCycle(Event *ev) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ProjectileGenerator_Heavy : public ProjectileGenerator
|
||||
{
|
||||
private:
|
||||
str m_sProjectileModel;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ProjectileGenerator_Heavy);
|
||||
|
||||
ProjectileGenerator_Heavy();
|
||||
|
||||
void SetProjectileModel(Event *ev);
|
||||
|
||||
bool Attack(int count) override;
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ThrobbingBox_Explosive : public Animate
|
||||
{
|
||||
protected:
|
||||
str m_sUsedModel;
|
||||
str m_sSound;
|
||||
bool m_bUsed;
|
||||
float m_fExplosionDamage;
|
||||
float m_fRadius;
|
||||
float m_fStopwatchDuration;
|
||||
str m_sActivateSound;
|
||||
str m_sTickSound;
|
||||
str m_sDestroyedModel;
|
||||
ScriptThreadLabel m_thread;
|
||||
ScriptThreadLabel m_useThread;
|
||||
str m_sEffect;
|
||||
Vector m_vOffset;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_Explosive);
|
||||
|
||||
ThrobbingBox_Explosive();
|
||||
|
||||
void SetExplosionOffset(Event *ev);
|
||||
void SetExplosionEffect(Event *ev);
|
||||
void SetTriggered(Event *ev);
|
||||
void DoExplosion(Event *ev);
|
||||
void SetUseThread(Event *ev);
|
||||
void SetThread(Event *ev);
|
||||
void SetStopWatchDuration(Event *ev);
|
||||
void SetRadius(Event *ev);
|
||||
void SetDamage(Event *ev);
|
||||
void TickSound(Event *ev);
|
||||
void ActivateSound(Event *ev);
|
||||
void ExplosionSound(Event *ev);
|
||||
void UsedModel(Event *ev);
|
||||
void SetDestroyModel(Event *ev);
|
||||
void OnBlowUp(Event *ev);
|
||||
void OnUse(Event *ev);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodePlayerFlak88 : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodePlayerFlak88);
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodeFlak88 : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodeFlak88);
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodeNebelwerfer : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodeNebelwerfer);
|
||||
};
|
||||
|
||||
class ThrobbingBox_ExplodePlayerNebelwerfer : public ThrobbingBox_Explosive
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_ExplodePlayerNebelwerfer);
|
||||
};
|
||||
|
||||
#define TBE_SPAWNFLAG_DESTROYED_MODEL 1
|
||||
#define TBE_SPAWNFLAG_MAKE_WET 2
|
||||
|
||||
class ThrobbingBox_Stickybomb : public ThrobbingBox_Explosive
|
||||
{
|
||||
private:
|
||||
float m_fStopwatchStartTime;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(ThrobbingBox_Stickybomb);
|
||||
|
||||
void OnStickyBombWet(Event *ev);
|
||||
void OnStickyBombUse(Event *ev);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
#define OBJECTIVE_SPAWNFLAG_TURN_ON 1
|
||||
|
||||
class Objective : public Entity
|
||||
{
|
||||
private:
|
||||
str m_sText;
|
||||
int m_iObjectiveIndex;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(Objective);
|
||||
|
||||
Objective();
|
||||
|
||||
void Archive(Archiver &arc) override;
|
||||
void TurnOn(Event *ev);
|
||||
void TurnOff(Event *ev);
|
||||
void Complete(Event *ev);
|
||||
void SetCurrent(Event *ev);
|
||||
Vector GetOrigin() const;
|
||||
void SetObjectiveNbr(Event *ev);
|
||||
void SetText(Event *ev);
|
||||
int GetObjectiveIndex() const;
|
||||
};
|
||||
|
||||
class FencePost : public Entity
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(FencePost);
|
||||
};
|
||||
|
||||
class AISpawnPoint : public SimpleArchivedEntity
|
||||
{
|
||||
private:
|
||||
str m_sModel;
|
||||
int m_iHealth;
|
||||
str m_sEnemyName;
|
||||
float m_iAccuracy;
|
||||
int m_iAmmoGrenade;
|
||||
float m_iBalconyHeight;
|
||||
int m_iDisguiseLevel;
|
||||
float m_fDisguisePeriod;
|
||||
float m_fDisguiseRange;
|
||||
float m_fEnemyShareRange;
|
||||
float m_fFixedLeash;
|
||||
float m_fGrenadeAwareness;
|
||||
str m_sGun;
|
||||
float m_fMaxNoticeTimeScale;
|
||||
float m_fSoundAwareness;
|
||||
str m_sTypeAttack;
|
||||
str m_sTypeDisguise;
|
||||
str m_sTypeGrenade;
|
||||
str m_sTypeIdle;
|
||||
bool m_bPatrolWaitTrigger;
|
||||
float m_fHearing;
|
||||
float m_fSight;
|
||||
float m_fFov;
|
||||
float m_fLeash;
|
||||
float m_fMinDist;
|
||||
float m_fMaxDist;
|
||||
float m_fInterval;
|
||||
bool m_bDontDropWeapons;
|
||||
bool m_bDontDropHealth;
|
||||
str m_sFavoriteEnemy;
|
||||
bool m_bNoSurprise;
|
||||
str m_sPatrolPath;
|
||||
str m_sTurret;
|
||||
str m_sAlarmNode;
|
||||
str m_sWeapon;
|
||||
str m_sTarget;
|
||||
str m_sVoiceType;
|
||||
bool m_bForceDropWeapon;
|
||||
bool m_bForceDropHealth;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(AISpawnPoint);
|
||||
|
||||
AISpawnPoint();
|
||||
|
||||
void GetForceDropHealth(Event *ev);
|
||||
void SetForceDropHealth(Event *ev);
|
||||
void GetForceDropWeapon(Event *ev);
|
||||
void SetForceDropWeapon(Event *ev);
|
||||
void GetVoiceType(Event *ev);
|
||||
void SetVoiceType(Event *ev);
|
||||
void GetTarget(Event *ev);
|
||||
void SetTarget(Event *ev);
|
||||
void GetWeapon(Event *ev);
|
||||
void SetWeapon(Event *ev);
|
||||
void GetAlarmNode(Event *ev);
|
||||
void SetAlarmNode(Event *ev);
|
||||
void GetTurret(Event *ev);
|
||||
void SetTurret(Event *ev);
|
||||
void GetPatrolPath(Event *ev);
|
||||
void SetPatrolPath(Event *ev);
|
||||
void GetNoSurprise(Event *ev);
|
||||
void SetNoSurprise(Event *ev);
|
||||
void SetFavoriteEnemy(Event *ev);
|
||||
void GetFavoriteEnemy(Event *ev);
|
||||
void GetDontDropHealth(Event *ev);
|
||||
void SetDontDropHealth(Event *ev);
|
||||
void GetDontDropWeapons(Event *ev);
|
||||
void SetDontDropWeapons(Event *ev);
|
||||
void GetInterval(Event *ev);
|
||||
void SetInterval(Event *ev);
|
||||
void GetMaxDistance(Event *ev);
|
||||
void SetMaxDistance(Event *ev);
|
||||
void GetMinDistance(Event *ev);
|
||||
void SetMinDistance(Event *ev);
|
||||
void GetLeash(Event *ev);
|
||||
void SetLeash(Event *ev);
|
||||
void GetFov(Event *ev);
|
||||
void SetFov(Event *ev);
|
||||
void SetSight(Event *ev);
|
||||
void GetSight(Event *ev);
|
||||
void GetHearing(Event *ev);
|
||||
void SetHearing(Event *ev);
|
||||
void GetPatrolWaitTrigger(Event *ev);
|
||||
void SetPatrolWaitTrigger(Event *ev);
|
||||
void GetTypeIdle(Event *ev);
|
||||
void SetTypeIdle(Event *ev);
|
||||
void GetTypeGrenade(Event *ev);
|
||||
void SetTypeGrenade(Event *ev);
|
||||
void GetTypeDisguise(Event *ev);
|
||||
void SetTypeDisguise(Event *ev);
|
||||
void GetTypeAttack(Event *ev);
|
||||
void SetTypeAttack(Event *ev);
|
||||
void SetSoundAwareness(Event *ev);
|
||||
void GetSoundAwareness(Event *ev);
|
||||
void SetMaxNoticeTimeScale(Event *ev);
|
||||
void GetMaxNoticeTimeScale(Event *ev);
|
||||
void GetGun(Event *ev);
|
||||
void SetGun(Event *ev);
|
||||
void GetGrenadeAwareness(Event *ev);
|
||||
void SetGrenadeAwareness(Event *ev);
|
||||
void SetFixedLeash(Event *ev);
|
||||
void GetFixedLeash(Event *ev);
|
||||
void GetEnemyShareRange(Event *ev);
|
||||
void SetEnemyShareRange(Event *ev);
|
||||
void GetDisguiseRange(Event *ev);
|
||||
void SetDisguiseRange(Event *ev);
|
||||
void GetDisguisePeriod(Event *ev);
|
||||
void SetDisguisePeriod(Event *ev);
|
||||
void GetDisguiseLevel(Event *ev);
|
||||
void SetDisguiseLevel(Event *ev);
|
||||
void GetBalconyHeight(Event *ev);
|
||||
void SetBalconyHeight(Event *ev);
|
||||
void GetAmmoGrenade(Event *ev);
|
||||
void SetAmmoGrenade(Event *ev);
|
||||
void GetAccuracy(Event *ev);
|
||||
void SetAccuracy(Event *ev);
|
||||
void GetEnemyName(Event *ev);
|
||||
void SetEnemyName(Event *ev);
|
||||
void GetHealth(Event *ev);
|
||||
void SetHealth(Event *ev);
|
||||
void GetModel(Event *ev);
|
||||
void SetModel(Event *ev);
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "Tow_Entities.h"
|
||||
#include "player.h"
|
||||
#include "scriptthread.h"
|
||||
|
||||
TOWObjectiveMan g_TOWObjectiveMan;
|
||||
|
||||
TOWObjectiveMan::TOWObjectiveMan()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void TOWObjectiveMan::Reset()
|
||||
{
|
||||
m_towObjectives.ClearObjectList();
|
||||
m_iNumAxisObjectives = 0;
|
||||
m_iNumAlliesObjectives = 0;
|
||||
}
|
||||
|
||||
void TOWObjectiveMan::AddObjective(TOWObjective *objective)
|
||||
{
|
||||
if (!objective) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (objective->GetController()) {
|
||||
case CONTROLLER_ALLIES:
|
||||
m_iNumAlliesObjectives++;
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
m_iNumAxisObjectives++;
|
||||
break;
|
||||
}
|
||||
|
||||
m_towObjectives.AddObject(objective);
|
||||
}
|
||||
|
||||
void TOWObjectiveMan::TakeOverObjective(eController controller, eController controllingTeam)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (controllingTeam == CONTROLLER_DRAW) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (controllingTeam) {
|
||||
case CONTROLLER_ALLIES:
|
||||
m_iNumAlliesObjectives++;
|
||||
if (m_iNumAxisObjectives) {
|
||||
m_iNumAxisObjectives--;
|
||||
}
|
||||
dmManager.CheckEndMatch();
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
m_iNumAxisObjectives++;
|
||||
if (m_iNumAlliesObjectives) {
|
||||
m_iNumAlliesObjectives--;
|
||||
}
|
||||
dmManager.CheckEndMatch();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < game.maxclients; i++) {
|
||||
gentity_t *ent = &g_entities[i];
|
||||
Player *player;
|
||||
bool bSameTeam;
|
||||
|
||||
if (!ent->inuse || !ent->entity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
player = static_cast<Player *>(ent->entity);
|
||||
|
||||
switch (controllingTeam) {
|
||||
case CONTROLLER_ALLIES:
|
||||
bSameTeam = player->GetTeam() == TEAM_ALLIES;
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
bSameTeam = player->GetTeam() == TEAM_AXIS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// play a different sound for the losing team
|
||||
if (bSameTeam) {
|
||||
player->PlayInstantMessageSound("success");
|
||||
} else {
|
||||
player->PlayInstantMessageSound("failure");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Event EV_SetController("ControlledBy", EV_DEFAULT, "i", "ControlledBy", "Sets the team controlling the objective");
|
||||
Event EV_TakeOver(
|
||||
"TakeOver", EV_DEFAULT, "i", "TeamNum", "Sets the team controlling the objective. 0 = Axis, 1 = Allies"
|
||||
);
|
||||
Event EV_SetAxisObjNum("AxisObjNum", EV_DEFAULT, "i", "AxisObjNum", "Sets the objective number for the axis team");
|
||||
Event EV_SetAlliesObjNum(
|
||||
"AlliesObjNum", EV_DEFAULT, "i", "AlliesObjNum", "Sets the objective number for the allies team"
|
||||
);
|
||||
static Event EV_Initialize("initialize", EV_DEFAULT, 0, 0, "Initialize object");
|
||||
static Event EV_SetCurrent(
|
||||
"SetCurrent", EV_DEFAULT, "i", "TeamNum", "Set this objective as the current objective for the specified team."
|
||||
);
|
||||
Event EV_GetController("ControlledBy", EV_DEFAULT, 0, 0, "Objective controller", EV_GETTER);
|
||||
|
||||
CLASS_DECLARATION(Objective, TOWObjective, "func_towobjective") {
|
||||
{&EV_SetController, &TOWObjective::SetController },
|
||||
{&EV_TakeOver, &TOWObjective::TakeOver },
|
||||
{&EV_SetAxisObjNum, &TOWObjective::SetAxisObjNum },
|
||||
{&EV_SetAlliesObjNum, &TOWObjective::SetAlliesObjNum},
|
||||
{&EV_Initialize, &TOWObjective::OnInitialize },
|
||||
{&EV_SetCurrent, &TOWObjective::SetCurrent },
|
||||
{&EV_GetController, &TOWObjective::GetController },
|
||||
{NULL, NULL }
|
||||
};
|
||||
|
||||
TOWObjective::TOWObjective()
|
||||
{
|
||||
m_eController = CONTROLLER_DRAW;
|
||||
m_eLeadingController = CONTROLLER_DRAW;
|
||||
m_bNoRespawnForLeading = false;
|
||||
m_iAxisObjNum = 1;
|
||||
m_iAlliesObjNum = 1;
|
||||
m_sAxisObjName = "default";
|
||||
m_sAlliesObjName = "default";
|
||||
|
||||
if (spawnflags & TOWOBJECTIVE_SPAWNFLAG_NO_RESPAWN) {
|
||||
m_bNoRespawnForLeading = true;
|
||||
}
|
||||
|
||||
PostEvent(EV_Initialize, 0.001f);
|
||||
}
|
||||
|
||||
void TOWObjective::SetController(Event *ev)
|
||||
{
|
||||
m_eController = static_cast<eController>(ev->GetInteger(1));
|
||||
|
||||
if (m_bNoRespawnForLeading) {
|
||||
m_eLeadingController = m_eController;
|
||||
}
|
||||
|
||||
if (m_eController != CONTROLLER_ALLIES && m_eController != CONTROLLER_AXIS) {
|
||||
m_eController = CONTROLLER_DRAW;
|
||||
}
|
||||
}
|
||||
|
||||
void TOWObjective::GetController(Event *ev)
|
||||
{
|
||||
ev->AddInteger(m_eController);
|
||||
}
|
||||
|
||||
void TOWObjective::TakeOver(Event *ev)
|
||||
{
|
||||
eController controller = static_cast<eController>(ev->GetInteger(1));
|
||||
if (controller == m_eController || controller == CONTROLLER_DRAW) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (controller) {
|
||||
case CONTROLLER_ALLIES:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "1");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "0");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "1");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_TOWObjectiveMan.TakeOverObjective(m_eController, controller);
|
||||
|
||||
if (m_bNoRespawnForLeading) {
|
||||
//
|
||||
// Disable team respawn for the leading team
|
||||
//
|
||||
dmManager.StopTeamRespawn(m_eLeadingController);
|
||||
}
|
||||
}
|
||||
|
||||
void TOWObjective::SetAlliesObjNum(Event *ev)
|
||||
{
|
||||
m_iAlliesObjNum = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void TOWObjective::SetAxisObjNum(Event *ev)
|
||||
{
|
||||
m_iAxisObjNum = ev->GetInteger(1);
|
||||
}
|
||||
|
||||
void TOWObjective::OnInitialize(Event *ev)
|
||||
{
|
||||
m_sAlliesObjName = "tow_allied_obj" + str(m_iAlliesObjNum);
|
||||
m_sAxisObjName = "tow_allied_obj" + str(m_iAxisObjNum);
|
||||
|
||||
switch (m_eController) {
|
||||
case CONTROLLER_ALLIES:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "1");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "0");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "1");
|
||||
break;
|
||||
case CONTROLLER_DRAW:
|
||||
gi.cvar_set(m_sAxisObjName.c_str(), "0");
|
||||
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!LoadingSavegame) {
|
||||
g_TOWObjectiveMan.AddObjective(this);
|
||||
}
|
||||
}
|
||||
|
||||
void TOWObjective::SetCurrent(Event *ev)
|
||||
{
|
||||
eController controller = static_cast<eController>(ev->GetInteger(1));
|
||||
switch (controller) {
|
||||
case CONTROLLER_ALLIES:
|
||||
ScriptThread::SetCurrentObjective(GetObjectiveIndex(), TEAM_ALLIES);
|
||||
break;
|
||||
case CONTROLLER_AXIS:
|
||||
ScriptThread::SetCurrentObjective(GetObjectiveIndex(), TEAM_AXIS);
|
||||
break;
|
||||
default:
|
||||
SetCurrent(ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int TOWObjective::GetController() const
|
||||
{
|
||||
return m_eController;
|
||||
}
|
||||
|
||||
void TOWObjective::Archive(Archiver& arc)
|
||||
{
|
||||
arc.ArchiveInteger(&m_iAxisObjNum);
|
||||
arc.ArchiveInteger(&m_iAlliesObjNum);
|
||||
ArchiveEnum(m_eController, eController);
|
||||
ArchiveEnum(m_eLeadingController, eController);
|
||||
arc.ArchiveBool(&m_bNoRespawnForLeading);
|
||||
arc.ArchiveString(&m_sAxisObjName);
|
||||
arc.ArchiveString(&m_sAlliesObjName);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Entities.h"
|
||||
|
||||
#define TOWOBJECTIVE_SPAWNFLAG_NO_RESPAWN 2
|
||||
|
||||
class TOWObjective : public Objective
|
||||
{
|
||||
private:
|
||||
int m_iAxisObjNum;
|
||||
int m_iAlliesObjNum;
|
||||
eController m_eController;
|
||||
eController m_eLeadingController;
|
||||
bool m_bNoRespawnForLeading;
|
||||
str m_sAxisObjName;
|
||||
str m_sAlliesObjName;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(TOWObjective);
|
||||
|
||||
TOWObjective();
|
||||
|
||||
void SetController(Event *ev);
|
||||
void GetController(Event *ev);
|
||||
void TakeOver(Event *ev);
|
||||
void SetAlliesObjNum(Event *ev);
|
||||
void SetAxisObjNum(Event *ev);
|
||||
void OnInitialize(Event *ev);
|
||||
void SetCurrent(Event *ev);
|
||||
|
||||
int GetController() const;
|
||||
|
||||
void Archive(Archiver& arc) override;
|
||||
};
|
||||
|
||||
class TOWObjectiveMan
|
||||
{
|
||||
private:
|
||||
Container<TOWObjective *> m_towObjectives;
|
||||
int m_iNumAxisObjectives;
|
||||
int m_iNumAlliesObjectives;
|
||||
|
||||
public:
|
||||
TOWObjectiveMan();
|
||||
|
||||
void Reset();
|
||||
void AddObjective(TOWObjective *objective);
|
||||
void TakeOverObjective(eController controller, eController controllingTeam);
|
||||
};
|
||||
|
||||
extern TOWObjectiveMan g_TOWObjectiveMan;
|
||||
+12
-21
@@ -2573,7 +2573,7 @@ Actor::Actor()
|
||||
setMoveType( MOVETYPE_WALK );
|
||||
mass = 175;
|
||||
flags |= FL_THINK;
|
||||
flags &= ~FL_UNKNOWN;
|
||||
flags &= ~FL_ANIMATE;
|
||||
setContentsSolid();
|
||||
setSolidType( SOLID_BBOX );
|
||||
m_fFov = 90.0f;
|
||||
@@ -3230,7 +3230,7 @@ void Actor::SetEnemy
|
||||
{
|
||||
//this cansee call changes m_bEnemyVisible and m_bEnemyInFOV
|
||||
//FIXME: macro
|
||||
CanSee(m_Enemy, 0, 0.828 * world->farplane_distance);
|
||||
CanSee(m_Enemy, 0, 0.828 * world->farplane_distance, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4512,12 +4512,8 @@ void Actor::UpdateAnim
|
||||
Com_Printf("ChangeAnim\n");
|
||||
ChangeAnim();
|
||||
}
|
||||
Director.iPaused--;
|
||||
if (!Director.iPaused)
|
||||
{
|
||||
Director.ExecuteRunning();
|
||||
}
|
||||
Director.iPaused++;
|
||||
Director.Unpause();
|
||||
Director.Pause();
|
||||
|
||||
if (m_csSayAnim != STRING_EMPTY)
|
||||
{
|
||||
@@ -5534,9 +5530,7 @@ void Actor::Think
|
||||
|
||||
m_bNeedReload = false;
|
||||
mbBreakSpecialAttack = false;
|
||||
Director.iPaused--;
|
||||
if (!Director.iPaused)
|
||||
Director.ExecuteRunning();
|
||||
Director.Unpause();
|
||||
|
||||
//gi.DPrintf("Actor::Think 5: entnum %d, classname: %s\n", entnum, G_GetEntity(0) ? G_GetEntity(0)->getClassname() : "");
|
||||
}
|
||||
@@ -6791,10 +6785,11 @@ bool Actor::CanSee
|
||||
(
|
||||
Entity *e1,
|
||||
float fov,
|
||||
float vision_distance
|
||||
float vision_distance,
|
||||
bool bNoEnts
|
||||
)
|
||||
{
|
||||
bool canSee = Sentient::CanSee(e1, fov, vision_distance);
|
||||
bool canSee = Sentient::CanSee(e1, fov, vision_distance, false);
|
||||
if (e1 == m_Enemy)
|
||||
{
|
||||
m_iEnemyVisibleCheckTime = level.inttime;
|
||||
@@ -7147,7 +7142,7 @@ bool Actor::CanSeeEnemy
|
||||
{
|
||||
//FIXME: macro
|
||||
if (level.inttime > iMaxDirtyTime + m_iEnemyVisibleCheckTime)
|
||||
CanSee(m_Enemy, 0, 0.828 * world->farplane_distance);
|
||||
CanSee(m_Enemy, 0, 0.828 * world->farplane_distance, false);
|
||||
|
||||
return m_bEnemyVisible;
|
||||
}
|
||||
@@ -7667,7 +7662,7 @@ bool Actor::NoticeShot
|
||||
|
||||
if (pTarget)
|
||||
{
|
||||
if (DoesTheoreticPathExist(pShooter->origin, fDist * 1.5) || CanSee(pTarget, 0, 0.828 * world->farplane_distance))
|
||||
if (DoesTheoreticPathExist(pShooter->origin, fDist * 1.5) || CanSee(pTarget, 0, 0.828 * world->farplane_distance, false))
|
||||
{
|
||||
m_PotentialEnemies.ConfirmEnemy(this, pTarget);
|
||||
}
|
||||
@@ -8233,13 +8228,9 @@ void Actor::IdleTurn
|
||||
|
||||
SafePtr<SimpleEntity> prevTurnEntity = m_pTurnEntity;
|
||||
|
||||
Director.iPaused--;
|
||||
if (!Director.iPaused)
|
||||
{
|
||||
Director.ExecuteRunning();
|
||||
}
|
||||
Director.Unpause();
|
||||
Unregister(STRING_TURNDONE);
|
||||
Director.iPaused++;
|
||||
Director.Pause();
|
||||
|
||||
|
||||
if (m_pTurnEntity == prevTurnEntity)
|
||||
|
||||
+99
-27
@@ -35,31 +35,103 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "grenadehint.h"
|
||||
#include "parm.h"
|
||||
|
||||
extern Event EV_Actor_Start;
|
||||
extern Event EV_Actor_Dead;
|
||||
extern Event EV_Actor_LookAt;
|
||||
extern Event EV_Actor_TurnTo;
|
||||
extern Event EV_Actor_FinishedBehavior;
|
||||
extern Event EV_Actor_NotifyBehavior;
|
||||
extern Event EV_Actor_FinishedMove;
|
||||
extern Event EV_Actor_FinishedAnim;
|
||||
extern Event EV_Actor_WalkTo;
|
||||
extern Event EV_Actor_RunTo;
|
||||
extern Event EV_Actor_Anim;
|
||||
extern Event EV_Actor_AttackFinished;
|
||||
extern Event EV_Actor_Attack;
|
||||
extern Event EV_Actor_AttackPlayer;
|
||||
extern Event EV_Actor_AIOn;
|
||||
extern Event EV_Actor_AIOff;
|
||||
extern Event EV_Actor_AIDeaf;
|
||||
extern Event EV_Actor_AIDumb;
|
||||
extern Event EV_ActorIncomingProjectile;
|
||||
extern Event EV_Anim_Done;
|
||||
extern Event EV_ActorOnlyShootable;
|
||||
extern Event EV_Actor_BounceOff;
|
||||
extern Event EV_Actor_Push;
|
||||
extern Event EV_Actor_Statemap;
|
||||
extern Event EV_Actor_SetTargetable;
|
||||
//
|
||||
// Export these events for AISpawnPoint (since 2.30)
|
||||
//
|
||||
extern Event EV_Actor_SetGun;
|
||||
extern Event EV_Actor_SetGun2;
|
||||
extern Event EV_Actor_GetGun;
|
||||
extern Event EV_Actor_GetSight;
|
||||
extern Event EV_Actor_SetSight;
|
||||
extern Event EV_Actor_SetSight2;
|
||||
extern Event EV_Actor_GetHearing;
|
||||
extern Event EV_Actor_SetHearing;
|
||||
extern Event EV_Actor_SetHearing2;
|
||||
extern Event EV_Actor_GetFov;
|
||||
extern Event EV_Actor_SetFov;
|
||||
extern Event EV_Actor_SetFov2;
|
||||
extern Event EV_Actor_SetTypeIdle;
|
||||
extern Event EV_Actor_SetTypeIdle2;
|
||||
extern Event EV_Actor_GetTypeIdle;
|
||||
extern Event EV_Actor_SetTypeAttack;
|
||||
extern Event EV_Actor_SetTypeAttack2;
|
||||
extern Event EV_Actor_GetTypeAttack;
|
||||
extern Event EV_Actor_SetTypeDisguise;
|
||||
extern Event EV_Actor_SetTypeDisguise2;
|
||||
extern Event EV_Actor_GetTypeDisguise;
|
||||
extern Event EV_Actor_SetDisguiseLevel;
|
||||
extern Event EV_Actor_SetDisguiseLevel2;
|
||||
extern Event EV_Actor_GetDisguiseLevel;
|
||||
extern Event EV_Actor_SetTypeGrenade;
|
||||
extern Event EV_Actor_SetTypeGrenade2;
|
||||
extern Event EV_Actor_GetTypeGrenade;
|
||||
extern Event EV_Actor_SetPatrolPath;
|
||||
extern Event EV_Actor_SetPatrolPath2;
|
||||
extern Event EV_Actor_GetPatrolPath;
|
||||
extern Event EV_Actor_SetPatrolWaitTrigger;
|
||||
extern Event EV_Actor_SetPatrolWaitTrigger2;
|
||||
extern Event EV_Actor_GetPatrolWaitTrigger;
|
||||
extern Event EV_Actor_SetAlarmNode;
|
||||
extern Event EV_Actor_SetAlarmNode2;
|
||||
extern Event EV_Actor_GetAlarmNode;
|
||||
extern Event EV_Actor_SetAccuracy;
|
||||
extern Event EV_Actor_SetAccuracy2;
|
||||
extern Event EV_Actor_GetAccuracy;
|
||||
extern Event EV_Actor_SetMinDistance;
|
||||
extern Event EV_Actor_SetMinDistance2;
|
||||
extern Event EV_Actor_GetMinDistance;
|
||||
extern Event EV_Actor_SetMaxDistance;
|
||||
extern Event EV_Actor_SetMaxDistance2;
|
||||
extern Event EV_Actor_GetMaxDistance;
|
||||
extern Event EV_Actor_GetLeash;
|
||||
extern Event EV_Actor_SetLeash;
|
||||
extern Event EV_Actor_SetLeash2;
|
||||
extern Event EV_Actor_GetInterval;
|
||||
extern Event EV_Actor_SetInterval;
|
||||
extern Event EV_Actor_SetInterval2;
|
||||
extern Event EV_Actor_SetDisguiseRange;
|
||||
extern Event EV_Actor_SetDisguiseRange2;
|
||||
extern Event EV_Actor_GetDisguiseRange;
|
||||
extern Event EV_Actor_SetDisguisePeriod;
|
||||
extern Event EV_Actor_SetDisguisePeriod2;
|
||||
extern Event EV_Actor_GetDisguisePeriod;
|
||||
extern Event EV_Actor_SetGrenadeAwareness;
|
||||
extern Event EV_Actor_SetGrenadeAwareness2;
|
||||
extern Event EV_Actor_GetGrenadeAwareness;
|
||||
extern Event EV_Actor_SetTurret;
|
||||
extern Event EV_Actor_SetTurret2;
|
||||
extern Event EV_Actor_GetTurret;
|
||||
extern Event EV_Actor_SetSoundAwareness;
|
||||
extern Event EV_Actor_SetSoundAwareness2;
|
||||
extern Event EV_Actor_GetSoundAwareness;
|
||||
extern Event EV_Actor_SetGrenadeAwareness;
|
||||
extern Event EV_Actor_SetGrenadeAwareness2;
|
||||
extern Event EV_Actor_SetAmmoGrenade;
|
||||
extern Event EV_Actor_SetAmmoGrenade2;
|
||||
extern Event EV_Actor_GetAmmoGrenade;
|
||||
extern Event EV_Actor_GetMaxNoticeTimeScale;
|
||||
extern Event EV_Actor_SetMaxNoticeTimeScale;
|
||||
extern Event EV_Actor_SetMaxNoticeTimeScale2;
|
||||
extern Event EV_Actor_GetFixedLeash;
|
||||
extern Event EV_Actor_SetFixedLeash;
|
||||
extern Event EV_Actor_SetFixedLeash2;
|
||||
extern Event EV_Actor_GetEnemyShareRange;
|
||||
extern Event EV_Actor_SetEnemyShareRange;
|
||||
extern Event EV_Actor_SetEnemyShareRange2;
|
||||
extern Event EV_Actor_SetWeapon;
|
||||
extern Event EV_Actor_GetWeapon;
|
||||
extern Event EV_Actor_GetVoiceType;
|
||||
extern Event EV_Actor_SetVoiceType;
|
||||
extern Event EV_Actor_SetVoiceType2;
|
||||
extern Event EV_Actor_GetFavoriteEnemy;
|
||||
extern Event EV_Actor_SetFavoriteEnemy;
|
||||
extern Event EV_Actor_SetFavoriteEnemy2;
|
||||
extern Event EV_Actor_SetBalconyHeight;
|
||||
extern Event EV_Actor_SetBalconyHeight2;
|
||||
extern Event EV_Actor_GetBalconyHeight;
|
||||
extern Event EV_Actor_GetNoSurprise;
|
||||
extern Event EV_Actor_SetNoSurprise;
|
||||
extern Event EV_Actor_SetNoSurprise2;
|
||||
extern Event EV_Actor_DeathEmbalm;
|
||||
|
||||
// Bones used by actor
|
||||
@@ -981,7 +1053,7 @@ public:
|
||||
void NotifySquadmateKilled( Sentient *pSquadMate, Sentient *pAttacker );
|
||||
void RaiseAlertnessForEventType( int iType );
|
||||
void RaiseAlertness( float fAmount );
|
||||
virtual bool CanSee( Entity *e1, float fov, float vision_distance ) override;
|
||||
virtual bool CanSee( Entity *e1, float fov, float vision_distance, bool bNoEnts ) override;
|
||||
virtual Vector GunPosition( void ) override;
|
||||
bool WithinVisionDistance( Entity *ent ) const;
|
||||
bool InFOV( Vector pos, float check_fov, float check_fovdot );
|
||||
@@ -1178,7 +1250,7 @@ public:
|
||||
bool ShortenPathToAttack( float fMinDist );
|
||||
void StrafeToAttack( float fDist, vec3_t vDir );
|
||||
virtual Vector GunTarget( bool bNoCollision ) override;
|
||||
virtual qboolean setModel( void );
|
||||
virtual qboolean setModel( void ) override;
|
||||
void EventSetHeadModel( Event *ev );
|
||||
void EventGetHeadModel( Event *ev );
|
||||
void EventSetHeadSkin( Event *ev );
|
||||
|
||||
@@ -465,7 +465,7 @@ void Actor::State_Cover_Shoot
|
||||
|
||||
if (level.inttime > m_iStateTime + 10000)
|
||||
{
|
||||
gi.Cvar_Set("g_monitornum", va("%i", entnum));
|
||||
gi.cvar_set("g_monitornum", va("%i", entnum));
|
||||
assert(!"anim/shoot.scr took over 10 seconds");
|
||||
Com_Error(ERR_DROP, "anim/shoot.scr took over 10 seconds, entnum = %i, targetname = %s", entnum, targetname.c_str());
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ void Actor::Think_Curious
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Enemy || CanSeeEnemy(100))
|
||||
if (!m_Enemy || CanSeeEnemy(100))
|
||||
{
|
||||
ClearPath();
|
||||
Anim_Stand();
|
||||
|
||||
@@ -313,7 +313,7 @@ float ActorEnemy::UpdateLMRF
|
||||
|
||||
*pbInFovAndRange = true;
|
||||
|
||||
if (!pSelf->CanSee(m_pEnemy, 0, 0))
|
||||
if (!pSelf->CanSee(m_pEnemy, 0, 0, false))
|
||||
{
|
||||
return 8.0;
|
||||
}
|
||||
@@ -684,7 +684,7 @@ void ActorEnemySet::ConfirmEnemyIfCanSeeSharerOrEnemy
|
||||
if (!pSelf->CanSee(
|
||||
pSharer,
|
||||
pSelf->m_bSilent ? 90.0f : 0,
|
||||
0.828 * world->farplane_distance))
|
||||
0.828 * world->farplane_distance, false))
|
||||
return;
|
||||
}
|
||||
pActorEnemy->m_fVisibility = 1.0;
|
||||
|
||||
+713
-607
File diff suppressed because it is too large.
Load diff
+130
-128
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,10 +24,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#ifndef __ANIMATE_H__
|
||||
#define __ANIMATE_H__
|
||||
|
||||
#if defined ( GAME_DLL )
|
||||
#include "entity.h"
|
||||
#elif defined ( CGAME_DLL )
|
||||
#include "script/canimate.h"
|
||||
#if defined(GAME_DLL)
|
||||
# include "entity.h"
|
||||
#elif defined(CGAME_DLL)
|
||||
# include "script/canimate.h"
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
@@ -35,177 +35,179 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
extern Event EV_SetAnim;
|
||||
extern Event EV_SetSyncTime;
|
||||
|
||||
#define ANIM_PAUSED 1
|
||||
#define ANIM_SYNC 2
|
||||
#define ANIM_FINISHED 4
|
||||
#define ANIM_NOEXIT 8
|
||||
#define ANIM_NODELTA 16
|
||||
#define ANIM_LOOP 32
|
||||
#define ANIM_NOACTION 64
|
||||
#define ANIM_PAUSED 1
|
||||
#define ANIM_SYNC 2
|
||||
#define ANIM_FINISHED 4
|
||||
#define ANIM_NOEXIT 8
|
||||
#define ANIM_NODELTA 16
|
||||
#define ANIM_LOOP 32
|
||||
#define ANIM_NOACTION 64
|
||||
|
||||
#define MINIMUM_DELTA_MOVEMENT 8
|
||||
#define MINIMUM_DELTA_MOVEMENT_PER_FRAME ( MINIMUM_DELTA_MOVEMENT / 20.0f )
|
||||
#define MINIMUM_DELTA_MOVEMENT 8
|
||||
#define MINIMUM_DELTA_MOVEMENT_PER_FRAME (MINIMUM_DELTA_MOVEMENT / 20.0f)
|
||||
|
||||
#define FLAGGED_ANIMATE_SLOT 20
|
||||
#define FLAGGED_ANIMATE_SLOT 20
|
||||
|
||||
class Animate;
|
||||
|
||||
typedef SafePtr<Animate> AnimatePtr;
|
||||
|
||||
class AnimationEvent : public Event
|
||||
{
|
||||
private:
|
||||
short anim_number;
|
||||
short anim_frame;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( AnimationEvent );
|
||||
|
||||
void *operator new( size_t size );
|
||||
void operator delete( void *ptr );
|
||||
|
||||
AnimationEvent( str name ) : Event( name ) { anim_number = 0; anim_frame = 0; }
|
||||
AnimationEvent( const Event& ev ) : Event( ev ) { anim_number = 0; anim_frame = 0; }
|
||||
AnimationEvent() {}
|
||||
|
||||
void SetAnimationFrame( int frame ) { anim_frame = frame; };
|
||||
void SetAnimationNumber( int num ) { anim_number = num; };
|
||||
};
|
||||
|
||||
class Animate : public Entity
|
||||
{
|
||||
protected:
|
||||
int animFlags[ MAX_FRAMEINFOS ];
|
||||
int animFlags[MAX_FRAMEINFOS];
|
||||
|
||||
float syncTime;
|
||||
float syncRate;
|
||||
int pauseSyncTime;
|
||||
float syncTime;
|
||||
float syncRate;
|
||||
int pauseSyncTime;
|
||||
bool is_paused;
|
||||
|
||||
Event *doneEvents[ MAX_FRAMEINFOS ];
|
||||
Event *doneEvents[MAX_FRAMEINFOS];
|
||||
|
||||
float animtimes[ MAX_FRAMEINFOS ];
|
||||
float frametimes[ MAX_FRAMEINFOS ];
|
||||
float animtimes[MAX_FRAMEINFOS];
|
||||
float frametimes[MAX_FRAMEINFOS];
|
||||
|
||||
public:
|
||||
Vector frame_delta;
|
||||
Vector frame_delta;
|
||||
float angular_delta;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( Animate );
|
||||
CLASS_PROTOTYPE(Animate);
|
||||
|
||||
Animate();
|
||||
~Animate();
|
||||
Animate();
|
||||
~Animate();
|
||||
|
||||
void DoExitCommands( int slot = 0 );
|
||||
void NewAnim( int animnum, int slot = 0, float weight = 1.0f );
|
||||
void NewAnim( int animnum, Event *endevent, int slot = 0, float weight = 1.0f );
|
||||
void NewAnim( int animnum, Event &endevent, int slot = 0, float weight = 1.0f );
|
||||
void NewAnim( const char *animname, int slot = 0, float weight = 1.0f );
|
||||
void NewAnim( const char *animname, Event *endevent, int slot = 0, float weight = 1.0f );
|
||||
void NewAnim( const char *animname, Event &endevent, int slot = 0, float weight = 1.0f );
|
||||
void SetFrame( void );
|
||||
qboolean HasAnim( const char *animname );
|
||||
Event *AnimDoneEvent( int slot = 0 );
|
||||
void SetAnimDoneEvent( Event &event, int slot = 0 );
|
||||
void SetAnimDoneEvent( Event *event, int slot = 0 );
|
||||
int NumFrames( int slot = 0 );
|
||||
int NumAnims( void );
|
||||
const char *AnimName( int slot = 0 );
|
||||
float AnimTime( int slot = 0 );
|
||||
virtual void AnimFinished( int slot = 0 );
|
||||
void SetTime( int slot = 0, float time = 0.0f );
|
||||
void SetNormalTime( int slot = 0, float normal = 1.0f );
|
||||
float GetTime( int slot = 0 );
|
||||
float GetNormalTime( int slot = 0 );
|
||||
void SetWeight( int slot = 0, float weight = 1.0f );
|
||||
float GetWeight( int slot = 0 );
|
||||
void SetRepeatType( int slot = 0 );
|
||||
void SetOnceType( int slot = 0 );
|
||||
void SetSyncRate( float rate );
|
||||
void SetSyncTime( float s );
|
||||
void UseSyncTime(int slot, int sync);
|
||||
void NewAnim(int animnum, int slot = 0, float weight = 1.0f);
|
||||
void NewAnim(int animnum, Event *endevent, int slot = 0, float weight = 1.0f);
|
||||
void NewAnim(int animnum, Event &endevent, int slot = 0, float weight = 1.0f);
|
||||
void NewAnim(const char *animname, int slot = 0, float weight = 1.0f);
|
||||
void NewAnim(const char *animname, Event *endevent, int slot = 0, float weight = 1.0f);
|
||||
void NewAnim(const char *animname, Event &endevent, int slot = 0, float weight = 1.0f);
|
||||
void SetFrame(void);
|
||||
qboolean HasAnim(const char *animname);
|
||||
Event *AnimDoneEvent(int slot = 0);
|
||||
void SetAnimDoneEvent(Event &event, int slot = 0);
|
||||
void SetAnimDoneEvent(Event *event, int slot = 0);
|
||||
int NumAnims(void);
|
||||
const char *AnimName(int slot = 0);
|
||||
float AnimTime(int slot = 0);
|
||||
|
||||
void Pause( int slot = 0, int pause = 1 );
|
||||
void StopAnimating( int slot = 0 );
|
||||
void StopAnimatingAtEnd( int slot = 0 );
|
||||
|
||||
virtual int CurrentAnim( int slot = 0 );
|
||||
virtual float CurrentTime( int slot = 0 );
|
||||
int CurrentAnim(int slot = 0) const override;
|
||||
float CurrentTime(int slot = 0) const override;
|
||||
|
||||
void PreAnimate( void ) override;
|
||||
void PostAnimate( void ) override;
|
||||
void Archive(Archiver &arc) override;
|
||||
virtual void AnimFinished(int slot = 0);
|
||||
|
||||
virtual void DumpAnimInfo( void );
|
||||
|
||||
void Archive( Archiver &arc ) override;
|
||||
void PreAnimate(void) override;
|
||||
void PostAnimate(void) override;
|
||||
void SetTime(int slot = 0, float time = 0.0f);
|
||||
void SetNormalTime(int slot = 0, float normal = 1.0f);
|
||||
float GetTime(int slot = 0);
|
||||
float GetNormalTime(int slot = 0);
|
||||
void SetWeight(int slot = 0, float weight = 1.0f);
|
||||
float GetWeight(int slot = 0);
|
||||
void SetRepeatType(int slot = 0);
|
||||
void SetOnceType(int slot = 0);
|
||||
bool IsRepeatType(int slot);
|
||||
void Pause(int slot = 0, int pause = 1);
|
||||
void StopAnimating(int slot = 0);
|
||||
void UseSyncTime(int slot, int sync);
|
||||
void SetSyncTime(float s);
|
||||
float GetSyncTime();
|
||||
void SetSyncRate(float rate);
|
||||
|
||||
void FrameDeltaEvent( Event *ev );
|
||||
void ForwardExec( Event *ev );
|
||||
void EventSetSyncTime( Event *ev );
|
||||
void EventIsLoopingAnim( Event *ev );
|
||||
void StopAnimating( Event *ev );
|
||||
float GetSyncRate();
|
||||
void PauseSyncTime(int pause);
|
||||
float GetYawOffset();
|
||||
float GetCrossTime(int slot);
|
||||
|
||||
void DoExitCommands(int slot = 0);
|
||||
void ForwardExec(Event *ev);
|
||||
void EventSetSyncTime(Event *ev);
|
||||
void EventIsLoopingAnim(Event *ev);
|
||||
void EventSetYawFromBone(Event *ev);
|
||||
void EventPlayerSpawn(Event *ev);
|
||||
void EventPlayerSpawnUtility(Event *ev);
|
||||
void EventPauseAnim(Event *ev);
|
||||
virtual void DumpAnimInfo();
|
||||
void SlotChanged(int slot);
|
||||
|
||||
// FIXME: delete this, fakk2 remnant
|
||||
int NumFrames(int slot = 0);
|
||||
};
|
||||
|
||||
extern MEM_BlockAlloc<AnimationEvent> AnimationEvent_allocator;
|
||||
|
||||
inline int Animate::CurrentAnim( int slot )
|
||||
inline void Animate::SetWeight(int slot, float weight)
|
||||
{
|
||||
return edict->s.frameInfo[ slot ].index;
|
||||
edict->s.frameInfo[slot].weight = weight;
|
||||
}
|
||||
|
||||
inline float Animate::CurrentTime( int slot )
|
||||
inline float Animate::GetWeight(int slot)
|
||||
{
|
||||
return edict->s.frameInfo[ slot ].time;
|
||||
return edict->s.frameInfo[slot].weight;
|
||||
}
|
||||
|
||||
inline int Animate::NumFrames( int slot )
|
||||
inline bool Animate::IsRepeatType(int slot)
|
||||
{
|
||||
return gi.Anim_NumFrames( edict->tiki, edict->s.frameInfo[ slot ].index );
|
||||
return (animFlags[slot] & ANIM_LOOP) != 0;
|
||||
}
|
||||
|
||||
inline float Animate::AnimTime( int slot )
|
||||
inline float Animate::GetSyncTime()
|
||||
{
|
||||
return animtimes[ slot ];
|
||||
return syncTime;
|
||||
}
|
||||
|
||||
inline int Animate::NumAnims( void )
|
||||
inline float Animate::GetSyncRate()
|
||||
{
|
||||
return gi.TIKI_NumAnims( edict->tiki );
|
||||
return syncRate;
|
||||
}
|
||||
|
||||
inline const char *Animate::AnimName( int slot )
|
||||
inline void Animate::PauseSyncTime(int pause)
|
||||
{
|
||||
return gi.Anim_NameForNum( edict->tiki, edict->s.frameInfo[ slot ].index );
|
||||
pauseSyncTime = pause;
|
||||
}
|
||||
|
||||
inline Event *Animate::AnimDoneEvent( int slot )
|
||||
inline void Animate::Archive(Archiver& arc)
|
||||
{
|
||||
return doneEvents[ slot ];
|
||||
Entity::Archive(arc);
|
||||
|
||||
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
|
||||
arc.ArchiveInteger(&animFlags[i]);
|
||||
}
|
||||
arc.ArchiveFloat(&syncTime);
|
||||
arc.ArchiveFloat(&syncRate);
|
||||
arc.ArchiveInteger(&pauseSyncTime);
|
||||
arc.ArchiveBool(&is_paused);
|
||||
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
|
||||
arc.ArchiveEventPointer(&doneEvents[i]);
|
||||
}
|
||||
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
|
||||
arc.ArchiveFloat(&animtimes[i]);
|
||||
}
|
||||
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
|
||||
arc.ArchiveFloat(&frametimes[i]);
|
||||
}
|
||||
arc.ArchiveVector(&frame_delta);
|
||||
arc.ArchiveFloat(&angular_delta);
|
||||
}
|
||||
|
||||
inline void Animate::Archive( Archiver &arc )
|
||||
inline void Animate::SlotChanged(int slot)
|
||||
{
|
||||
Entity::Archive( arc );
|
||||
animFlags[slot] = (animFlags[slot] | ANIM_NODELTA) & ~ANIM_FINISHED;
|
||||
}
|
||||
|
||||
for( int i = MAX_FRAMEINFOS - 1; i >= 0; i-- )
|
||||
{
|
||||
arc.ArchiveInteger( &animFlags[ i ] );
|
||||
}
|
||||
arc.ArchiveFloat( &syncTime );
|
||||
arc.ArchiveFloat( &syncRate );
|
||||
arc.ArchiveInteger( &pauseSyncTime );
|
||||
for( int i = MAX_FRAMEINFOS - 1; i >= 0; i-- )
|
||||
{
|
||||
arc.ArchiveEventPointer( &doneEvents[ i ] );
|
||||
}
|
||||
for( int i = MAX_FRAMEINFOS - 1; i >= 0; i-- )
|
||||
{
|
||||
arc.ArchiveFloat( &animtimes[ i ] );
|
||||
}
|
||||
for( int i = MAX_FRAMEINFOS - 1; i >= 0; i-- )
|
||||
{
|
||||
arc.ArchiveFloat( &frametimes[ i ] );
|
||||
}
|
||||
arc.ArchiveVector( &frame_delta );
|
||||
inline float Animate::CurrentTime(int slot) const
|
||||
{
|
||||
return edict->s.frameInfo[slot].time;
|
||||
}
|
||||
|
||||
inline Event *Animate::AnimDoneEvent(int slot)
|
||||
{
|
||||
return doneEvents[slot];
|
||||
}
|
||||
|
||||
inline int Animate::NumFrames(int slot)
|
||||
{
|
||||
return gi.Anim_NumFrames(edict->tiki, edict->s.frameInfo[slot].index);
|
||||
}
|
||||
|
||||
#endif /* animate.h */
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "animationevent.h"
|
||||
#include "../qcommon/mem_blockalloc.h"
|
||||
|
||||
MEM_BlockAlloc<AnimationEvent> AnimationEvent_allocator;
|
||||
|
||||
CLASS_DECLARATION(Event, AnimationEvent, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
AnimationEvent::AnimationEvent(str command, int numArgs)
|
||||
: Event(command, numArgs)
|
||||
{
|
||||
anim_number = 0;
|
||||
anim_frame = 0;
|
||||
}
|
||||
|
||||
AnimationEvent::AnimationEvent(const Event& ev)
|
||||
: Event(ev)
|
||||
{
|
||||
anim_number = 0;
|
||||
anim_frame = 0;
|
||||
}
|
||||
|
||||
AnimationEvent::AnimationEvent() {}
|
||||
|
||||
void *AnimationEvent::operator new(size_t size)
|
||||
{
|
||||
return AnimationEvent_allocator.Alloc();
|
||||
}
|
||||
|
||||
void AnimationEvent::operator delete(void *ptr)
|
||||
{
|
||||
return AnimationEvent_allocator.Free(ptr);
|
||||
}
|
||||
|
||||
int AnimationEvent::GetAnimationFrame() const
|
||||
{
|
||||
return anim_frame;
|
||||
}
|
||||
|
||||
int AnimationEvent::GetAnimationNumber() const
|
||||
{
|
||||
return anim_number;
|
||||
}
|
||||
|
||||
void AnimationEvent::SetAnimationFrame(int frame)
|
||||
{
|
||||
anim_frame = frame;
|
||||
};
|
||||
|
||||
void AnimationEvent::SetAnimationNumber(int num)
|
||||
{
|
||||
anim_number = num;
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// animate.h -- Animation event
|
||||
|
||||
#include "../qcommon/listener.h"
|
||||
|
||||
class AnimationEvent : public Event
|
||||
{
|
||||
private:
|
||||
short anim_number;
|
||||
short anim_frame;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(AnimationEvent);
|
||||
|
||||
void *operator new(size_t size);
|
||||
void operator delete(void *ptr);
|
||||
|
||||
AnimationEvent(str command, int numArgs = 0);
|
||||
AnimationEvent(const Event& ev);
|
||||
AnimationEvent();
|
||||
|
||||
int GetAnimationFrame() const;
|
||||
int GetAnimationNumber() const;
|
||||
void SetAnimationFrame(int frame);
|
||||
void SetAnimationNumber(int num);
|
||||
};
|
||||
|
||||
extern MEM_BlockAlloc<AnimationEvent> AnimationEvent_allocator;
|
||||
@@ -814,7 +814,7 @@ SafePtrBase * ptr
|
||||
{
|
||||
pointer_fixup_t *fixup;
|
||||
|
||||
ArchiveData( ARC_SafePointer, &index, sizeof( &index ) );
|
||||
ArchiveData( ARC_SafePointer, &index, sizeof( index ) );
|
||||
|
||||
// Check for a NULL pointer
|
||||
assert( ptr );
|
||||
@@ -984,11 +984,11 @@ void Archiver::ArchiveConfigString( int cs )
|
||||
if( archivemode == ARCHIVE_READ )
|
||||
{
|
||||
ArchiveString( &s );
|
||||
glbs.SetConfigstring( cs, s.c_str() );
|
||||
glbs.setConfigstring( cs, s.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
s = glbs.GetConfigstring( cs );
|
||||
s = glbs.getConfigstring( cs );
|
||||
ArchiveString( &s );
|
||||
}
|
||||
#endif
|
||||
@@ -1133,7 +1133,7 @@ void Archiver::ArchiveObject
|
||||
}
|
||||
|
||||
ArchiveInteger( &entnum );
|
||||
( ( Entity * )obj )->SetEntNum( entnum );
|
||||
( ( Entity * )obj )->entnum = entnum;
|
||||
//
|
||||
// make sure to setup spawnflags properly
|
||||
//
|
||||
|
||||
@@ -226,7 +226,7 @@ inline void Container<Type>::Archive
|
||||
numobjects = num;
|
||||
}
|
||||
|
||||
ArchiveFunc( arc, &objlist[ i ] );
|
||||
ArchiveFunc( arc, &objlist[ i - 1 ] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ void con_set< key, value >::Archive
|
||||
Archiver& arc
|
||||
)
|
||||
{
|
||||
Entry< key, value > *e;
|
||||
Entry *e;
|
||||
int hash;
|
||||
int i;
|
||||
|
||||
@@ -361,18 +361,17 @@ void con_set< key, value >::Archive
|
||||
{
|
||||
if( tableLength != 1 )
|
||||
{
|
||||
table = new Entry< key, value > *[ tableLength ]();
|
||||
memset( table, 0, tableLength * sizeof( Entry< key, value > * ) );
|
||||
table = new Entry *[ tableLength ]();
|
||||
memset( table, 0, tableLength * sizeof( Entry * ) );
|
||||
}
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
e = new Entry< key, value >;
|
||||
e = new Entry;
|
||||
e->Archive( arc );
|
||||
|
||||
hash = HashCode< key >( e->key ) % tableLength;
|
||||
|
||||
e->index = i;
|
||||
e->next = table[ hash ];
|
||||
table[ hash ] = e;
|
||||
}
|
||||
|
||||
+78
-49
@@ -50,7 +50,6 @@ float PM_NOCLIPfriction = 5.0f;
|
||||
|
||||
int c_pmove = 0;
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
PM_AddEvent
|
||||
@@ -1100,35 +1099,57 @@ static void PM_CheckDuck( void )
|
||||
return;
|
||||
}
|
||||
|
||||
if( ( pm->ps->pm_flags & ( PMF_DUCKED | PMF_VIEW_PRONE ) ) == ( PMF_DUCKED | PMF_VIEW_PRONE ) )
|
||||
{
|
||||
pm->maxs[ 2 ] = 54.0f;
|
||||
}
|
||||
else if( pm->ps->pm_flags & PMF_DUCKED )
|
||||
{
|
||||
pm->maxs[ 2 ] = 60.0f;
|
||||
pm->ps->viewheight = CROUCH_VIEWHEIGHT;
|
||||
}
|
||||
else if( pm->ps->pm_flags & PMF_VIEW_PRONE )
|
||||
{
|
||||
pm->maxs[ 2 ] = 20.0f;
|
||||
pm->ps->viewheight = PRONE_VIEWHEIGHT;
|
||||
}
|
||||
else if( pm->ps->pm_flags & PMF_VIEW_DUCK_RUN )
|
||||
{
|
||||
pm->maxs[ 2 ] = 94.0f;
|
||||
pm->mins[ 2 ] = 54.0f;
|
||||
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
|
||||
}
|
||||
else if( pm->ps->pm_flags & PMF_VIEW_JUMP_START )
|
||||
{
|
||||
pm->maxs[ 2 ] = 94.0f;
|
||||
pm->ps->viewheight = JUMP_START_VIEWHEIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pm->maxs[ 2 ] = 94.0f;
|
||||
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
|
||||
if (pm->protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
|
||||
//
|
||||
// Prone was removed in 2.0
|
||||
//
|
||||
if (pm->ps->pm_flags & PMF_DUCKED)
|
||||
{
|
||||
pm->maxs[2] = 54.f;
|
||||
pm->ps->viewheight = CROUCH_VIEWHEIGHT;
|
||||
}
|
||||
else if (pm->ps->pm_flags & PMF_VIEW_JUMP_START)
|
||||
{
|
||||
pm->maxs[2] = 94.0f;
|
||||
pm->ps->viewheight = JUMP_START_VIEWHEIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pm->maxs[2] = 94.0f;
|
||||
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
|
||||
}
|
||||
} else {
|
||||
if ((pm->ps->pm_flags & (PMF_DUCKED | PMF_VIEW_PRONE)) == (PMF_DUCKED | PMF_VIEW_PRONE))
|
||||
{
|
||||
pm->maxs[2] = 54.0f;
|
||||
pm->ps->viewheight = CROUCH_VIEWHEIGHT;
|
||||
}
|
||||
else if (pm->ps->pm_flags & PMF_DUCKED)
|
||||
{
|
||||
pm->maxs[2] = 60.0f;
|
||||
pm->ps->viewheight = CROUCH_VIEWHEIGHT;
|
||||
}
|
||||
else if (pm->ps->pm_flags & PMF_VIEW_PRONE)
|
||||
{
|
||||
pm->maxs[2] = 20.0f;
|
||||
pm->ps->viewheight = PRONE_VIEWHEIGHT;
|
||||
}
|
||||
else if (pm->ps->pm_flags & PMF_VIEW_DUCK_RUN)
|
||||
{
|
||||
pm->maxs[2] = 94.0f;
|
||||
pm->mins[2] = 54.0f;
|
||||
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
|
||||
}
|
||||
else if (pm->ps->pm_flags & PMF_VIEW_JUMP_START)
|
||||
{
|
||||
pm->maxs[2] = 94.0f;
|
||||
pm->ps->viewheight = JUMP_START_VIEWHEIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pm->maxs[2] = 94.0f;
|
||||
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,22 +1463,25 @@ void PmoveSingle( pmove_t *pmove )
|
||||
|
||||
pml.frametime = pml.msec * 0.001;
|
||||
|
||||
if( ( pm->cmd.buttons & ( BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT ) &&
|
||||
( pm->cmd.buttons & ( BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT ) ) != ( BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT ) ) )
|
||||
if ((pm->cmd.buttons & (BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT) &&
|
||||
(pm->cmd.buttons & (BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT)) != (BUTTON_LEAN_LEFT | BUTTON_LEAN_RIGHT)) &&
|
||||
(!pm->cmd.forwardmove || pm->alwaysAllowLean) &&
|
||||
(!pm->cmd.rightmove || pm->alwaysAllowLean) &&
|
||||
(!pm->cmd.upmove || pm->alwaysAllowLean))
|
||||
{
|
||||
if( pm->cmd.buttons & BUTTON_LEAN_LEFT )
|
||||
{
|
||||
if( pm->ps->fLeanAngle <= -40.0f )
|
||||
if( pm->ps->fLeanAngle <= -pm->leanMax)
|
||||
{
|
||||
pm->ps->fLeanAngle = -40.0f;
|
||||
pm->ps->fLeanAngle = -pm->leanMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
float fAngle = pml.frametime * ( -40.0f - pm->ps->fLeanAngle );
|
||||
float fLeanAngle = pml.frametime * -4.0f;
|
||||
float fAngle = pml.frametime * ( -pm->leanMax - pm->ps->fLeanAngle ) * pm->leanAdd;
|
||||
float fLeanAngle = pml.frametime * -pm->leanSpeed;
|
||||
|
||||
if( fAngle * 10.0f <= fLeanAngle ) {
|
||||
fLeanAngle = fAngle * 10.0f;
|
||||
if( fAngle <= fLeanAngle ) {
|
||||
fLeanAngle = fAngle;
|
||||
}
|
||||
|
||||
pm->ps->fLeanAngle += fLeanAngle;
|
||||
@@ -1465,19 +1489,19 @@ void PmoveSingle( pmove_t *pmove )
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pm->ps->fLeanAngle >= 40.0f )
|
||||
if( pm->ps->fLeanAngle >= pm->leanMax )
|
||||
{
|
||||
pm->ps->fLeanAngle = 40.0f;
|
||||
pm->ps->fLeanAngle = pm->leanMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
float fAngle = 40.0f - pm->ps->fLeanAngle;
|
||||
float fLeanAngle = pml.frametime * 4.0f;
|
||||
float fMult = pml.frametime * fAngle;
|
||||
float fAngle = pm->leanMax - pm->ps->fLeanAngle;
|
||||
float fLeanAngle = pml.frametime * pm->leanSpeed;
|
||||
float fMult = pml.frametime * fAngle * pm->leanAdd;
|
||||
|
||||
if( fLeanAngle <= fMult * 10.0f )
|
||||
if( fLeanAngle <= fMult )
|
||||
{
|
||||
fLeanAngle = fMult * 10.0f;
|
||||
fLeanAngle = fMult;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1490,11 +1514,11 @@ void PmoveSingle( pmove_t *pmove )
|
||||
}
|
||||
else if( pm->ps->fLeanAngle )
|
||||
{
|
||||
float fAngle = pm->ps->fLeanAngle * pml.frametime * 15.0f;
|
||||
float fAngle = pm->ps->fLeanAngle * pml.frametime * pm->leanRecoverSpeed;
|
||||
|
||||
if( pm->ps->fLeanAngle <= 0.0f )
|
||||
{
|
||||
float fLeanAngle = -4.0f * pml.frametime;
|
||||
float fLeanAngle = pml.frametime * -pm->leanSpeed;
|
||||
|
||||
if( fAngle <= fLeanAngle )
|
||||
{
|
||||
@@ -1505,9 +1529,9 @@ void PmoveSingle( pmove_t *pmove )
|
||||
}
|
||||
else
|
||||
{
|
||||
float fLeanAngle = pml.frametime * 4.0f;
|
||||
float fLeanAngle = pml.frametime * pm->leanSpeed;
|
||||
|
||||
if( fLeanAngle <= fAngle ) {
|
||||
if(fAngle >= fLeanAngle) {
|
||||
fLeanAngle = fAngle;
|
||||
}
|
||||
|
||||
@@ -1515,6 +1539,10 @@ void PmoveSingle( pmove_t *pmove )
|
||||
}
|
||||
}
|
||||
|
||||
if (pm->ps->pm_flags & PMF_NO_LEAN) {
|
||||
pm->ps->fLeanAngle = 0;
|
||||
}
|
||||
|
||||
// update the viewangles
|
||||
PM_UpdateViewAngles( pm->ps, &pm->cmd );
|
||||
|
||||
@@ -1540,6 +1568,7 @@ void PmoveSingle( pmove_t *pmove )
|
||||
|
||||
if( ( pm->ps->pm_flags & PMF_NO_MOVE ) || ( pm->ps->pm_flags & PMF_FROZEN ) )
|
||||
{
|
||||
PM_CheckDuck();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+652
-558
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "bg_voteoptions.h"
|
||||
|
||||
// FIXME: unimplemented
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "listener.h"
|
||||
#include "g_public.h"
|
||||
|
||||
typedef enum voteoptiontype_e {
|
||||
/** No input. */
|
||||
VOTE_NO_CHOICES,
|
||||
/** List of choices. */
|
||||
VOTE_OPTION_LIST,
|
||||
/** Text input type command. */
|
||||
VOTE_OPTION_TEXT,
|
||||
/** Accepts an integer as an input. */
|
||||
VOTE_OPTION_INTEGER,
|
||||
/** Accepts a float number as input. */
|
||||
VOTE_OPTION_FLOAT,
|
||||
/** A list of clients, one to choose. */
|
||||
VOTE_OPTION_CLIENT,
|
||||
/** A list of clients (excluding self), one to choose. */
|
||||
VOTE_OPTION_CLIENT_NOT_SELF,
|
||||
} voteoptiontype_t;
|
||||
|
||||
class VoteOptionListItem
|
||||
{
|
||||
str m_sItemName;
|
||||
str m_sCommand;
|
||||
class VoteOptionListItem *m_pNext;
|
||||
};
|
||||
|
||||
class SingleVoteOption
|
||||
{
|
||||
str m_sVoteName;
|
||||
str m_sCommand;
|
||||
voteoptiontype_t m_optionType;
|
||||
VoteOptionListItem *m_pListItem;
|
||||
class SingleVoteOption *m_pNext;
|
||||
};
|
||||
|
||||
class VoteOptions : public Class
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(VoteOptions);
|
||||
|
||||
public:
|
||||
str m_sFileName;
|
||||
str m_sBuffer;
|
||||
SingleVoteOption *m_pHeadOption;
|
||||
int field_5;
|
||||
float field_6;
|
||||
float field_7;
|
||||
float field_8;
|
||||
float field_9;
|
||||
float field_10;
|
||||
};
|
||||
+104
-78
@@ -115,7 +115,7 @@ void CameraMoveState::DoNodeEvents
|
||||
ent = NULL;
|
||||
do
|
||||
{
|
||||
ent = ( Entity * )G_FindTarget( ( SimpleEntity * )ent, node->triggertarget.c_str() );
|
||||
ent = G_FindTarget( ent, node->triggertarget.c_str() );
|
||||
if( !ent )
|
||||
{
|
||||
break;
|
||||
@@ -486,6 +486,16 @@ Event EV_Camera_NoWatch
|
||||
"if fadeTime is specified, camera will fade over that time",
|
||||
EV_NORMAL
|
||||
);
|
||||
Event EV_Camera_WatchString
|
||||
(
|
||||
"watchstring",
|
||||
EV_CONSOLE,
|
||||
"sF",
|
||||
"string fadeTime",
|
||||
"Makes the camera watch based on a string.\n"
|
||||
"if fadeTime is specified, camera will fade over that time",
|
||||
EV_NORMAL
|
||||
);
|
||||
|
||||
//
|
||||
// Camera positioning events
|
||||
@@ -679,46 +689,47 @@ LEVEL_EXIT if the camera is being used, the level exit state will be set
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
CLASS_DECLARATION( Entity, Camera, "func_camera" )
|
||||
{
|
||||
{ &EV_Camera_CameraThink, &Camera::CameraThink },
|
||||
{ &EV_Activate, &Camera::StartMoving },
|
||||
{ &EV_Camera_StartMoving, &Camera::StartMoving },
|
||||
{ &EV_Camera_StopMoving, &Camera::StopMoving },
|
||||
{ &EV_Camera_Pause, &Camera::Pause },
|
||||
{ &EV_Camera_Continue, &Camera::Continue },
|
||||
{ &EV_Camera_SetSpeed, &Camera::SetSpeed },
|
||||
{ &EV_Camera_SetFollowDistance, &Camera::SetFollowDistance },
|
||||
{ &EV_Camera_SetFollowYaw, &Camera::SetFollowYaw },
|
||||
{ &EV_Camera_AbsoluteYaw, &Camera::AbsoluteYaw },
|
||||
{ &EV_Camera_RelativeYaw, &Camera::RelativeYaw },
|
||||
{ &EV_Camera_SetOrbitHeight, &Camera::SetOrbitHeight },
|
||||
{ &EV_Camera_SetFOV, &Camera::SetFOV },
|
||||
{ &EV_Camera_Orbit, &Camera::OrbitEvent },
|
||||
{ &EV_Camera_Follow, &Camera::FollowEvent },
|
||||
{ &EV_Camera_Watch, &Camera::WatchEvent },
|
||||
{ &EV_Camera_WatchPath, &Camera::WatchPathEvent },
|
||||
{ &EV_Camera_WatchNodes, &Camera::WatchNodesEvent },
|
||||
{ &EV_Camera_NoWatch, &Camera::NoWatchEvent },
|
||||
{ &EV_Camera_LookAt, &Camera::LookAt },
|
||||
{ &EV_Camera_TurnTo, &Camera::TurnTo },
|
||||
{ &EV_Camera_MoveToEntity, &Camera::MoveToEntity },
|
||||
{ &EV_Camera_MoveToPos, &Camera::MoveToPos },
|
||||
{ &EV_Camera_Cut, &Camera::Cut },
|
||||
{ &EV_Camera_FadeTime, &Camera::FadeTime },
|
||||
{ &EV_Camera_SetNextCamera, &Camera::SetNextCamera },
|
||||
{ &EV_Camera_SetupCamera, &Camera::SetupCamera },
|
||||
{ &EV_SetAngles, &Camera::SetAnglesEvent },
|
||||
{ &EV_Camera_SetAutoState, &Camera::SetAutoStateEvent },
|
||||
{ &EV_Camera_SetAutoRadius, &Camera::SetAutoRadiusEvent },
|
||||
{ &EV_Camera_SetAutoStartTime, &Camera::SetAutoStartTimeEvent },
|
||||
{ &EV_Camera_SetAutoStopTime, &Camera::SetAutoStopTimeEvent },
|
||||
{ &EV_Camera_SetMaximumAutoFOV, &Camera::SetMaximumAutoFOVEvent },
|
||||
{ &EV_Camera_SetAutoActive, &Camera::SetAutoActiveEvent },
|
||||
{ &EV_Camera_SetShowQuakes, &Camera::SetShowQuakes },
|
||||
CLASS_DECLARATION(Entity, Camera, "func_camera")
|
||||
{
|
||||
{ &EV_Camera_CameraThink, &Camera::CameraThink },
|
||||
{ &EV_Activate, &Camera::StartMoving },
|
||||
{ &EV_Camera_StartMoving, &Camera::StartMoving },
|
||||
{ &EV_Camera_StopMoving, &Camera::StopMoving },
|
||||
{ &EV_Camera_Pause, &Camera::Pause },
|
||||
{ &EV_Camera_Continue, &Camera::Continue },
|
||||
{ &EV_Camera_SetSpeed, &Camera::SetSpeed },
|
||||
{ &EV_Camera_SetFollowDistance, &Camera::SetFollowDistance },
|
||||
{ &EV_Camera_SetFollowYaw, &Camera::SetFollowYaw },
|
||||
{ &EV_Camera_AbsoluteYaw, &Camera::AbsoluteYaw },
|
||||
{ &EV_Camera_RelativeYaw, &Camera::RelativeYaw },
|
||||
{ &EV_Camera_SetOrbitHeight, &Camera::SetOrbitHeight },
|
||||
{ &EV_Camera_SetFOV, &Camera::SetFOV },
|
||||
{ &EV_Camera_Orbit, &Camera::OrbitEvent },
|
||||
{ &EV_Camera_Follow, &Camera::FollowEvent },
|
||||
{ &EV_Camera_Watch, &Camera::WatchEvent },
|
||||
{ &EV_Camera_WatchPath, &Camera::WatchPathEvent },
|
||||
{ &EV_Camera_WatchNodes, &Camera::WatchNodesEvent },
|
||||
{ &EV_Camera_NoWatch, &Camera::NoWatchEvent },
|
||||
{ &EV_Camera_LookAt, &Camera::LookAt },
|
||||
{ &EV_Camera_TurnTo, &Camera::TurnTo },
|
||||
{ &EV_Camera_MoveToEntity, &Camera::MoveToEntity },
|
||||
{ &EV_Camera_MoveToPos, &Camera::MoveToPos },
|
||||
{ &EV_Camera_Cut, &Camera::Cut },
|
||||
{ &EV_Camera_FadeTime, &Camera::FadeTime },
|
||||
{ &EV_Camera_SetNextCamera, &Camera::SetNextCamera },
|
||||
{ &EV_Camera_SetupCamera, &Camera::SetupCamera },
|
||||
{ &EV_SetAngles, &Camera::SetAnglesEvent },
|
||||
{ &EV_Camera_SetAutoState, &Camera::SetAutoStateEvent },
|
||||
{ &EV_Camera_SetAutoRadius, &Camera::SetAutoRadiusEvent },
|
||||
{ &EV_Camera_SetAutoStartTime, &Camera::SetAutoStartTimeEvent },
|
||||
{ &EV_Camera_SetAutoStopTime, &Camera::SetAutoStopTimeEvent },
|
||||
{ &EV_Camera_SetMaximumAutoFOV, &Camera::SetMaximumAutoFOVEvent },
|
||||
{ &EV_Camera_SetAutoActive, &Camera::SetAutoActiveEvent },
|
||||
{ &EV_Camera_WatchString, &Camera::WatchStringEvent },
|
||||
{ &EV_Camera_SetShowQuakes, &Camera::EventShowQuakes },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
@@ -1935,20 +1946,47 @@ void Camera::WatchEvent
|
||||
Event *ev
|
||||
)
|
||||
|
||||
{
|
||||
float time;
|
||||
{
|
||||
float time;
|
||||
|
||||
if ( ev->NumArgs() > 1 )
|
||||
{
|
||||
time = ev->GetFloat( 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
time = fadeTime;
|
||||
}
|
||||
if (ev->NumArgs() > 1)
|
||||
{
|
||||
time = ev->GetFloat(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
time = fadeTime;
|
||||
}
|
||||
|
||||
Watch( ev->GetString( 1 ), time );
|
||||
}
|
||||
// fixed since mohaab v2.30
|
||||
// use the entity instead
|
||||
Watch(ev->GetEntity(1), time);
|
||||
}
|
||||
|
||||
void Camera::WatchStringEvent(Event* ev) {
|
||||
float time;
|
||||
|
||||
if (ev->NumArgs() > 1)
|
||||
{
|
||||
time = ev->GetFloat(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
time = fadeTime;
|
||||
}
|
||||
|
||||
Watch(ev->GetString(1), time);
|
||||
}
|
||||
|
||||
void Camera::EventShowQuakes(Event* ev)
|
||||
{
|
||||
if (ev->NumArgs() > 0)
|
||||
{
|
||||
m_bShowquakes = ev->GetBoolean(1);
|
||||
} else {
|
||||
m_bShowquakes = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
Entity * GetWatchEntity
|
||||
(
|
||||
@@ -2174,18 +2212,6 @@ void Camera::NoWatchEvent
|
||||
newstate.watch.watchNodes = false;
|
||||
}
|
||||
|
||||
void Camera::SetShowQuakes( Event * ev )
|
||||
{
|
||||
if( ev->NumArgs() > 0 )
|
||||
{
|
||||
m_bShowquakes = ev->GetBoolean( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bShowquakes = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void SetCamera
|
||||
(
|
||||
Entity *ent,
|
||||
@@ -2604,36 +2630,36 @@ void CameraManager::UpdateUI
|
||||
//
|
||||
// set path name
|
||||
//
|
||||
gi.Cvar_Set( "cam_filename", pathName );
|
||||
gi.cvar_set( "cam_filename", pathName );
|
||||
if ( current )
|
||||
{
|
||||
|
||||
gi.Cvar_Set( "cam_origin", va( "%.2f %.2f %.2f", current->origin[ 0 ], current->origin[ 1 ], current->origin[ 2 ] ) );
|
||||
gi.Cvar_Set( "cam_angles_yaw", va( "%.1f", current->angles[ YAW ] ) );
|
||||
gi.Cvar_Set( "cam_angles_pitch", va( "%.1f", current->angles[ PITCH ] ) );
|
||||
gi.Cvar_Set( "cam_angles_roll", va( "%.1f", current->angles[ ROLL ] ) );
|
||||
gi.Cvar_Set( "cam_thread", current->thread.c_str() );
|
||||
gi.Cvar_Set( "cam_target", current->triggertarget.c_str() );
|
||||
gi.Cvar_Set( "cam_watch", current->watchEnt.c_str() );
|
||||
gi.cvar_set( "cam_origin", va( "%.2f %.2f %.2f", current->origin[ 0 ], current->origin[ 1 ], current->origin[ 2 ] ) );
|
||||
gi.cvar_set( "cam_angles_yaw", va( "%.1f", current->angles[ YAW ] ) );
|
||||
gi.cvar_set( "cam_angles_pitch", va( "%.1f", current->angles[ PITCH ] ) );
|
||||
gi.cvar_set( "cam_angles_roll", va( "%.1f", current->angles[ ROLL ] ) );
|
||||
gi.cvar_set( "cam_thread", current->thread.c_str() );
|
||||
gi.cvar_set( "cam_target", current->triggertarget.c_str() );
|
||||
gi.cvar_set( "cam_watch", current->watchEnt.c_str() );
|
||||
temp = current->GetFov();
|
||||
if ( temp )
|
||||
{
|
||||
gi.Cvar_Set( "cam_fov", va( "%.1f", temp ) );
|
||||
gi.cvar_set( "cam_fov", va( "%.1f", temp ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.Cvar_Set( "cam_fov", "Default" );
|
||||
gi.cvar_set( "cam_fov", "Default" );
|
||||
}
|
||||
temp = current->GetFadeTime();
|
||||
if ( temp != -1 )
|
||||
{
|
||||
gi.Cvar_Set( "cam_fadetime", va( "%.2f", temp ) );
|
||||
gi.cvar_set( "cam_fadetime", va( "%.2f", temp ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.Cvar_Set( "cam_fadetime", "Default" );
|
||||
gi.cvar_set( "cam_fadetime", "Default" );
|
||||
}
|
||||
gi.Cvar_Set( "cam_speed", va( "%.1f", current->speed ) );
|
||||
gi.cvar_set( "cam_speed", va( "%.1f", current->speed ) );
|
||||
|
||||
//
|
||||
// set node num
|
||||
@@ -2645,7 +2671,7 @@ void CameraManager::UpdateUI
|
||||
next = next->GetNext();
|
||||
num++;
|
||||
}
|
||||
gi.Cvar_Set( "cam_nodenum", va( "%d", num ) );
|
||||
gi.cvar_set( "cam_nodenum", va( "%d", num ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -227,7 +227,6 @@ class Camera : public Entity
|
||||
|
||||
// Miscellaneous
|
||||
Vector m_vPosOffset;
|
||||
bool m_bShowquakes;
|
||||
|
||||
protected:
|
||||
CameraState currentstate;
|
||||
@@ -242,6 +241,8 @@ class Camera : public Entity
|
||||
float followFadeTime; // time for fov transition
|
||||
float watchFadeTime; // time for fov transition
|
||||
|
||||
bool m_bShowquakes;
|
||||
|
||||
str nextCamera;
|
||||
|
||||
qboolean showcamera;
|
||||
@@ -285,9 +286,11 @@ class Camera : public Entity
|
||||
void OrbitEvent( Event *ev );
|
||||
void FollowEvent( Event *ev );
|
||||
void WatchEvent( Event *ev );
|
||||
void WatchStringEvent( Event *ev );
|
||||
void WatchPathEvent( Event *ev );
|
||||
void WatchNodesEvent( Event *ev );
|
||||
void NoWatchEvent( Event *ev );
|
||||
void NoWatchEvent(Event* ev);
|
||||
void EventShowQuakes(Event* ev);
|
||||
void LookAt( Event *ev );
|
||||
void MoveToEntity( Event *ev );
|
||||
void MoveToPos( Event *ev );
|
||||
@@ -306,7 +309,6 @@ class Camera : public Entity
|
||||
void SetAutoStopTimeEvent( Event * ev );
|
||||
void SetMaximumAutoFOVEvent( Event * ev );
|
||||
void SetAutoActiveEvent( Event * ev );
|
||||
void SetShowQuakes( Event * ev );
|
||||
|
||||
str& NextCamera( void );
|
||||
float Fov( void );
|
||||
|
||||
+800
-1014
File diff suppressed because it is too large.
Load diff
+264
-319
@@ -29,390 +29,335 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "entity.h"
|
||||
#include "script.h"
|
||||
|
||||
enum testcondition_t
|
||||
{
|
||||
TC_ISTRUE, // no prefix
|
||||
TC_ISFALSE, // !
|
||||
TC_EDGETRUE, // +
|
||||
TC_EDGEFALSE // -
|
||||
};
|
||||
|
||||
enum movecontrol_t
|
||||
{
|
||||
MOVECONTROL_NONE,
|
||||
MOVECONTROL_USER, // Quake style
|
||||
MOVECONTROL_LEGS, // Quake style, legs state system active
|
||||
MOVECONTROL_USER_MOVEANIM,
|
||||
MOVECONTROL_ANIM, // move based on animation, with full collision testing
|
||||
MOVECONTROL_ABSOLUTE, // move based on animation, with full collision testing but no turning
|
||||
MOVECONTROL_HANGING, // move based on animation, with full collision testing, hanging
|
||||
MOVECONTROL_ROPE_GRAB,
|
||||
MOVECONTROL_ROPE_RELEASE,
|
||||
MOVECONTROL_ROPE_MOVE,
|
||||
MOVECONTROL_PICKUPENEMY,
|
||||
MOVECONTROL_PUSH,
|
||||
MOVECONTROL_CLIMBWALL,
|
||||
MOVECONTROL_USEANIM,
|
||||
MOVECONTROL_CROUCH,
|
||||
MOVECONTROL_LOOPUSEANIM,
|
||||
MOVECONTROL_USEOBJECT,
|
||||
MOVECONTROL_COOLOBJECT,
|
||||
enum testcondition_t {
|
||||
TC_ISTRUE, // no prefix
|
||||
TC_ISFALSE, // !
|
||||
TC_EDGETRUE, // +
|
||||
TC_EDGEFALSE // -
|
||||
};
|
||||
|
||||
enum cameratype_t
|
||||
{
|
||||
CAMERA_TOPDOWN,
|
||||
CAMERA_BEHIND,
|
||||
CAMERA_FRONT,
|
||||
CAMERA_SIDE,
|
||||
CAMERA_BEHIND_FIXED,
|
||||
CAMERA_SIDE_LEFT,
|
||||
CAMERA_SIDE_RIGHT,
|
||||
CAMERA_BEHIND_NOPITCH
|
||||
enum movecontrol_t {
|
||||
MOVECONTROL_NONE,
|
||||
MOVECONTROL_USER, // Quake style
|
||||
MOVECONTROL_LEGS, // Quake style, legs state system active
|
||||
MOVECONTROL_USER_MOVEANIM,
|
||||
MOVECONTROL_ANIM, // move based on animation, with full collision testing
|
||||
MOVECONTROL_ABSOLUTE, // move based on animation, with full collision testing but no turning
|
||||
MOVECONTROL_HANGING, // move based on animation, with full collision testing, hanging
|
||||
MOVECONTROL_ROPE_GRAB,
|
||||
MOVECONTROL_ROPE_RELEASE,
|
||||
MOVECONTROL_ROPE_MOVE,
|
||||
MOVECONTROL_PICKUPENEMY,
|
||||
MOVECONTROL_PUSH,
|
||||
MOVECONTROL_CLIMBWALL,
|
||||
MOVECONTROL_USEANIM,
|
||||
MOVECONTROL_CROUCH,
|
||||
MOVECONTROL_LOOPUSEANIM,
|
||||
MOVECONTROL_USEOBJECT,
|
||||
MOVECONTROL_COOLOBJECT,
|
||||
};
|
||||
|
||||
#define DEFAULT_MOVETYPE MOVECONTROL_NONE
|
||||
#define DEFAULT_CAMERA CAMERA_BEHIND
|
||||
enum cameratype_t {
|
||||
CAMERA_TOPDOWN,
|
||||
CAMERA_BEHIND,
|
||||
CAMERA_FRONT,
|
||||
CAMERA_SIDE,
|
||||
CAMERA_BEHIND_FIXED,
|
||||
CAMERA_SIDE_LEFT,
|
||||
CAMERA_SIDE_RIGHT,
|
||||
CAMERA_BEHIND_NOPITCH
|
||||
};
|
||||
|
||||
#define DEFAULT_MOVETYPE MOVECONTROL_NONE
|
||||
#define DEFAULT_CAMERA CAMERA_BEHIND
|
||||
|
||||
class Conditional;
|
||||
|
||||
template< class Type >
|
||||
struct Condition
|
||||
{
|
||||
const char *name;
|
||||
qboolean ( Type::*func )( Conditional &condition );
|
||||
};
|
||||
template<class Type>
|
||||
struct Condition {
|
||||
const char *name;
|
||||
qboolean (Type::*func)(Conditional& condition);
|
||||
};
|
||||
|
||||
class Conditional : public Class
|
||||
{
|
||||
private :
|
||||
qboolean result;
|
||||
qboolean previous_result;
|
||||
bool checked;
|
||||
|
||||
public :
|
||||
CLASS_PROTOTYPE( Conditional );
|
||||
|
||||
Condition<Class> condition;
|
||||
Container<str> parmList;
|
||||
|
||||
bool getResult( testcondition_t test, Entity &ent );
|
||||
const char *getName( void );
|
||||
|
||||
Conditional( Condition<Class> &condition );
|
||||
Conditional();
|
||||
|
||||
const char *getParm( int number );
|
||||
void addParm( str parm );
|
||||
int numParms( void );
|
||||
void clearCheck( void );
|
||||
void clearPrevious( void );
|
||||
};
|
||||
|
||||
inline void Conditional::addParm
|
||||
(
|
||||
str parm
|
||||
)
|
||||
|
||||
{
|
||||
parmList.AddObject( parm );
|
||||
}
|
||||
|
||||
inline const char *Conditional::getParm
|
||||
(
|
||||
int number
|
||||
)
|
||||
|
||||
{
|
||||
if ( ( number < 1 ) || ( number > parmList.NumObjects() ) )
|
||||
{
|
||||
gi.Error( ERR_DROP, "Parm #%d out of range on %s condition\n", number, condition.name );
|
||||
}
|
||||
return parmList.ObjectAt( number ).c_str();
|
||||
}
|
||||
|
||||
inline int Conditional::numParms
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
return parmList.NumObjects();
|
||||
}
|
||||
|
||||
inline void Conditional::clearCheck
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
checked = false;
|
||||
}
|
||||
|
||||
inline void Conditional::clearPrevious
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
previous_result = 0;
|
||||
}
|
||||
|
||||
inline const char *Conditional::getName
|
||||
(
|
||||
void
|
||||
)
|
||||
|
||||
{
|
||||
return condition.name;
|
||||
}
|
||||
|
||||
inline bool Conditional::getResult
|
||||
(
|
||||
testcondition_t test,
|
||||
Entity &ent
|
||||
)
|
||||
{
|
||||
if ( condition.func && !checked )
|
||||
{
|
||||
checked = true;
|
||||
previous_result = result;
|
||||
|
||||
result = ( ent.*condition.func )( *this );
|
||||
}
|
||||
private:
|
||||
qboolean result;
|
||||
qboolean previous_result;
|
||||
bool checked;
|
||||
|
||||
switch( test )
|
||||
{
|
||||
case TC_ISFALSE :
|
||||
return !result;
|
||||
public:
|
||||
CLASS_PROTOTYPE(Conditional);
|
||||
|
||||
case TC_EDGETRUE:
|
||||
return result && !previous_result;
|
||||
Condition<Class> condition;
|
||||
Container<str> parmList;
|
||||
|
||||
case TC_EDGEFALSE:
|
||||
return !result && previous_result;
|
||||
bool getResult(testcondition_t test, Entity &ent);
|
||||
const char *getName(void);
|
||||
|
||||
case TC_ISTRUE :
|
||||
default:
|
||||
return result != false;
|
||||
}
|
||||
Conditional(Condition<Class>& condition);
|
||||
Conditional();
|
||||
|
||||
const char *getParm(int number);
|
||||
void addParm(str parm);
|
||||
int numParms(void);
|
||||
void clearCheck(void);
|
||||
void clearPrevious(void);
|
||||
};
|
||||
|
||||
inline void Conditional::addParm(str parm)
|
||||
|
||||
{
|
||||
parmList.AddObject(parm);
|
||||
}
|
||||
|
||||
inline const char *Conditional::getParm(int number)
|
||||
|
||||
{
|
||||
if ((number < 1) || (number > parmList.NumObjects())) {
|
||||
gi.Error(ERR_DROP, "Parm #%d out of range on %s condition\n", number, condition.name);
|
||||
}
|
||||
return parmList.ObjectAt(number).c_str();
|
||||
}
|
||||
|
||||
inline int Conditional::numParms(void)
|
||||
|
||||
{
|
||||
return parmList.NumObjects();
|
||||
}
|
||||
|
||||
inline void Conditional::clearCheck(void)
|
||||
|
||||
{
|
||||
checked = false;
|
||||
}
|
||||
|
||||
inline void Conditional::clearPrevious(void)
|
||||
|
||||
{
|
||||
previous_result = 0;
|
||||
}
|
||||
|
||||
inline const char *Conditional::getName(void)
|
||||
|
||||
{
|
||||
return condition.name;
|
||||
}
|
||||
|
||||
inline bool Conditional::getResult(testcondition_t test, Entity& ent)
|
||||
{
|
||||
if (condition.func && !checked) {
|
||||
checked = true;
|
||||
previous_result = result;
|
||||
|
||||
result = (ent.*condition.func)(*this);
|
||||
}
|
||||
|
||||
switch (test) {
|
||||
case TC_ISFALSE:
|
||||
return !result;
|
||||
|
||||
case TC_EDGETRUE:
|
||||
return result && !previous_result;
|
||||
|
||||
case TC_EDGEFALSE:
|
||||
return !result && previous_result;
|
||||
|
||||
case TC_ISTRUE:
|
||||
default:
|
||||
return result != false;
|
||||
}
|
||||
}
|
||||
|
||||
class State;
|
||||
class StateMap;
|
||||
|
||||
class Expression : public Class
|
||||
{
|
||||
private :
|
||||
struct condition_t
|
||||
{
|
||||
testcondition_t test;
|
||||
int condition_index;
|
||||
};
|
||||
{
|
||||
private:
|
||||
struct condition_t {
|
||||
testcondition_t test;
|
||||
int condition_index;
|
||||
};
|
||||
|
||||
str value;
|
||||
Container<condition_t> conditions;
|
||||
str value;
|
||||
Container<condition_t> conditions;
|
||||
|
||||
public :
|
||||
Expression();
|
||||
Expression( Expression &exp );
|
||||
Expression( Script &script, State &state );
|
||||
public:
|
||||
Expression();
|
||||
Expression(Expression& exp);
|
||||
Expression(Script& script, State& state);
|
||||
|
||||
void operator=( const Expression &exp );
|
||||
void operator=(const Expression& exp);
|
||||
|
||||
bool getResult( State &state, Entity &ent, Container<Conditional *> *sent_conditionals );
|
||||
const char *getValue( void );
|
||||
};
|
||||
bool getResult(State &state, Entity &ent, Container<Conditional *> *sent_conditionals);
|
||||
const char *getValue(void);
|
||||
};
|
||||
|
||||
inline void Expression::operator=
|
||||
(
|
||||
const Expression &exp
|
||||
)
|
||||
|
||||
{
|
||||
int i;
|
||||
inline void Expression::operator=(const Expression& exp)
|
||||
|
||||
value = exp.value;
|
||||
{
|
||||
int i;
|
||||
|
||||
conditions.FreeObjectList();
|
||||
for( i = 1; i <= exp.conditions.NumObjects(); i++ )
|
||||
{
|
||||
conditions.AddObject( exp.conditions.ObjectAt( i ) );
|
||||
}
|
||||
}
|
||||
value = exp.value;
|
||||
|
||||
inline const char *Expression::getValue
|
||||
(
|
||||
void
|
||||
)
|
||||
conditions.FreeObjectList();
|
||||
for (i = 1; i <= exp.conditions.NumObjects(); i++) {
|
||||
conditions.AddObject(exp.conditions.ObjectAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
return value.c_str();
|
||||
}
|
||||
inline const char *Expression::getValue(void)
|
||||
|
||||
{
|
||||
return value.c_str();
|
||||
}
|
||||
|
||||
class State : public Class
|
||||
{
|
||||
private :
|
||||
Container<int> condition_indexes;
|
||||
{
|
||||
private:
|
||||
Container<int> condition_indexes;
|
||||
|
||||
StateMap &statemap;
|
||||
StateMap& statemap;
|
||||
|
||||
str name;
|
||||
str name;
|
||||
|
||||
str nextState;
|
||||
movecontrol_t movetype;
|
||||
cameratype_t cameratype;
|
||||
str nextState;
|
||||
movecontrol_t movetype;
|
||||
cameratype_t cameratype;
|
||||
|
||||
str behaviorName;
|
||||
Container<str> behaviorParmList;
|
||||
str behaviorName;
|
||||
Container<str> behaviorParmList;
|
||||
|
||||
float minTime;
|
||||
float maxTime;
|
||||
float minTime;
|
||||
float maxTime;
|
||||
|
||||
Container<Expression> legAnims;
|
||||
Container<Expression> m_actionAnims;
|
||||
int m_iActionAnimType;
|
||||
Container<Expression> legAnims;
|
||||
Container<Expression> m_actionAnims;
|
||||
int m_iActionAnimType;
|
||||
|
||||
Container<Expression> states;
|
||||
Container<str> entryCommands;
|
||||
Container<str> exitCommands;
|
||||
Container<Expression> states;
|
||||
Container<str> entryCommands;
|
||||
Container<str> exitCommands;
|
||||
|
||||
void readNextState( Script &script );
|
||||
void readMoveType( Script &script );
|
||||
void readCamera( Script &script );
|
||||
void readLegs( Script &script );
|
||||
void readAction( Script &script );
|
||||
void readBehavior( Script &script );
|
||||
void readTime( Script &script );
|
||||
void readStates( Script &script );
|
||||
void readCommands( Script &script, Container<str> &container );
|
||||
void readNextState(Script& script);
|
||||
void readMoveType(Script& script);
|
||||
void readCamera(Script& script);
|
||||
void readLegs(Script& script);
|
||||
void readAction(Script& script);
|
||||
void readBehavior(Script& script);
|
||||
void readTime(Script& script);
|
||||
void readStates(Script& script);
|
||||
void readCommands(Script& script, Container<str>& container);
|
||||
|
||||
void ParseAndProcessCommand( str command, Entity *target );
|
||||
void ParseAndProcessCommand(str command, Entity *target);
|
||||
|
||||
public :
|
||||
State( const char *name, Script &script, StateMap &map );
|
||||
public:
|
||||
State(const char *name, Script& script, StateMap& map);
|
||||
|
||||
State *Evaluate( Entity &ent, Container<Conditional *> *ent_conditionals );
|
||||
int addCondition( const char *name, Script &script );
|
||||
void CheckStates( void );
|
||||
State *Evaluate(Entity& ent, Container<Conditional *> *ent_conditionals);
|
||||
int addCondition(const char *name, Script &script);
|
||||
void CheckStates(void);
|
||||
|
||||
const char *getName( void );
|
||||
const char *getName(void);
|
||||
|
||||
const char *getLegAnim( Entity &ent, Container<Conditional *> *sent_conditionals );
|
||||
const char *getActionAnim( Entity &ent, Container<Conditional *> *sent_conditionals, int *piAnimType = NULL );
|
||||
const char *getBehaviorName( void );
|
||||
State *getNextState( void );
|
||||
movecontrol_t getMoveType( void );
|
||||
cameratype_t getCameraType( void );
|
||||
qboolean setCameraType( str ctype );
|
||||
const char *getLegAnim(Entity &ent, Container<Conditional *> *sent_conditionals);
|
||||
const char *getActionAnim(Entity &ent, Container<Conditional *> *sent_conditionals, int *piAnimType = NULL);
|
||||
const char *getBehaviorName(void);
|
||||
State *getNextState(void);
|
||||
movecontrol_t getMoveType(void);
|
||||
cameratype_t getCameraType(void);
|
||||
qboolean setCameraType(str ctype);
|
||||
|
||||
const char *getBehaviorParm( int number=1 );
|
||||
void addBehaviorParm( str parm );
|
||||
int numBehaviorParms( void );
|
||||
const char *getBehaviorParm(int number = 1);
|
||||
void addBehaviorParm(str parm);
|
||||
int numBehaviorParms(void);
|
||||
|
||||
float getMinTime( void );
|
||||
float getMaxTime( void );
|
||||
void ProcessEntryCommands( Entity *target );
|
||||
void ProcessExitCommands( Entity *target );
|
||||
void GetLegAnims( Container<const char *> *c );
|
||||
void GetActionAnims( Container<const char *> *c );
|
||||
};
|
||||
float getMinTime(void);
|
||||
float getMaxTime(void);
|
||||
void ProcessEntryCommands(Entity *target);
|
||||
void ProcessExitCommands(Entity *target);
|
||||
void GetLegAnims(Container<const char *> *c);
|
||||
void GetActionAnims(Container<const char *> *c);
|
||||
};
|
||||
|
||||
inline void State::addBehaviorParm
|
||||
(
|
||||
str parm
|
||||
)
|
||||
inline void State::addBehaviorParm(str parm)
|
||||
|
||||
{
|
||||
behaviorParmList.AddObject( parm );
|
||||
}
|
||||
{
|
||||
behaviorParmList.AddObject(parm);
|
||||
}
|
||||
|
||||
inline const char *State::getBehaviorParm
|
||||
(
|
||||
int number
|
||||
)
|
||||
inline const char *State::getBehaviorParm(int number)
|
||||
|
||||
{
|
||||
return behaviorParmList.ObjectAt( number ).c_str();
|
||||
}
|
||||
{
|
||||
return behaviorParmList.ObjectAt(number).c_str();
|
||||
}
|
||||
|
||||
inline int State::numBehaviorParms
|
||||
(
|
||||
void
|
||||
)
|
||||
inline int State::numBehaviorParms(void)
|
||||
|
||||
{
|
||||
return behaviorParmList.NumObjects();
|
||||
}
|
||||
{
|
||||
return behaviorParmList.NumObjects();
|
||||
}
|
||||
|
||||
class StateMap : public Class
|
||||
{
|
||||
private :
|
||||
Container<State *> stateList;
|
||||
Condition<Class> *current_conditions;
|
||||
Container<Conditional *> *current_conditionals;
|
||||
str filename;
|
||||
|
||||
public :
|
||||
StateMap( const char *filename, Condition<Class> *conditions, Container<Conditional *> *conditionals );
|
||||
~StateMap();
|
||||
{
|
||||
private:
|
||||
Container<State *> stateList;
|
||||
Condition<Class> *current_conditions;
|
||||
Container<Conditional *> *current_conditionals;
|
||||
str filename;
|
||||
|
||||
Condition<Class> *getCondition( const char *name );
|
||||
int findConditional( Conditional *condition );
|
||||
int addConditional( Conditional *condition );
|
||||
Conditional *getConditional( const char *name );
|
||||
void GetAllAnims( Container<const char *> *c );
|
||||
State *FindState( const char *name );
|
||||
const char *Filename();
|
||||
};
|
||||
public:
|
||||
StateMap(const char *filename, Condition<Class> *conditions, Container<Conditional *> *conditionals);
|
||||
~StateMap();
|
||||
|
||||
inline const char *StateMap::Filename
|
||||
(
|
||||
void
|
||||
)
|
||||
Condition<Class> *getCondition(const char *name);
|
||||
int findConditional(Conditional *condition);
|
||||
int addConditional(Conditional *condition);
|
||||
Conditional *getConditional(const char *name);
|
||||
void GetAllAnims(Container<const char *> *c);
|
||||
State *FindState(const char *name);
|
||||
const char *Filename();
|
||||
};
|
||||
|
||||
{
|
||||
return filename.c_str();
|
||||
}
|
||||
inline const char *StateMap::Filename(void)
|
||||
|
||||
inline const char *State::getName
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return filename.c_str();
|
||||
}
|
||||
|
||||
{
|
||||
return name.c_str();
|
||||
}
|
||||
inline const char *State::getName(void)
|
||||
|
||||
inline State *State::getNextState
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return name.c_str();
|
||||
}
|
||||
|
||||
{
|
||||
return statemap.FindState( nextState.c_str() );
|
||||
}
|
||||
inline State *State::getNextState(void)
|
||||
|
||||
inline movecontrol_t State::getMoveType
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return statemap.FindState(nextState.c_str());
|
||||
}
|
||||
|
||||
{
|
||||
return movetype;
|
||||
}
|
||||
inline movecontrol_t State::getMoveType(void)
|
||||
|
||||
inline cameratype_t State::getCameraType
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return movetype;
|
||||
}
|
||||
|
||||
{
|
||||
return cameratype;
|
||||
}
|
||||
inline cameratype_t State::getCameraType(void)
|
||||
|
||||
void ClearCachedStatemaps( void );
|
||||
StateMap *GetStatemap( str filename, Condition<Class> *conditions, Container<Conditional *> *conditionals, qboolean reload, qboolean cache_only = false );
|
||||
void CacheStatemap( str filename, Condition<Class> *conditions );
|
||||
{
|
||||
return cameratype;
|
||||
}
|
||||
|
||||
void ClearCachedStatemaps(void);
|
||||
StateMap *GetStatemap(
|
||||
str filename,
|
||||
Condition<Class> *conditions,
|
||||
Container<Conditional *> *conditionals,
|
||||
qboolean reload,
|
||||
qboolean cache_only = false
|
||||
);
|
||||
void CacheStatemap(str filename, Condition<Class> *conditions);
|
||||
|
||||
#endif /* !__CHARACTERSTATE_H__ */
|
||||
@@ -57,7 +57,7 @@ void ConsoleEvent::SetConsoleEdict(gentity_t* edict)
|
||||
GetConsoleEdict
|
||||
=======================
|
||||
*/
|
||||
gentity_t* ConsoleEvent::GetConsoleEdict(void)
|
||||
gentity_t* ConsoleEvent::GetConsoleEdict(void) const
|
||||
{
|
||||
if (m_consoleedict)
|
||||
return m_consoleedict;
|
||||
@@ -70,7 +70,7 @@ gentity_t* ConsoleEvent::GetConsoleEdict(void)
|
||||
ErrorInternal
|
||||
=======================
|
||||
*/
|
||||
void ConsoleEvent::ErrorInternal(Listener* l, str text)
|
||||
void ConsoleEvent::ErrorInternal(Listener* l, str text) const
|
||||
{
|
||||
gentity_t* edict = GetConsoleEdict();
|
||||
str eventname = getName();
|
||||
|
||||
@@ -19,9 +19,9 @@ public:
|
||||
ConsoleEvent(str name) : Event(name) { m_consoleedict = NULL; }
|
||||
|
||||
void SetConsoleEdict(gentity_t* edict);
|
||||
gentity_t* GetConsoleEdict(void);
|
||||
gentity_t* GetConsoleEdict(void) const;
|
||||
|
||||
void ErrorInternal(Listener* l, str text) override;
|
||||
void ErrorInternal(Listener* l, str text) const override;
|
||||
};
|
||||
|
||||
extern MEM_BlockAlloc<ConsoleEvent> ConsoleEvent_allocator;
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "damagemodel.h"
|
||||
|
||||
// FIXME: unimplemented
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -865,3 +865,36 @@ void G_DebugHighlightFacet
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void G_DebugString(Vector pos, float scale, float r, float g, float b, const char* pszText, ...)
|
||||
{
|
||||
debugstring_t* string;
|
||||
va_list va;
|
||||
char szTemp[32768];
|
||||
|
||||
if (!g_numdebugstrings) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (*gi.numDebugStrings < g_numdebugstrings->integer) {
|
||||
string = (debugstring_t*)&DebugStrings[*gi.numDebugStrings];
|
||||
|
||||
(*gi.numDebugStrings)++;
|
||||
|
||||
va_start(va, pszText);
|
||||
vsprintf(szTemp, pszText, va);
|
||||
va_end(va);
|
||||
|
||||
VectorCopy(pos, string->pos);
|
||||
string->scale = scale;
|
||||
string->color[0] = r;
|
||||
string->color[1] = g;
|
||||
string->color[2] = b;
|
||||
string->color[3] = 1.0f;
|
||||
strncpy(string->szText, szTemp, sizeof(string->szText));
|
||||
string->szText[sizeof(string->szText) - 1] = 0;
|
||||
}
|
||||
else {
|
||||
gi.DPrintf("G_DebugString: Exceeded g_numdebugstrings\n");
|
||||
}
|
||||
}
|
||||
+1765
-1085
File diff suppressed because it is too large.
Load diff
+231
-102
@@ -21,149 +21,278 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
// dm_manager.h: Deathmatch Manager.
|
||||
|
||||
#ifndef __DM_MANAGER_H__
|
||||
#define __DM_MANAGER_H__
|
||||
#pragma once
|
||||
|
||||
#include "listener.h"
|
||||
#include "dm_team.h"
|
||||
#include "Tow_Entities.h"
|
||||
|
||||
extern cvar_t *g_tempaxisscore;
|
||||
extern cvar_t *g_tempaxiswinsinrow;
|
||||
extern cvar_t *g_tempalliesscore;
|
||||
extern cvar_t *g_tempallieswinsinrow;
|
||||
|
||||
class PlayerStart;
|
||||
class Player;
|
||||
|
||||
class DM_Team : public Listener
|
||||
{
|
||||
public:
|
||||
Container<PlayerStart *> m_spawnpoints;
|
||||
Container<Player *> m_players;
|
||||
int m_maxplayers;
|
||||
|
||||
str m_teamname;
|
||||
int m_teamnumber;
|
||||
int m_index;
|
||||
|
||||
int m_countdown;
|
||||
int m_teamwins;
|
||||
int m_wins_in_a_row;
|
||||
|
||||
int m_iKills;
|
||||
int m_iDeaths;
|
||||
|
||||
qboolean m_bHasSpawnedPlayers;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE(DM_Team);
|
||||
|
||||
DM_Team();
|
||||
~DM_Team();
|
||||
|
||||
void Reset(void);
|
||||
|
||||
void AddPlayer(Player *player);
|
||||
void RemovePlayer(Player *player);
|
||||
|
||||
void setName(str name);
|
||||
str getName(void);
|
||||
void setNumber(int num);
|
||||
int getNumber(void);
|
||||
void setIndex(int index);
|
||||
int getIndex(void);
|
||||
|
||||
void TeamWin(void);
|
||||
void TeamLoss(void);
|
||||
void AddDeaths(Player *player, int numDeaths);
|
||||
void AddKills(Player *player, int numKills);
|
||||
void UpdateTeamStatus(void);
|
||||
|
||||
void TeamInvulnerable(void);
|
||||
void BeginFight(void);
|
||||
|
||||
float PlayersRangeFromSpot(PlayerStart *spot);
|
||||
|
||||
bool IsDead(void) const;
|
||||
bool IsEmpty(void) const;
|
||||
bool IsReady(void) const;
|
||||
|
||||
int NumNotReady(void) const;
|
||||
int NumLivePlayers(void) const;
|
||||
int TotalPlayersKills(void) const;
|
||||
|
||||
PlayerStart *GetRandomFfaSpawnpoint(Player *player);
|
||||
PlayerStart *GetRandomTeamSpawnpoint(Player *player);
|
||||
PlayerStart *GetRandomObjectiveSpawnpoint(Player *player);
|
||||
|
||||
void InitSpawnPoints(void);
|
||||
|
||||
protected:
|
||||
PlayerStart *FarthestSpawnPoint(void);
|
||||
PlayerStart *GetRandomSpawnpoint(void);
|
||||
PlayerStart *GetRandomSpawnpointWithMetric(
|
||||
Player *player, float (*MetricFunction)(const float *, DM_Team *dmTeam, const Player *player)
|
||||
);
|
||||
};
|
||||
|
||||
using DM_TeamPtr = SafePtr<DM_Team>;
|
||||
|
||||
inline void DM_Team::setName(str name)
|
||||
{
|
||||
m_teamname = name;
|
||||
};
|
||||
|
||||
inline str DM_Team::getName(void)
|
||||
{
|
||||
return m_teamname;
|
||||
};
|
||||
|
||||
inline void DM_Team::setNumber(int num)
|
||||
{
|
||||
m_teamnumber = num;
|
||||
}
|
||||
|
||||
inline int DM_Team::getNumber(void)
|
||||
{
|
||||
return m_teamnumber;
|
||||
}
|
||||
|
||||
inline void DM_Team::setIndex(int index)
|
||||
{
|
||||
m_index = index;
|
||||
}
|
||||
|
||||
inline int DM_Team::getIndex(void)
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
inline bool DM_Team::IsReady(void) const
|
||||
{
|
||||
return !NumNotReady();
|
||||
}
|
||||
|
||||
class SimpleAmmoType : public Class
|
||||
{
|
||||
public:
|
||||
str type;
|
||||
int amount;
|
||||
|
||||
public:
|
||||
SimpleAmmoType();
|
||||
};
|
||||
|
||||
class Player;
|
||||
|
||||
class DM_Manager : public Listener
|
||||
{
|
||||
private:
|
||||
Container< Player * > m_players;
|
||||
Container< DM_TeamPtr > m_teams;
|
||||
Container<Player *> m_players;
|
||||
Container<DM_TeamPtr> m_teams;
|
||||
|
||||
DM_Team m_team_spectator;
|
||||
DM_Team m_team_freeforall;
|
||||
DM_Team m_team_allies;
|
||||
DM_Team m_team_axis;
|
||||
DM_Team m_team_spectator;
|
||||
DM_Team m_team_freeforall;
|
||||
DM_Team m_team_allies;
|
||||
DM_Team m_team_axis;
|
||||
|
||||
float m_fRoundTime;
|
||||
float m_fRoundEndTime;
|
||||
float m_fRoundTime;
|
||||
float m_fRoundEndTime;
|
||||
|
||||
bool m_bAllowRespawns;
|
||||
bool m_bRoundBasedGame;
|
||||
int m_iDefaultRoundLimit;
|
||||
bool m_bAllowRespawns;
|
||||
bool m_bRoundBasedGame;
|
||||
bool m_bIgnoringClockForBomb;
|
||||
int m_iTeamWin;
|
||||
int m_iDefaultRoundLimit;
|
||||
|
||||
const_str m_csTeamClockSide;
|
||||
const_str m_csTeamBombPlantSide;
|
||||
const_str m_csTeamClockSide;
|
||||
const_str m_csTeamBombPlantSide;
|
||||
|
||||
int m_iNumTargetsToDestroy;
|
||||
int m_iNumTargetsDestroyed;
|
||||
int m_iNumBombsPlanted;
|
||||
int m_iTotalMapTime;
|
||||
int m_iNumTargetsToDestroy;
|
||||
int m_iNumTargetsDestroyed;
|
||||
int m_iNumBombsPlanted;
|
||||
int m_iTotalMapTime;
|
||||
|
||||
int m_iTeamWin;
|
||||
bool m_bIgnoringClockForBomb;
|
||||
bool m_bAllowAxisRespawn;
|
||||
bool m_bAllowAlliedRespawn;
|
||||
|
||||
// scoreboard data
|
||||
char scoreString[ MAX_STRING_CHARS ];
|
||||
size_t scoreLength;
|
||||
int scoreEntries;
|
||||
// scoreboard data
|
||||
char scoreString[MAX_STRING_CHARS];
|
||||
size_t scoreLength;
|
||||
int scoreEntries;
|
||||
|
||||
private:
|
||||
void BuildTeamInfo( DM_Team *dmTeam );
|
||||
void BuildPlayerTeamInfo( DM_Team *dmTeam, int *iPlayerList, DM_Team *ignoreTeam = NULL );
|
||||
void InsertEntry( const char *entry );
|
||||
void InsertEmpty( void );
|
||||
void BuildTeamInfo(DM_Team *dmTeam);
|
||||
void BuildTeamInfo_ver6(DM_Team *dmTeam);
|
||||
void BuildTeamInfo_ver15(DM_Team *dmTeam);
|
||||
void BuildPlayerTeamInfo(DM_Team *dmTeam, int *iPlayerList, DM_Team *ignoreTeam = NULL);
|
||||
void InsertEntry(const char *entry);
|
||||
void InsertEntryNoCount(const char *entry);
|
||||
void InsertEmpty(void);
|
||||
bool IsAlivePlayer(Player* player) const;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( DM_Manager );
|
||||
CLASS_PROTOTYPE(DM_Manager);
|
||||
|
||||
DM_Manager();
|
||||
~DM_Manager();
|
||||
DM_Manager();
|
||||
~DM_Manager();
|
||||
|
||||
void Reset( void );
|
||||
void InitGame(void);
|
||||
void AddPlayer(Player *player);
|
||||
bool JoinTeam(Player *player, teamtype_t teamType);
|
||||
void LeaveTeam(Player *player);
|
||||
void RebuildTeamConfigstrings(void);
|
||||
void RemovePlayer(Player *player);
|
||||
void PlayerKilled(Player *player);
|
||||
|
||||
DM_Team *GetTeam( str name );
|
||||
DM_Team *GetTeam( teamtype_t team );
|
||||
void Countdown(Event *ev);
|
||||
void Reset(void);
|
||||
void Score(Player *player);
|
||||
|
||||
bool JoinTeam( Player *player, teamtype_t teamType );
|
||||
void LeaveTeam( Player *player );
|
||||
void PrintAllClients(str s);
|
||||
bool CheckEndMatch(void);
|
||||
bool TeamHitScoreLimit(void);
|
||||
bool PlayerHitScoreLimit(void);
|
||||
void EventDoRoundTransition(Event *ev);
|
||||
void EventFinishRoundTransition(Event *ev);
|
||||
void TeamWin(int teamnum);
|
||||
void StartRound(void);
|
||||
void EndRound(void);
|
||||
bool GameHasRounds(void) const;
|
||||
bool GameAllowsRespawns(void) const;
|
||||
void SetGameAllowsRespawns(bool bAllow);
|
||||
bool AllowRespawn(void) const;
|
||||
int GetRoundLimit(void) const;
|
||||
void SetDefaultRoundLimit(int round_limit);
|
||||
const_str GetClockSide(void) const;
|
||||
void SetClockSide(const_str s);
|
||||
const_str GetBombPlantTeam(void) const;
|
||||
void SetBombPlantTeam(const_str s);
|
||||
int GetTargetsToDestroy(void) const;
|
||||
void SetTargetsToDestroy(int);
|
||||
int GetTargetsDestroyed(void) const;
|
||||
void SetTargetsDestroyed(int);
|
||||
int GetBombsPlanted(void) const;
|
||||
void SetBombsPlanted(int);
|
||||
int GetTeamWin(void);
|
||||
bool WaitingForPlayers(void) const;
|
||||
bool IsGameActive(void) const;
|
||||
int PlayerCount(void) const;
|
||||
Player *GetPlayer(int index) const;
|
||||
teamtype_t GetAutoJoinTeam(void);
|
||||
|
||||
Player *GetPlayer( int num );
|
||||
void InitGame( void );
|
||||
DM_Team *GetTeamAllies(void);
|
||||
DM_Team *GetTeamAxis(void);
|
||||
|
||||
void AddPlayer( Player *player );
|
||||
void RemovePlayer( Player *player );
|
||||
void PlayerKilled( Player *player );
|
||||
float GetMatchStartTime(void);
|
||||
void StopTeamRespawn(eController controller);
|
||||
bool AllowTeamRespawn(int teamnum) const;
|
||||
int GetTeamSpawnTimeLeft() const;
|
||||
|
||||
void RebuildTeamConfigstrings( void );
|
||||
DM_Team *GetTeam(str name);
|
||||
DM_Team *GetTeam(teamtype_t team);
|
||||
|
||||
static int compareScores( const void *elem1, const void *elem2 );
|
||||
void Score( Player *player );
|
||||
|
||||
void PrintAllClients( str s );
|
||||
bool CheckEndMatch( void );
|
||||
bool TeamHitScoreLimit( void );
|
||||
bool PlayerHitScoreLimit( void );
|
||||
void EventDoRoundTransition( Event *ev );
|
||||
void EventFinishRoundTransition( Event *ev );
|
||||
void TeamWin( int teamnum );
|
||||
void StartRound( void );
|
||||
void EndRound( void );
|
||||
bool GameHasRounds( void ) const;
|
||||
bool GameAllowsRespawns( void ) const;
|
||||
void SetGameAllowsRespawns( bool bAllow );
|
||||
bool AllowRespawn( void ) const;
|
||||
int GetRoundLimit( void ) const;
|
||||
void SetDefaultRoundLimit( int round_limit );
|
||||
const_str GetClockSide( void ) const;
|
||||
void SetClockSide( const_str s );
|
||||
const_str GetBombPlantTeam( void ) const;
|
||||
void SetBombPlantTeam( const_str s );
|
||||
int GetTargetsToDestroy( void ) const;
|
||||
void SetTargetsToDestroy( int );
|
||||
int GetTargetsDestroyed( void ) const;
|
||||
void SetTargetsDestroyed( int );
|
||||
int GetBombsPlanted( void ) const;
|
||||
void SetBombsPlanted( int );
|
||||
int GetTeamWin( void );
|
||||
bool WaitingForPlayers( void ) const;
|
||||
bool IsGameActive( void ) const;
|
||||
int PlayerCount( void ) const;
|
||||
teamtype_t GetAutoJoinTeam( void );
|
||||
DM_Team *GetTeamAllies( void );
|
||||
DM_Team *GetTeamAxis( void );
|
||||
float GetMatchStartTime( void );
|
||||
protected:
|
||||
static int compareScores(const void *elem1, const void *elem2);
|
||||
};
|
||||
|
||||
inline
|
||||
bool DM_Manager::GameHasRounds
|
||||
(
|
||||
void
|
||||
)
|
||||
const
|
||||
inline int DM_Manager::GetTeamWin(void)
|
||||
{
|
||||
return m_bRoundBasedGame;
|
||||
return m_iTeamWin;
|
||||
}
|
||||
|
||||
inline
|
||||
bool DM_Manager::GameAllowsRespawns
|
||||
(
|
||||
void
|
||||
)
|
||||
const
|
||||
inline DM_Team *DM_Manager::GetTeamAllies(void)
|
||||
{
|
||||
return m_bAllowRespawns;
|
||||
return &m_team_allies;
|
||||
}
|
||||
|
||||
inline
|
||||
void DM_Manager::SetGameAllowsRespawns
|
||||
(
|
||||
bool bAllow
|
||||
)
|
||||
inline DM_Team *DM_Manager::GetTeamAxis(void)
|
||||
{
|
||||
m_bAllowRespawns = bAllow;
|
||||
return &m_team_axis;
|
||||
}
|
||||
|
||||
inline bool DM_Manager::GameHasRounds(void) const
|
||||
{
|
||||
return m_bRoundBasedGame;
|
||||
}
|
||||
|
||||
inline bool DM_Manager::GameAllowsRespawns(void) const
|
||||
{
|
||||
return m_bAllowRespawns;
|
||||
}
|
||||
|
||||
inline void DM_Manager::SetGameAllowsRespawns(bool bAllow)
|
||||
{
|
||||
m_bAllowRespawns = bAllow;
|
||||
}
|
||||
|
||||
extern DM_Manager dmManager;
|
||||
|
||||
#endif /* __DM_MANAGER_H__ */
|
||||
@@ -1,764 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// dm_team.cpp: Deathmatch Team Manager.
|
||||
|
||||
#include "player.h"
|
||||
#include "dm_team.h"
|
||||
#include "dm_manager.h"
|
||||
#include "playerstart.h"
|
||||
|
||||
typedef struct spawnsort_s {
|
||||
PlayerStart *spawnpoint;
|
||||
float fMetric;
|
||||
} spawnsort_t;
|
||||
|
||||
static qboolean SpotWouldTelefrag( float *origin )
|
||||
{
|
||||
static Vector mins = Vector( -16, -16, 1 );
|
||||
static Vector maxs = Vector( 16, 16, 97 );
|
||||
trace_t trace;
|
||||
|
||||
trace = G_Trace( Vector(origin), mins, maxs, Vector(origin), NULL, MASK_PLAYERSOLID, qfalse, "SpotWouldTelefrag" );
|
||||
|
||||
if( trace.startsolid || trace.allsolid )
|
||||
return qtrue;
|
||||
else
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static int compare_spawnsort( const void *pe1, const void *pe2 )
|
||||
{
|
||||
float fDelta = ( ( spawnsort_t * )pe1 )->fMetric - ( ( spawnsort_t * )pe2 )->fMetric;
|
||||
|
||||
if( fDelta >= -0.001f )
|
||||
{
|
||||
if( fDelta <= 0.001f )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static PlayerStart *GetRandomSpawnpointFromList( spawnsort_t *pSpots, int nSpots )
|
||||
{
|
||||
int i = nSpots;
|
||||
float fTotalMetric;
|
||||
float fMinPosMetric;
|
||||
float fChosen;
|
||||
|
||||
if( nSpots <= 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qsort( pSpots, nSpots, sizeof( spawnsort_t ), compare_spawnsort );
|
||||
|
||||
if( pSpots[ 0 ].fMetric > 0.0f )
|
||||
{
|
||||
if( nSpots > 5 ) {
|
||||
nSpots = 5;
|
||||
}
|
||||
|
||||
fMinPosMetric = pSpots[ 0 ].fMetric * nSpots;
|
||||
fTotalMetric = fMinPosMetric;
|
||||
|
||||
if( nSpots <= 1 )
|
||||
{
|
||||
fChosen = fMinPosMetric;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
fTotalMetric = 0.0f;
|
||||
|
||||
for( i = 0; i < nSpots; i++ )
|
||||
{
|
||||
if( pSpots[ i ].fMetric <= 0.0f ) {
|
||||
break;
|
||||
}
|
||||
|
||||
fChosen = pSpots[ i ].fMetric * ( nSpots - i );
|
||||
fTotalMetric += fChosen;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if( i < nSpots )
|
||||
{
|
||||
fChosen = fMinPosMetric;
|
||||
}
|
||||
|
||||
fMinPosMetric = fTotalMetric;
|
||||
}
|
||||
|
||||
fTotalMetric = ( fMinPosMetric - i * fChosen * 0.90f ) * G_Random();
|
||||
for( i = 0; i < nSpots - 1; i++ )
|
||||
{
|
||||
fTotalMetric -= ( nSpots - i ) * pSpots[ i ].fMetric - ( fChosen * 0.90f );
|
||||
if( fTotalMetric <= 0.0f ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pSpots[ i ].spawnpoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
// return the spot anyway
|
||||
return pSpots[ 0 ].spawnpoint;
|
||||
}
|
||||
}
|
||||
|
||||
void DM_Team::Reset( void )
|
||||
{
|
||||
m_spawnpoints.ClearObjectList();
|
||||
m_players.ClearObjectList();
|
||||
}
|
||||
|
||||
void DM_Team::AddDeaths( Player *player, int numDeaths )
|
||||
{
|
||||
if( level.intermissiontime || dmManager.GetTeamWin() )
|
||||
return;
|
||||
|
||||
if( g_gametype->integer == GT_TEAM_ROUNDS || g_gametype->integer == GT_OBJECTIVE )
|
||||
return;
|
||||
|
||||
player->AddDeaths( numDeaths );
|
||||
|
||||
if( m_teamnumber > TEAM_FREEFORALL )
|
||||
m_iDeaths += numDeaths;
|
||||
}
|
||||
|
||||
void DM_Team::AddKills( Player *player, int numKills )
|
||||
{
|
||||
if( level.intermissiontime || dmManager.GetTeamWin() )
|
||||
return;
|
||||
|
||||
player->AddKills( numKills );
|
||||
|
||||
if( m_teamnumber > TEAM_FREEFORALL )
|
||||
{
|
||||
m_iKills += numKills;
|
||||
|
||||
if( g_gametype->integer == GT_TEAM_ROUNDS || g_gametype->integer == GT_OBJECTIVE )
|
||||
player->AddDeaths( numKills );
|
||||
else
|
||||
m_teamwins += numKills;
|
||||
}
|
||||
}
|
||||
|
||||
void DM_Team::AddPlayer( Player *player )
|
||||
{
|
||||
m_players.AddObject( player );
|
||||
}
|
||||
|
||||
void DM_Team::RemovePlayer( Player *player )
|
||||
{
|
||||
m_players.RemoveObject( player );
|
||||
}
|
||||
|
||||
void DM_Team::TeamWin( void )
|
||||
{
|
||||
m_teamwins++;
|
||||
m_wins_in_a_row++;
|
||||
|
||||
for( int i = 1; i <= m_players.NumObjects(); i++ )
|
||||
{
|
||||
m_players.ObjectAt( i )->WonMatch();
|
||||
}
|
||||
|
||||
UpdateTeamStatus();
|
||||
|
||||
if( m_teamnumber == TEAM_ALLIES )
|
||||
{
|
||||
gi.Cvar_Set( "g_scoreboardpicover", "textures/hud/allieswin" );
|
||||
}
|
||||
else if( m_teamnumber == TEAM_AXIS )
|
||||
{
|
||||
gi.Cvar_Set( "g_scoreboardpicover", "textures/hud/axiswin" );
|
||||
}
|
||||
}
|
||||
|
||||
void DM_Team::TeamLoss( void )
|
||||
{
|
||||
m_wins_in_a_row = 0;
|
||||
|
||||
for( int i = 1; i <= m_players.NumObjects(); i++ )
|
||||
{
|
||||
m_players.ObjectAt( i )->LostMatch();
|
||||
}
|
||||
|
||||
UpdateTeamStatus();
|
||||
}
|
||||
|
||||
bool DM_Team::IsDead( void ) const
|
||||
{
|
||||
Player *player;
|
||||
|
||||
if( IsEmpty() )
|
||||
{
|
||||
if( dmManager.IsGameActive() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !m_bHasSpawnedPlayers ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( dmManager.AllowRespawn() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int i = m_players.NumObjects(); i > 0; i-- )
|
||||
{
|
||||
player = m_players.ObjectAt( i );
|
||||
|
||||
if( player->IsSpectator() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !player->IsDead() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DM_Team::IsEmpty( void ) const
|
||||
{
|
||||
return m_players.NumObjects() <= 0;
|
||||
}
|
||||
|
||||
bool DM_Team::IsReady( void ) const
|
||||
{
|
||||
return !NumNotReady();
|
||||
}
|
||||
|
||||
int DM_Team::NumNotReady( void ) const
|
||||
{
|
||||
Player *player;
|
||||
int num = 0;
|
||||
|
||||
for( int i = 1; i <= m_players.NumObjects(); i++ )
|
||||
{
|
||||
player = m_players.ObjectAt( i );
|
||||
|
||||
if( player->IsReady() && !player->IsDead() )
|
||||
i++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int DM_Team::NumLivePlayers( void ) const
|
||||
{
|
||||
Player *player;
|
||||
int num = 0;
|
||||
|
||||
for( int i = 1; i <= m_players.NumObjects(); i++ )
|
||||
{
|
||||
player = m_players.ObjectAt( i );
|
||||
|
||||
if( !player->IsDead() && !player->IsSpectator() )
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int DM_Team::TotalPlayersKills( void ) const
|
||||
{
|
||||
Player *player;
|
||||
int iKills = 0;
|
||||
|
||||
for( int i = 1; i <= m_players.NumObjects(); i++ )
|
||||
{
|
||||
player = m_players.ObjectAt( i );
|
||||
|
||||
if( !player->IsDead() && !player->IsSpectator() )
|
||||
{
|
||||
iKills += player->GetNumKills();
|
||||
}
|
||||
}
|
||||
|
||||
return iKills;
|
||||
}
|
||||
|
||||
void DM_Team::TeamInvulnerable( void )
|
||||
{
|
||||
for( int i = 1; i <= m_players.NumObjects(); i++ )
|
||||
{
|
||||
m_players.ObjectAt( i )->takedamage = DAMAGE_NO;
|
||||
}
|
||||
}
|
||||
|
||||
void DM_Team::BeginFight( void )
|
||||
{
|
||||
for( int i = 1; i <= m_players.NumObjects(); i++ )
|
||||
{
|
||||
m_players.ObjectAt( i )->BeginFight();
|
||||
}
|
||||
}
|
||||
|
||||
void DM_Team::UpdateTeamStatus( void )
|
||||
{
|
||||
for( int i = 1; i <= m_players.NumObjects(); i++ )
|
||||
{
|
||||
m_players.ObjectAt( i )->UpdateStatus( va( "%d wins (%d in a row)", m_teamwins, m_wins_in_a_row ) );
|
||||
}
|
||||
}
|
||||
|
||||
float SpawnpointMetric_Ffa( const float *origin, DM_Team *dmTeam, const Player *player )
|
||||
{
|
||||
float fMinEnemyDistSquared = 23170.0f * 23170.0f;
|
||||
int i;
|
||||
int nPlayers = dmManager.PlayerCount();
|
||||
float fDist;
|
||||
|
||||
for( i = 1; i < nPlayers; i++ )
|
||||
{
|
||||
Player *teammate = dmManager.GetPlayer( i );
|
||||
if( teammate == player || teammate->IsDead() || teammate->IsSpectator() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fDist = ( teammate->origin - Vector( origin ) ).lengthSquared();
|
||||
|
||||
if( fMinEnemyDistSquared > fDist ) {
|
||||
fMinEnemyDistSquared = fDist;
|
||||
}
|
||||
}
|
||||
|
||||
return fMinEnemyDistSquared - ( G_Random( 0.25f ) + 1.0f ) * ( 1024.0f * 1024.0f );
|
||||
}
|
||||
|
||||
float SpawnpointMetric_Team( const float *origin, DM_Team *dmTeam, const Player *player )
|
||||
{
|
||||
float fMinEnemyDistSquared = 23170.0f * 23170.0f;
|
||||
float fSumFriendDistSquared = 0.0f;
|
||||
float fDistSquared;
|
||||
float fMetric;
|
||||
int i;
|
||||
int nPlayers = dmManager.PlayerCount();
|
||||
int nFriends = 0;
|
||||
|
||||
for( i = 1; i < nPlayers; i++ )
|
||||
{
|
||||
Player *teammate = dmManager.GetPlayer( i );
|
||||
if( teammate == player || teammate->IsDead() || teammate->IsSpectator() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fDistSquared = ( teammate->origin - Vector( origin ) ).lengthSquared();
|
||||
|
||||
if( teammate->GetDM_Team() == dmTeam )
|
||||
{
|
||||
nFriends++;
|
||||
fSumFriendDistSquared += fDistSquared;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( fMinEnemyDistSquared > fDistSquared ) {
|
||||
fMinEnemyDistSquared = fDistSquared;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fMetric = fMinEnemyDistSquared - ( G_Random( 0.25f ) + 1.0f ) * ( 1024.0f * 1024.0f );
|
||||
|
||||
if( nFriends )
|
||||
{
|
||||
fMetric += 0.25f * ( ( 23170.0f * 23170.0f ) - fSumFriendDistSquared / nFriends );
|
||||
}
|
||||
|
||||
return fMetric;
|
||||
}
|
||||
|
||||
float SpawnpointMetric_Objective( const float *origin, DM_Team *dmTeam, const Player *player )
|
||||
{
|
||||
return rand() * 0.0000000005f;
|
||||
}
|
||||
|
||||
PlayerStart *DM_Team::GetRandomFfaSpawnpoint( Player *player )
|
||||
{
|
||||
return GetRandomSpawnpointWithMetric( player, SpawnpointMetric_Ffa );
|
||||
}
|
||||
|
||||
PlayerStart *DM_Team::GetRandomTeamSpawnpoint( Player *player )
|
||||
{
|
||||
return GetRandomSpawnpointWithMetric( player, SpawnpointMetric_Team );
|
||||
}
|
||||
|
||||
PlayerStart *DM_Team::GetRandomObjectiveSpawnpoint( Player *player )
|
||||
{
|
||||
return GetRandomSpawnpointWithMetric( player, SpawnpointMetric_Objective );
|
||||
}
|
||||
|
||||
float DM_Team::PlayersRangeFromSpot( PlayerStart *spot )
|
||||
{
|
||||
float bestplayerdistance = 9999999.0f;
|
||||
Vector vDist;
|
||||
int i;
|
||||
gentity_t *ent;
|
||||
Player *player;
|
||||
|
||||
if( g_gametype->integer > GT_FFA ) {
|
||||
return bestplayerdistance;
|
||||
}
|
||||
|
||||
// find the nearest player from the post
|
||||
for( i = 0, ent = g_entities; i < game.maxclients; i++, ent++ )
|
||||
{
|
||||
if( !ent->client || !ent->entity ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
player = ( Player * )ent->entity;
|
||||
if( !player->IsDead() && !player->IsSpectator() && m_teamnumber != player->GetTeam() )
|
||||
{
|
||||
vDist = spot->origin - player->origin;
|
||||
if( bestplayerdistance > vDist.length() )
|
||||
bestplayerdistance = vDist.length();
|
||||
}
|
||||
}
|
||||
|
||||
return bestplayerdistance;
|
||||
}
|
||||
|
||||
PlayerStart *DM_Team::FarthestSpawnPoint( void )
|
||||
{
|
||||
int i;
|
||||
int iNumPoints;
|
||||
float bestdistance;
|
||||
float bestplayerdistance;
|
||||
PlayerStart *pSpot;
|
||||
PlayerStart *pBestSpot;
|
||||
PlayerStart *pSpot2;
|
||||
PlayerStart *pSpot3;
|
||||
|
||||
bestplayerdistance = 0.0f;
|
||||
pBestSpot = NULL;
|
||||
pSpot2 = NULL;
|
||||
pSpot3 = NULL;
|
||||
iNumPoints = m_spawnpoints.NumObjects();
|
||||
|
||||
for( i = 1; i <= iNumPoints; i++ )
|
||||
{
|
||||
pSpot = m_spawnpoints.ObjectAt( i );
|
||||
|
||||
bestdistance = PlayersRangeFromSpot( m_spawnpoints.ObjectAt( i ) );
|
||||
if( bestdistance > bestplayerdistance )
|
||||
{
|
||||
bestplayerdistance = bestdistance;
|
||||
pSpot3 = pSpot2;
|
||||
pSpot2 = pBestSpot;
|
||||
pBestSpot = pSpot;
|
||||
}
|
||||
}
|
||||
|
||||
if( pSpot3 && G_Random() < 0.2f )
|
||||
{
|
||||
return pSpot3;
|
||||
}
|
||||
else if( pSpot2 && G_Random() < 0.3f )
|
||||
{
|
||||
return pSpot2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pBestSpot;
|
||||
}
|
||||
}
|
||||
|
||||
PlayerStart *DM_Team::GetRandomSpawnpoint( void )
|
||||
{
|
||||
PlayerStart *spot = NULL;
|
||||
int numPoints = m_spawnpoints.NumObjects();
|
||||
|
||||
if( numPoints )
|
||||
{
|
||||
spot = FarthestSpawnPoint();
|
||||
if( !spot )
|
||||
{
|
||||
spot = m_spawnpoints.ObjectAt( ( int )( G_Random( numPoints ) + 1.0f ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
warning( "DM_Team::GetRandomSpawnpoint", "No spawnpoints found\n" );
|
||||
spot = NULL;
|
||||
}
|
||||
|
||||
return spot;
|
||||
}
|
||||
|
||||
PlayerStart *DM_Team::GetRandomSpawnpointWithMetric( Player *player, float( *MetricFunction ) ( const float *origin, DM_Team *dmTeam, const Player *player ) )
|
||||
{
|
||||
static float offset[ 4 ][ 3 ];
|
||||
spawnsort_t points[ 1024 ];
|
||||
PlayerStart *spot = NULL;
|
||||
int numSpots = 0;
|
||||
int iPoint = 0;
|
||||
|
||||
for( int i = 1; i <= m_spawnpoints.NumObjects(); i++ )
|
||||
{
|
||||
spot = m_spawnpoints.ObjectAt( i );
|
||||
if( spot->m_bForbidSpawns || player->GetLastSpawnpoint() == spot ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !SpotWouldTelefrag( spot->origin ) )
|
||||
{
|
||||
points[ numSpots ].spawnpoint = spot;
|
||||
points[ numSpots ].fMetric = MetricFunction( spot->origin, this, player );
|
||||
numSpots++;
|
||||
|
||||
if( numSpots >= ( sizeof( points ) / sizeof( points[ 0 ] ) ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spot = GetRandomSpawnpointFromList( points, numSpots );
|
||||
if( spot ) {
|
||||
return spot;
|
||||
}
|
||||
|
||||
numSpots = 0;
|
||||
|
||||
for( int i = 1; i <= m_spawnpoints.NumObjects(); i++ )
|
||||
{
|
||||
spot = m_spawnpoints.ObjectAt( i );
|
||||
if( spot->m_bForbidSpawns ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for( int j = 0; j < sizeof( offset ) / sizeof( offset[ 0 ] ); j++ )
|
||||
{
|
||||
Vector vNewSpawn = spot->origin + offset[ j ];
|
||||
|
||||
if( G_SightTrace(
|
||||
spot->origin,
|
||||
player->mins,
|
||||
player->maxs,
|
||||
vNewSpawn,
|
||||
( Entity * )NULL,
|
||||
( Entity * )NULL,
|
||||
MASK_PLAYERSOLID,
|
||||
qfalse,
|
||||
"DM_Team::GetRandomSpawnpointWithMetric" ) == 1 )
|
||||
{
|
||||
Vector vEnd = vNewSpawn - Vector( 0, 0, 64 );
|
||||
|
||||
trace_t trace = G_Trace(
|
||||
vNewSpawn,
|
||||
player->mins,
|
||||
player->maxs,
|
||||
vEnd,
|
||||
player,
|
||||
MASK_PLAYERSOLID,
|
||||
qfalse,
|
||||
"TempSpawnPoint" );
|
||||
|
||||
if( !trace.allsolid && !trace.startsolid &&
|
||||
trace.fraction != 1.0f && trace.fraction != 1.0f &&
|
||||
trace.plane.dist >= 0.8f )
|
||||
{
|
||||
points[ numSpots ].spawnpoint = new PlayerStart;
|
||||
points[ numSpots ].spawnpoint->setOrigin( trace.endpos );
|
||||
points[ numSpots ].spawnpoint->setAngles( spot->angles );
|
||||
points[ numSpots ].fMetric = MetricFunction( vNewSpawn, this, player );
|
||||
|
||||
if( numSpots >= ( sizeof( points ) / sizeof( points[ 0 ] ) ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spot = GetRandomSpawnpointFromList( points, numSpots );
|
||||
for( int i = 0; i < numSpots; i++ )
|
||||
{
|
||||
// delete all created spawnpoint
|
||||
if( points[ numSpots ].spawnpoint != spot ) {
|
||||
delete points[ numSpots ].spawnpoint;
|
||||
}
|
||||
}
|
||||
|
||||
if( spot ) {
|
||||
return spot;
|
||||
}
|
||||
|
||||
numSpots = 0;
|
||||
|
||||
for( int i = 1; i <= m_spawnpoints.NumObjects(); i++ )
|
||||
{
|
||||
spot = m_spawnpoints.ObjectAt( i );
|
||||
if( !spot->m_bForbidSpawns && player->GetLastSpawnpoint() != spot ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !SpotWouldTelefrag( spot->origin ) )
|
||||
{
|
||||
points[ numSpots ].spawnpoint = spot;
|
||||
points[ numSpots ].fMetric = MetricFunction( spot->origin, this, player );
|
||||
|
||||
if( numSpots >= ( sizeof( points ) / sizeof( points[ 0 ] ) ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GetRandomSpawnpointFromList( points, numSpots );
|
||||
}
|
||||
|
||||
void DM_Team::InitSpawnPoints
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
int i;
|
||||
|
||||
if( teamType == TEAM_SPECTATOR )
|
||||
{
|
||||
for( i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
|
||||
{
|
||||
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
|
||||
const char *classname = spawnpoint->getClassID();
|
||||
|
||||
if( !Q_stricmp( classname, "info_player_deathmatch" ) )
|
||||
{
|
||||
m_spawnpoints.AddObject( spawnpoint );
|
||||
}
|
||||
else if( !Q_stricmp( classname, "info_player_intermission" ) )
|
||||
{
|
||||
m_spawnpoints.AddObject( spawnpoint );
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if( g_gametype->integer <= GT_FFA )
|
||||
{
|
||||
for( i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
|
||||
{
|
||||
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
|
||||
const char *classname = spawnpoint->getClassID();
|
||||
|
||||
if( !Q_stricmp( classname, "info_player_deathmatch" ) )
|
||||
{
|
||||
m_spawnpoints.AddObject( spawnpoint );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_spawnpoints.NumObjects() <= 1 )
|
||||
{
|
||||
// Try with team spawnpoints
|
||||
for( i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
|
||||
{
|
||||
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
|
||||
const char *classname = spawnpoint->getClassID();
|
||||
|
||||
if( !Q_stricmp( classname, "info_player_allied" ) )
|
||||
{
|
||||
m_spawnpoints.AddObject( spawnpoint );
|
||||
}
|
||||
else if( !Q_stricmp( classname, "info_player_axis" ) )
|
||||
{
|
||||
m_spawnpoints.AddObject( spawnpoint );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( g_gametype->integer >= GT_TEAM )
|
||||
{
|
||||
if( teamType >= TEAM_ALLIES )
|
||||
{
|
||||
for( i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
|
||||
{
|
||||
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
|
||||
const char *classname = spawnpoint->getClassID();
|
||||
|
||||
if( teamType == TEAM_ALLIES && !Q_stricmp( classname, "info_player_allied" ) )
|
||||
{
|
||||
m_spawnpoints.AddObject( spawnpoint );
|
||||
}
|
||||
else if( teamType == TEAM_AXIS && !Q_stricmp( classname, "info_player_axis" ) )
|
||||
{
|
||||
m_spawnpoints.AddObject( spawnpoint );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_spawnpoints.NumObjects() )
|
||||
{
|
||||
// Try with info_player_deathmatch
|
||||
for( int i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
|
||||
{
|
||||
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
|
||||
const char *classname = spawnpoint->getClassID();
|
||||
|
||||
if( !Q_stricmp( classname, "info_player_deathmatch" ) )
|
||||
{
|
||||
m_spawnpoints.AddObject( spawnpoint );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DM_Team::DM_Team()
|
||||
{
|
||||
m_countdown = 0;
|
||||
m_teamwins = 0;
|
||||
m_wins_in_a_row = 0;
|
||||
m_teamnumber = -1;
|
||||
m_iKills = 0;
|
||||
m_iDeaths = 0;
|
||||
m_bHasSpawnedPlayers = false;
|
||||
}
|
||||
|
||||
DM_Team::~DM_Team()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CLASS_DECLARATION( Listener, DM_Team, NULL )
|
||||
{
|
||||
{ NULL, NULL }
|
||||
};
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// dm_team.cpp: Deathmatch Team Manager.
|
||||
|
||||
#ifndef __DM_TEAM_H__
|
||||
#define __DM_TEAM_H__
|
||||
|
||||
#include "listener.h"
|
||||
|
||||
class PlayerStart;
|
||||
class Player;
|
||||
|
||||
class DM_Team : public Listener
|
||||
{
|
||||
public:
|
||||
Container< PlayerStart * > m_spawnpoints;
|
||||
Container< Player * > m_players;
|
||||
|
||||
int m_maxplayers;
|
||||
|
||||
str m_teamname;
|
||||
|
||||
int m_teamnumber;
|
||||
|
||||
teamtype_t teamType;
|
||||
|
||||
int m_countdown;
|
||||
|
||||
int m_teamwins;
|
||||
int m_wins_in_a_row;
|
||||
|
||||
int m_iKills;
|
||||
int m_iDeaths;
|
||||
|
||||
qboolean m_bHasSpawnedPlayers;
|
||||
|
||||
public:
|
||||
CLASS_PROTOTYPE( DM_Team );
|
||||
|
||||
DM_Team();
|
||||
~DM_Team();
|
||||
|
||||
void Reset( void );
|
||||
|
||||
void AddDeaths( Player *player, int numDeaths );
|
||||
void AddKills( Player *player, int numKills );
|
||||
void AddPlayer( Player *player );
|
||||
|
||||
void RemovePlayer( Player *player );
|
||||
|
||||
void setName( str name ) { m_teamname = name; };
|
||||
str getName( void ) { return m_teamname; };
|
||||
void setNumber( int num ) { m_teamnumber = num; };
|
||||
int getNumber( void ) { return m_teamnumber; };
|
||||
void setIndex( int index );
|
||||
int getIndex( void );
|
||||
|
||||
void TeamWin( void );
|
||||
void TeamLoss( void );
|
||||
|
||||
bool IsDead( void ) const;
|
||||
bool IsEmpty( void ) const;
|
||||
bool IsReady( void ) const;
|
||||
|
||||
int NumNotReady( void ) const;
|
||||
int NumLivePlayers( void ) const;
|
||||
int TotalPlayersKills( void ) const;
|
||||
void TeamInvulnerable( void );
|
||||
void BeginFight( void );
|
||||
|
||||
float PlayersRangeFromSpot( PlayerStart *spot );
|
||||
|
||||
void UpdateTeamStatus( void );
|
||||
|
||||
void InitSpawnPoints( void );
|
||||
|
||||
PlayerStart *GetRandomFfaSpawnpoint( Player *player );
|
||||
PlayerStart *GetRandomTeamSpawnpoint( Player *player );
|
||||
PlayerStart *GetRandomObjectiveSpawnpoint( Player *player );
|
||||
protected:
|
||||
PlayerStart *FarthestSpawnPoint( void );
|
||||
PlayerStart *GetRandomSpawnpoint( void );
|
||||
PlayerStart *GetRandomSpawnpointWithMetric( Player *player, float( *MetricFunction ) ( float const *, DM_Team *dmTeam, const Player *player ) );
|
||||
};
|
||||
|
||||
typedef SafePtr< DM_Team > DM_TeamPtr;
|
||||
|
||||
#endif /* __DM_TEAM_H__ */
|
||||
+1
-27
@@ -965,12 +965,7 @@ qboolean Door::CanBeOpenedBy
|
||||
return master->CanBeOpenedBy( ent );
|
||||
}
|
||||
|
||||
if ( !locked && !key.length() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( ent && ent->isSubclassOf( Sentient ) && ( ( Sentient * )ent )->HasItem( key.c_str() ) )
|
||||
if ( !locked )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1036,30 +1031,9 @@ void Door::TryOpen
|
||||
|
||||
if ( !CanBeOpenedBy( other ) )
|
||||
{
|
||||
Item *item;
|
||||
ClassDef *cls;
|
||||
|
||||
if ( other->isClient() )
|
||||
{
|
||||
cls = getClass( key.c_str() );
|
||||
if ( !cls )
|
||||
{
|
||||
gi.DPrintf( "No item named '%s'\n", key.c_str() );
|
||||
return;
|
||||
}
|
||||
item = ( Item * )cls->newInstance();
|
||||
item->CancelEventsOfType( EV_Item_DropToFloor );
|
||||
item->CancelEventsOfType( EV_Remove );
|
||||
item->ProcessPendingEvents();
|
||||
gi.centerprintf ( other->edict, "You need the %s", item->getName().c_str() );
|
||||
delete item;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// once we're opened by an item, we no longer need that item to open the door
|
||||
key = "";
|
||||
|
||||
if ( Message().length() )
|
||||
{
|
||||
gi.centerprintf( other->edict, Message().c_str() );
|
||||
|
||||
+5510
-6080
File diff suppressed because it is too large.
Load diff
+612
-736
File diff suppressed because it is too large.
Load diff
@@ -105,7 +105,7 @@ void CreateExplosion
|
||||
|
||||
if( !explosionModel )
|
||||
{
|
||||
explosionModel = "fx_explosion.tik";
|
||||
explosionModel = "fx/fx_explosion.tik";
|
||||
}
|
||||
|
||||
explosion = new Explosion;
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "fixedturret.h"
|
||||
|
||||
CLASS_DECLARATION(VehicleTank, FixedTurret, NULL) {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
FixedTurret::FixedTurret()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void FixedTurret::Archive(Archiver& arc)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
qboolean FixedTurret::Drive(usercmd_t *ucmd)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void FixedTurret::DetachRemoteOwner()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void FixedTurret::EventDamage(Event *ev)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void FixedTurret::AttachDriverSlot(int slot, Entity *ent, Vector vExitPosition)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void FixedTurret::DetachDriverSlot(int slot, Vector vExitPosition, Vector *vExitAngles)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void FixedTurret::EventSetCollisionModel(Event *ev)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vehicle.h"
|
||||
|
||||
class FixedTurret : public VehicleTank
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE(FixedTurret);
|
||||
|
||||
public:
|
||||
FixedTurret();
|
||||
void Archive(Archiver& arc) override;
|
||||
|
||||
qboolean Drive(usercmd_t *ucmd) override;
|
||||
void DetachRemoteOwner() override;
|
||||
void EventDamage(Event *ev);
|
||||
|
||||
void AttachDriverSlot(int slot, Entity *ent, Vector vExitPosition) override;
|
||||
void DetachDriverSlot(int slot, Vector vExitPosition, Vector *vExitAngles) override;
|
||||
void EventSetCollisionModel(Event *ev);
|
||||
};
|
||||
+8
-32
@@ -242,10 +242,10 @@ void ClientThink_real( gentity_t *ent ) {
|
||||
}
|
||||
|
||||
if ( pmove_msec.integer < 8 ) {
|
||||
gi.Cvar_Set("pmove_msec", "8");
|
||||
gi.cvar_set("pmove_msec", "8");
|
||||
}
|
||||
else if (pmove_msec.integer > 33) {
|
||||
gi.Cvar_Set("pmove_msec", "33");
|
||||
gi.cvar_set("pmove_msec", "33");
|
||||
}
|
||||
|
||||
if ( pmove_fixed.integer || client->pers.pmoveFixed ) {
|
||||
@@ -341,8 +341,8 @@ void ClientThink_real( gentity_t *ent ) {
|
||||
else {
|
||||
pm.tracemask = MASK_PLAYERSOLID;
|
||||
}
|
||||
pm.trace = gi.Trace;
|
||||
pm.pointcontents = gi.PointContents;
|
||||
pm.trace = gi.trace;
|
||||
pm.pointcontents = gi.pointcontents;
|
||||
pm.debugLevel = g_debugMove.integer;
|
||||
pm.noFootsteps = ( dmflags->integer & DF_NO_FOOTSTEPS ) > 0;
|
||||
|
||||
@@ -707,7 +707,7 @@ void ClientUse(gentity_t *ent) {
|
||||
CalcMuzzlePoint(ent, forward, right, up, g_muzzle);
|
||||
|
||||
VectorMA(g_muzzle, 96.f, forward, right);
|
||||
gi.Trace(&tr, g_muzzle, NULL, NULL, right, ent - g_entities, MASK_SOLID,0,false);
|
||||
gi.trace(&tr, g_muzzle, NULL, NULL, right, ent - g_entities, MASK_SOLID,0,false);
|
||||
|
||||
if (tr.fraction == 1.f || tr.entityNum == ENTITYNUM_NONE || tr.entityNum == ENTITYNUM_WORLD) {
|
||||
ent->lastUseEntity = tr.entityNum;
|
||||
@@ -763,8 +763,8 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd ) {
|
||||
pm.ps = &client->ps;
|
||||
pm.cmd = *ucmd;
|
||||
pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; // spectators can fly through bodies
|
||||
pm.trace = gi.Trace;
|
||||
pm.pointcontents = gi.PointContents;
|
||||
pm.trace = gi.trace;
|
||||
pm.pointcontents = gi.pointcontents;
|
||||
|
||||
// perform a pmove
|
||||
Pmove (&pm);
|
||||
@@ -875,7 +875,7 @@ void G_TouchTriggers( gentity_t *ent )
|
||||
Event *ev;
|
||||
|
||||
// dead things don't activate triggers!
|
||||
if( ( ent->client || ( ent->r.svFlags & SVF_BOT ) ) && ( ent->entity->health <= 0 ) )
|
||||
if( ( ent->client || ( ent->r.svFlags & SVF_MONSTER ) ) && ( ent->entity->health <= 0 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -930,27 +930,3 @@ void G_ClientThink( gentity_t *ent, usercmd_t *cmd, usereyes_t *eyeinfo )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
G_ClientEndServerFrames
|
||||
=================
|
||||
*/
|
||||
void G_ClientEndServerFrames( void )
|
||||
{
|
||||
int i;
|
||||
gentity_t *ent;
|
||||
|
||||
// calc the player views now that all pushing
|
||||
// and damage has been added
|
||||
for( i = 0; i < game.maxclients; i++ )
|
||||
{
|
||||
ent = g_entities + i;
|
||||
if( !ent->inuse || !ent->client || !ent->entity )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ent->entity->EndFrame();
|
||||
}
|
||||
}
|
||||
|
||||
+192
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015 the OpenMoHAA team
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
@@ -24,6 +24,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#include "g_local.h"
|
||||
#include "entity.h"
|
||||
#include "playerbot.h"
|
||||
#include "g_bot.h"
|
||||
|
||||
static gentity_t* firstBot = NULL;
|
||||
static saved_bot_t* saved_bots = NULL;
|
||||
static unsigned int current_bot_count = 0;
|
||||
|
||||
void G_BotBegin
|
||||
(
|
||||
@@ -56,3 +61,189 @@ void G_BotThink
|
||||
|
||||
G_ClientThink( ent, &ucmd, &eyeinfo );
|
||||
}
|
||||
|
||||
gentity_t* G_GetFirstBot()
|
||||
{
|
||||
return firstBot;
|
||||
}
|
||||
|
||||
void G_AddBot(unsigned int num, saved_bot_t* saved)
|
||||
{
|
||||
int n;
|
||||
int i;
|
||||
int clientNum = -1;
|
||||
gentity_t *e;
|
||||
char botName[ MAX_NETNAME ];
|
||||
char challenge[ MAX_STRING_TOKENS ];
|
||||
char userinfo[MAX_INFO_STRING]{ 0 };
|
||||
Event* teamEv;
|
||||
|
||||
num = Q_min(num, sv_maxbots->integer);
|
||||
for( n = 0; n < num; n++ )
|
||||
{
|
||||
for( i = maxclients->integer; i < game.maxclients; i++ )
|
||||
{
|
||||
e = &g_entities[ i ];
|
||||
|
||||
if( !e->inuse && e->client )
|
||||
{
|
||||
clientNum = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( clientNum == -1 )
|
||||
{
|
||||
gi.Printf( "No free slot for a bot\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( gi.Argc() > 2 )
|
||||
{
|
||||
Q_strncpyz( botName, gi.Argv( 2 ), sizeof( botName ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( botName, "bot%d", clientNum - maxclients->integer + 1 );
|
||||
}
|
||||
|
||||
sprintf( challenge, "%d", clientNum - maxclients->integer + 1 );
|
||||
|
||||
e->s.clientNum = clientNum;
|
||||
e->s.number = clientNum;
|
||||
|
||||
if (saved) {
|
||||
strncpy(userinfo, saved->pers.userinfo, ARRAY_LEN(userinfo));
|
||||
} else {
|
||||
Info_SetValueForKey(userinfo, "name", botName);
|
||||
Info_SetValueForKey(userinfo, "dm_playermodel", "allied_pilot");
|
||||
Info_SetValueForKey(userinfo, "dm_playergermanmodel", "german_afrika_officer");
|
||||
Info_SetValueForKey(userinfo, "fov", "80");
|
||||
Info_SetValueForKey(userinfo, "protocol", "8");
|
||||
Info_SetValueForKey(userinfo, "ip", "0.0.0.0");
|
||||
Info_SetValueForKey(userinfo, "qport", "0");
|
||||
Info_SetValueForKey(userinfo, "challenge", challenge);
|
||||
Info_SetValueForKey(userinfo, "snaps", "1");
|
||||
Info_SetValueForKey(userinfo, "rate", "1");
|
||||
Info_SetValueForKey(userinfo, "dmprimary", "smg");
|
||||
}
|
||||
|
||||
current_bot_count++;
|
||||
|
||||
G_BotConnect( clientNum, userinfo );
|
||||
|
||||
if (saved) {
|
||||
e->client->pers = saved->pers;
|
||||
}
|
||||
|
||||
if( !firstBot )
|
||||
firstBot = e;
|
||||
|
||||
G_BotBegin( e );
|
||||
|
||||
if (saved) {
|
||||
/*
|
||||
switch (saved->team)
|
||||
{
|
||||
case TEAM_ALLIES:
|
||||
teamEv = new Event(EV_Player_JoinDMTeam);
|
||||
teamEv->AddString("allies");
|
||||
break;
|
||||
case TEAM_AXIS:
|
||||
teamEv = new Event(EV_Player_JoinDMTeam);
|
||||
teamEv->AddString("axis");
|
||||
break;
|
||||
default:
|
||||
teamEv = new Event(EV_Player_AutoJoinDMTeam);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
teamEv = new Event(EV_Player_AutoJoinDMTeam);
|
||||
e->entity->PostEvent(teamEv, level.frametime);
|
||||
|
||||
Event* ev = new Event(EV_Player_PrimaryDMWeapon);
|
||||
ev->AddString("smg");
|
||||
|
||||
e->entity->PostEvent(ev, level.frametime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G_RemoveBot(unsigned int num)
|
||||
{
|
||||
num = Q_min(atoi(gi.Argv(1)), sv_maxbots->integer);
|
||||
|
||||
for( int n = 0; n < num; n++ )
|
||||
{
|
||||
gentity_t *e = &g_entities[ game.maxclients - 1 - n ];
|
||||
if( e->inuse && e->client )
|
||||
{
|
||||
G_ClientDisconnect( e );
|
||||
current_bot_count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G_SaveBots() {
|
||||
unsigned int n;
|
||||
|
||||
if (saved_bots) {
|
||||
delete[] saved_bots;
|
||||
saved_bots = NULL;
|
||||
}
|
||||
|
||||
if (!current_bot_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
saved_bots = new saved_bot_t[current_bot_count];
|
||||
for (n = 0; n < current_bot_count; n++) {
|
||||
gentity_t* e = &g_entities[game.maxclients - sv_maxbots->integer + n];
|
||||
saved_bot_t& saved = saved_bots[n];
|
||||
|
||||
if (e->inuse && e->client)
|
||||
{
|
||||
Player* player = static_cast<Player*>(e->entity);
|
||||
|
||||
saved.bValid = true;
|
||||
//saved.team = player->GetTeam();
|
||||
saved.pers = player->client->pers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G_RestoreBots() {
|
||||
unsigned int n;
|
||||
|
||||
if (!saved_bots) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < sv_numbots->integer; n++) {
|
||||
saved_bot_t& saved = saved_bots[n];
|
||||
|
||||
G_AddBot(1, &saved);
|
||||
}
|
||||
|
||||
delete[] saved_bots;
|
||||
saved_bots = NULL;
|
||||
}
|
||||
|
||||
void G_ResetBots() {
|
||||
G_SaveBots();
|
||||
|
||||
current_bot_count = 0;
|
||||
}
|
||||
|
||||
void G_SpawnBots() {
|
||||
if (saved_bots) {
|
||||
G_RestoreBots();
|
||||
}
|
||||
|
||||
if (sv_numbots->integer > current_bot_count) {
|
||||
G_AddBot(sv_numbots->integer - current_bot_count);
|
||||
} else if (sv_numbots->integer < current_bot_count) {
|
||||
G_RemoveBot(current_bot_count - sv_numbots->integer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct saved_bot_t {
|
||||
client_persistant_t pers;
|
||||
bool bValid;
|
||||
|
||||
saved_bot_t()
|
||||
: bValid(false)
|
||||
{}
|
||||
};
|
||||
|
||||
void G_BotBegin(gentity_t* ent);
|
||||
void G_BotThink(gentity_t* ent, int msec);
|
||||
gentity_t* G_GetFirstBot();
|
||||
void G_AddBot(unsigned int num, saved_bot_t* saved = NULL);
|
||||
void G_RemoveBot(unsigned int num);
|
||||
void G_ResetBots();
|
||||
void G_SpawnBots();
|
||||
+375
-401
@@ -28,8 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
// g_client.c -- client functions that don't happen every frame
|
||||
|
||||
static vec3_t playerMins = {-15, -15, -24};
|
||||
static vec3_t playerMaxs = {15, 15, 32};
|
||||
static vec3_t playerMins = {-15, -15, -24};
|
||||
static vec3_t playerMaxs = {15, 15, 32};
|
||||
|
||||
// FIXME: OLD Q3 CODE
|
||||
|
||||
@@ -439,7 +439,6 @@ void SetClientViewAngle( gentity_t *ent, vec3_t angle ) {
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
||||
@@ -455,31 +454,31 @@ SelectNearestDeathmatchSpawnPoint
|
||||
Find the spot that we DON'T want to use
|
||||
================
|
||||
*/
|
||||
#define MAX_SPAWN_POINTS 128
|
||||
Entity *SelectNearestDeathmatchSpawnPoint( vec3_t from ) {
|
||||
Entity *spot;
|
||||
vec3_t delta;
|
||||
float dist, nearestDist;
|
||||
Entity *nearestSpot;
|
||||
#define MAX_SPAWN_POINTS 128
|
||||
|
||||
nearestDist = 999999;
|
||||
nearestSpot = NULL;
|
||||
spot = NULL;
|
||||
Entity *SelectNearestDeathmatchSpawnPoint(vec3_t from)
|
||||
{
|
||||
Entity *spot;
|
||||
vec3_t delta;
|
||||
float dist, nearestDist;
|
||||
Entity *nearestSpot;
|
||||
|
||||
while( ( spot = ( Entity * )G_FindClass( spot, "info_player_deathmatch" ) ) != NULL ) {
|
||||
nearestDist = 999999;
|
||||
nearestSpot = NULL;
|
||||
spot = NULL;
|
||||
|
||||
VectorSubtract( spot->origin, from, delta );
|
||||
dist = VectorLength( delta );
|
||||
if ( dist < nearestDist ) {
|
||||
nearestDist = dist;
|
||||
nearestSpot = spot;
|
||||
}
|
||||
}
|
||||
while ((spot = (Entity *)G_FindClass(spot, "info_player_deathmatch")) != NULL) {
|
||||
VectorSubtract(spot->origin, from, delta);
|
||||
dist = VectorLength(delta);
|
||||
if (dist < nearestDist) {
|
||||
nearestDist = dist;
|
||||
nearestSpot = spot;
|
||||
}
|
||||
}
|
||||
|
||||
return nearestSpot;
|
||||
return nearestSpot;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
SelectRandomDeathmatchSpawnPoint
|
||||
@@ -487,66 +486,57 @@ SelectRandomDeathmatchSpawnPoint
|
||||
go to a random point that doesn't telefrag
|
||||
================
|
||||
*/
|
||||
Entity *SelectRandomDeathmatchSpawnPoint( str spawnpoint_type )
|
||||
Entity *SelectRandomDeathmatchSpawnPoint(str spawnpoint_type)
|
||||
{
|
||||
Entity *spot = NULL;
|
||||
Entity *spot1 = NULL;
|
||||
Entity *spot2 = NULL;
|
||||
int count = 0;
|
||||
int selection;
|
||||
float range;
|
||||
float range1 = 99999.0f;
|
||||
float range2 = 99999.0f;
|
||||
Entity *spot = NULL;
|
||||
Entity *spot1 = NULL;
|
||||
Entity *spot2 = NULL;
|
||||
int count = 0;
|
||||
int selection;
|
||||
float range;
|
||||
float range1 = 99999.0f;
|
||||
float range2 = 99999.0f;
|
||||
|
||||
while( ( spot = ( Entity * )G_FindClass( spot, spawnpoint_type ) ) )
|
||||
{
|
||||
count++;
|
||||
while ((spot = (Entity *)G_FindClass(spot, spawnpoint_type))) {
|
||||
count++;
|
||||
|
||||
range = PlayersRangeFromSpot( spot );
|
||||
if( range2 <= range )
|
||||
{
|
||||
if( range1 > range )
|
||||
{
|
||||
range1 = range;
|
||||
spot1 = spot;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
range2 = range;
|
||||
spot2 = spot;
|
||||
}
|
||||
}
|
||||
range = PlayersRangeFromSpot(spot);
|
||||
if (range2 <= range) {
|
||||
if (range1 > range) {
|
||||
range1 = range;
|
||||
spot1 = spot;
|
||||
}
|
||||
} else {
|
||||
range2 = range;
|
||||
spot2 = spot;
|
||||
}
|
||||
}
|
||||
|
||||
spot = NULL;
|
||||
spot = NULL;
|
||||
|
||||
if( !count ) {
|
||||
return NULL;
|
||||
}
|
||||
if (!count) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( count > 2 )
|
||||
{
|
||||
count -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
spot1 = NULL;
|
||||
spot2 = NULL;
|
||||
}
|
||||
if (count > 2) {
|
||||
count -= 2;
|
||||
} else {
|
||||
spot1 = NULL;
|
||||
spot2 = NULL;
|
||||
}
|
||||
|
||||
for( selection = rand() % count; selection != -1; selection-- )
|
||||
{
|
||||
spot = ( Entity * )G_FindClass( spot, spawnpoint_type );
|
||||
if( !spot ) {
|
||||
break;
|
||||
}
|
||||
for (selection = rand() % count; selection != -1; selection--) {
|
||||
spot = (Entity *)G_FindClass(spot, spawnpoint_type);
|
||||
if (!spot) {
|
||||
break;
|
||||
}
|
||||
|
||||
if( spot == spot1 || spot == spot2 ) {
|
||||
selection++;
|
||||
}
|
||||
}
|
||||
if (spot == spot1 || spot == spot2) {
|
||||
selection++;
|
||||
}
|
||||
}
|
||||
|
||||
return spot;
|
||||
return spot;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -556,28 +546,26 @@ SelectRandomFurthestSpawnPoint
|
||||
Chooses a player start, deathmatch start, etc
|
||||
============
|
||||
*/
|
||||
Entity *SelectRandomFurthestSpawnPoint( void )
|
||||
Entity *SelectRandomFurthestSpawnPoint(void)
|
||||
{
|
||||
Entity *spot = NULL;
|
||||
Entity *bestspot = NULL;
|
||||
float bestplayerdistance = 0.0f;
|
||||
Entity *spot = NULL;
|
||||
Entity *bestspot = NULL;
|
||||
float bestplayerdistance = 0.0f;
|
||||
|
||||
while( ( spot = ( Entity * )G_FindClass( spot, "info_player_deathmatch" ) ) )
|
||||
{
|
||||
float dist = PlayersRangeFromSpot( spot );
|
||||
while ((spot = (Entity *)G_FindClass(spot, "info_player_deathmatch"))) {
|
||||
float dist = PlayersRangeFromSpot(spot);
|
||||
|
||||
if( dist > bestplayerdistance )
|
||||
{
|
||||
bestplayerdistance = dist;
|
||||
bestspot = spot;
|
||||
}
|
||||
}
|
||||
if (dist > bestplayerdistance) {
|
||||
bestplayerdistance = dist;
|
||||
bestspot = spot;
|
||||
}
|
||||
}
|
||||
|
||||
if( !bestspot ) {
|
||||
bestspot = ( Entity * )G_FindClass( NULL, "info_player_deathmatch" );
|
||||
}
|
||||
if (!bestspot) {
|
||||
bestspot = (Entity *)G_FindClass(NULL, "info_player_deathmatch");
|
||||
}
|
||||
|
||||
return bestspot;
|
||||
return bestspot;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -587,54 +575,50 @@ SelectSpawnPoint
|
||||
Chooses a player start, deathmatch start, etc
|
||||
============
|
||||
*/
|
||||
PlayerStart *SelectSpawnPoint( Player *player )
|
||||
PlayerStart *SelectSpawnPoint(Player *player)
|
||||
{
|
||||
PlayerStart *spot = NULL;
|
||||
PlayerStart *spot = NULL;
|
||||
|
||||
switch( g_gametype->integer )
|
||||
{
|
||||
case GT_FFA:
|
||||
spot = player->GetDM_Team()->GetRandomFfaSpawnpoint( player );
|
||||
break;
|
||||
case GT_SINGLE_PLAYER:
|
||||
break;
|
||||
case GT_TEAM:
|
||||
case GT_TEAM_ROUNDS:
|
||||
spot = player->GetDM_Team()->GetRandomTeamSpawnpoint( player );
|
||||
break;
|
||||
case GT_OBJECTIVE:
|
||||
spot = player->GetDM_Team()->GetRandomObjectiveSpawnpoint( player );
|
||||
break;
|
||||
default:
|
||||
Com_Printf("SelectSpawnPoint: unknown game type '%i'\n", g_gametype->integer);
|
||||
spot = player->GetDM_Team()->GetRandomFfaSpawnpoint( player );
|
||||
break;
|
||||
}
|
||||
switch (g_gametype->integer) {
|
||||
case GT_SINGLE_PLAYER:
|
||||
break;
|
||||
case GT_FFA:
|
||||
spot = player->GetDM_Team()->GetRandomFfaSpawnpoint(player);
|
||||
break;
|
||||
case GT_TEAM:
|
||||
case GT_TEAM_ROUNDS:
|
||||
case GT_LIBERATION:
|
||||
spot = player->GetDM_Team()->GetRandomTeamSpawnpoint(player);
|
||||
break;
|
||||
case GT_OBJECTIVE:
|
||||
case GT_TOW:
|
||||
spot = player->GetDM_Team()->GetRandomObjectiveSpawnpoint(player);
|
||||
break;
|
||||
default:
|
||||
Com_Printf("SelectSpawnPoint: unknown game type '%i'\n", g_gametype->integer);
|
||||
spot = player->GetDM_Team()->GetRandomFfaSpawnpoint(player);
|
||||
break;
|
||||
}
|
||||
|
||||
// find a single player start spot
|
||||
if( !spot )
|
||||
{
|
||||
while( ( spot = ( PlayerStart * )G_FindArchivedClass( spot, "info_player_start" ) ) != NULL )
|
||||
{
|
||||
if( level.spawnpoint.icmp( spot->TargetName() ) == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
// find a single player start spot
|
||||
if (!spot) {
|
||||
while ((spot = (PlayerStart *)G_FindArchivedClass(spot, "info_player_start")) != NULL) {
|
||||
if (level.spawnpoint.icmp(spot->TargetName()) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !spot && !level.spawnpoint.length() )
|
||||
{
|
||||
// there wasn't a spawnpoint without a target, so use any
|
||||
spot = ( PlayerStart * )G_FindArchivedClass( NULL, "info_player_start" );
|
||||
}
|
||||
if (!spot && !level.spawnpoint.length()) {
|
||||
// there wasn't a spawnpoint without a target, so use any
|
||||
spot = (PlayerStart *)G_FindArchivedClass(NULL, "info_player_start");
|
||||
}
|
||||
|
||||
if( !spot )
|
||||
{
|
||||
gi.Error( ERR_DROP, "No player spawn position named '%s'. Can't spawn player.\n", level.spawnpoint.c_str() );
|
||||
}
|
||||
}
|
||||
if (!spot) {
|
||||
gi.Error(ERR_DROP, "No player spawn position named '%s'. Can't spawn player.\n", level.spawnpoint.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return spot;
|
||||
return spot;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
@@ -644,89 +628,87 @@ PlayerStart *SelectSpawnPoint( Player *player )
|
||||
ClientCheckName
|
||||
============
|
||||
*/
|
||||
static void ClientCleanName( const char *in, char *out, int outSize )
|
||||
static void ClientCleanName(const char *in, char *out, int outSize)
|
||||
{
|
||||
int len, colorlessLen;
|
||||
char ch;
|
||||
char *p;
|
||||
int spaces;
|
||||
int len, colorlessLen;
|
||||
char ch;
|
||||
char *p;
|
||||
int spaces;
|
||||
|
||||
//save room for trailing null byte
|
||||
outSize--;
|
||||
//save room for trailing null byte
|
||||
outSize--;
|
||||
|
||||
len = 0;
|
||||
colorlessLen = 0;
|
||||
p = out;
|
||||
*p = 0;
|
||||
spaces = 0;
|
||||
len = 0;
|
||||
colorlessLen = 0;
|
||||
p = out;
|
||||
*p = 0;
|
||||
spaces = 0;
|
||||
|
||||
while( 1 ) {
|
||||
ch = *in++;
|
||||
if( !ch ) {
|
||||
break;
|
||||
}
|
||||
while (1) {
|
||||
ch = *in++;
|
||||
if (!ch) {
|
||||
break;
|
||||
}
|
||||
|
||||
// don't allow leading spaces
|
||||
if( colorlessLen == 0 && ch == ' ' ) {
|
||||
continue;
|
||||
}
|
||||
// don't allow leading spaces
|
||||
if (colorlessLen == 0 && ch == ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check colors
|
||||
if( ch == Q_COLOR_ESCAPE ) {
|
||||
// solo trailing carat is not a color prefix
|
||||
if( !*in ) {
|
||||
break;
|
||||
}
|
||||
// check colors
|
||||
if (ch == Q_COLOR_ESCAPE) {
|
||||
// solo trailing carat is not a color prefix
|
||||
if (!*in) {
|
||||
break;
|
||||
}
|
||||
|
||||
// don't allow black in a name, period
|
||||
if( ColorIndex(*in) == 0 ) {
|
||||
in++;
|
||||
continue;
|
||||
}
|
||||
// don't allow black in a name, period
|
||||
if (ColorIndex(*in) == 0) {
|
||||
in++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure room in dest for both chars
|
||||
if( len > outSize - 2 ) {
|
||||
break;
|
||||
}
|
||||
// make sure room in dest for both chars
|
||||
if (len > outSize - 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
*out++ = ch;
|
||||
*out++ = *in++;
|
||||
len += 2;
|
||||
continue;
|
||||
}
|
||||
*out++ = ch;
|
||||
*out++ = *in++;
|
||||
len += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't allow too many consecutive spaces
|
||||
// don't count spaces in colorlessLen
|
||||
if( ch == ' ' ) {
|
||||
spaces++;
|
||||
if( spaces > 3 ) {
|
||||
continue;
|
||||
}
|
||||
*out++ = ch;
|
||||
len++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
spaces = 0;
|
||||
}
|
||||
// don't allow too many consecutive spaces
|
||||
// don't count spaces in colorlessLen
|
||||
if (ch == ' ') {
|
||||
spaces++;
|
||||
if (spaces > 3) {
|
||||
continue;
|
||||
}
|
||||
*out++ = ch;
|
||||
len++;
|
||||
continue;
|
||||
} else {
|
||||
spaces = 0;
|
||||
}
|
||||
|
||||
if( len > outSize - 1 ) {
|
||||
break;
|
||||
}
|
||||
if (len > outSize - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
*out++ = ch;
|
||||
colorlessLen++;
|
||||
len++;
|
||||
}
|
||||
*out = 0;
|
||||
*out++ = ch;
|
||||
colorlessLen++;
|
||||
len++;
|
||||
}
|
||||
*out = 0;
|
||||
|
||||
// don't allow empty names
|
||||
if( *p == 0 || colorlessLen == 0 ) {
|
||||
Q_strncpyz( p, "UnnamedPlayer", outSize );
|
||||
}
|
||||
// don't allow empty names
|
||||
if (*p == 0 || colorlessLen == 0) {
|
||||
Q_strncpyz(p, "UnnamedPlayer", outSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
ClientUserInfoChanged
|
||||
@@ -738,102 +720,92 @@ The game can override any of the settings and call gi.SetUserinfo
|
||||
if desired.
|
||||
============
|
||||
*/
|
||||
void G_ClientUserinfoChanged( gentity_t *ent, const char *u ) {
|
||||
char *s;
|
||||
gclient_t *client;
|
||||
int clientnum;
|
||||
void G_ClientUserinfoChanged(gentity_t *ent, const char *u)
|
||||
{
|
||||
char *s;
|
||||
gclient_t *client;
|
||||
int clientnum;
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
client = ent->client;
|
||||
client = ent->client;
|
||||
|
||||
s = Info_ValueForKey( u, "name" );
|
||||
s = Info_ValueForKey(u, "name");
|
||||
|
||||
if( !s )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
|
||||
clientnum = ent - g_entities;
|
||||
clientnum = ent - g_entities;
|
||||
|
||||
if( gi.SanitizeName( s, client->pers.netname ) )
|
||||
{
|
||||
gi.Printf( "WARNING: had to sanitize the name for client %i\n", clientnum );
|
||||
}
|
||||
if (gi.SanitizeName(s, client->pers.netname)) {
|
||||
gi.Printf("WARNING: had to sanitize the name for client %i\n", clientnum);
|
||||
}
|
||||
|
||||
s = Info_ValueForKey( u, "dm_playermodel" );
|
||||
s = Info_ValueForKey(u, "dm_playermodel");
|
||||
|
||||
if( !s )
|
||||
{
|
||||
assert( 0 );
|
||||
return;
|
||||
}
|
||||
if (!s) {
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
Q_strncpyz( client->pers.playermodel, s, sizeof( client->pers.playermodel ) );
|
||||
Q_strncpyz(client->pers.dm_playermodel, s, sizeof(client->pers.dm_playermodel));
|
||||
|
||||
s = Info_ValueForKey( u, "dm_playergermanmodel" );
|
||||
s = Info_ValueForKey(u, "dm_playergermanmodel");
|
||||
|
||||
if( !s )
|
||||
{
|
||||
assert( 0 );
|
||||
return;
|
||||
}
|
||||
if (!s) {
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
Q_strncpyz( client->pers.playergermanmodel, s, sizeof( client->pers.playergermanmodel ) );
|
||||
Q_strncpyz(client->pers.dm_playergermanmodel, s, sizeof(client->pers.dm_playergermanmodel));
|
||||
|
||||
gi.SetConfigstring( CS_PLAYERS + clientnum, va( "name\\%s", client->pers.netname ) );
|
||||
gi.setConfigstring(CS_PLAYERS + clientnum, va("name\\%s", client->pers.netname));
|
||||
|
||||
if( ent->entity )
|
||||
{
|
||||
float fov;
|
||||
if (ent->entity) {
|
||||
float fov;
|
||||
|
||||
s = Info_ValueForKey( u, "fov" );
|
||||
s = Info_ValueForKey(u, "fov");
|
||||
|
||||
fov = atof( s );
|
||||
fov = atof(s);
|
||||
|
||||
if( fov < 80.0f )
|
||||
{
|
||||
fov = 80.0f;
|
||||
}
|
||||
else if( fov > 160.0f )
|
||||
{
|
||||
fov = 160.0f;
|
||||
}
|
||||
if (fov < 80.0f) {
|
||||
fov = 80.0f;
|
||||
} else if (fov > 160.0f) {
|
||||
fov = 160.0f;
|
||||
}
|
||||
|
||||
Event *ev = new Event( EV_Player_Fov );
|
||||
ev->AddFloat( fov );
|
||||
Event *ev = new Event(EV_Player_Fov);
|
||||
ev->AddFloat(fov);
|
||||
|
||||
ent->entity->ProcessEvent( ev );
|
||||
}
|
||||
ent->entity->ProcessEvent(ev);
|
||||
}
|
||||
|
||||
Q_strncpyz( client->pers.userinfo, u, sizeof( client->pers.userinfo ) );
|
||||
Q_strncpyz(client->pers.userinfo, u, sizeof(client->pers.userinfo));
|
||||
}
|
||||
|
||||
void G_BotConnect( int clientNum ) {
|
||||
gclient_t *client;
|
||||
gentity_t *ent;
|
||||
char userinfo[ MAX_INFO_STRING ];
|
||||
void G_BotConnect(int clientNum, const char* userinfo)
|
||||
{
|
||||
gclient_t *client;
|
||||
gentity_t *ent;
|
||||
|
||||
ent = &g_entities[ clientNum ];
|
||||
ent = &g_entities[clientNum];
|
||||
|
||||
ent->client = game.clients + clientNum;
|
||||
ent->s.number = clientNum;
|
||||
ent->client = game.clients + clientNum;
|
||||
ent->s.number = clientNum;
|
||||
|
||||
client = ent->client;
|
||||
client = ent->client;
|
||||
|
||||
Q_strncpyz( userinfo, client->pers.userinfo, sizeof( userinfo ) );
|
||||
// read the session data
|
||||
memset(client, 0, sizeof(*client));
|
||||
G_InitSessionData(client, userinfo);
|
||||
|
||||
// read the session data
|
||||
memset( client, 0, sizeof( *client ) );
|
||||
G_InitSessionData( client, userinfo );
|
||||
Q_strncpyz(client->pers.ip, "localhost", sizeof(client->pers.ip));
|
||||
client->pers.port = 0;
|
||||
|
||||
Q_strncpyz( client->pers.ip, "localhost", sizeof( client->pers.ip ) );
|
||||
client->pers.port = 0;
|
||||
|
||||
G_ClientUserinfoChanged( ent, userinfo );
|
||||
G_ClientUserinfoChanged(ent, userinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -856,64 +828,60 @@ to the server machine, but qfalse on map changes and tournement
|
||||
restarts.
|
||||
============
|
||||
*/
|
||||
const char *G_ClientConnect( int clientNum, qboolean firstTime ) {
|
||||
char *ip, *port, *value;
|
||||
gclient_t *client;
|
||||
gentity_t *ent;
|
||||
char userinfo[ MAX_INFO_STRING ];
|
||||
const char *G_ClientConnect(int clientNum, qboolean firstTime)
|
||||
{
|
||||
char *ip, *port, *value;
|
||||
gclient_t *client;
|
||||
gentity_t *ent;
|
||||
char userinfo[MAX_INFO_STRING];
|
||||
|
||||
gi.DPrintf("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT\n");
|
||||
if( !g_gametype->integer ) {
|
||||
return NULL;
|
||||
}
|
||||
gi.DPrintf("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT\n");
|
||||
if (!g_gametype->integer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ent = &g_entities[ clientNum ];
|
||||
ent = &g_entities[clientNum];
|
||||
|
||||
gi.GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );
|
||||
gi.GetUserinfo(clientNum, userinfo, sizeof(userinfo));
|
||||
|
||||
// IP filtering
|
||||
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=500
|
||||
// recommanding PB based IP / GUID banning, the builtin system is pretty limited
|
||||
// check to see if they are on the banned IP list
|
||||
ip = Info_ValueForKey( userinfo, "ip" );
|
||||
port = Info_ValueForKey( userinfo, "port" );
|
||||
// IP filtering
|
||||
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=500
|
||||
// recommanding PB based IP / GUID banning, the builtin system is pretty limited
|
||||
// check to see if they are on the banned IP list
|
||||
ip = Info_ValueForKey(userinfo, "ip");
|
||||
port = Info_ValueForKey(userinfo, "port");
|
||||
|
||||
// FIXME: what is fucking wrong with G_FilterPacket...
|
||||
//if ( G_FilterPacket( value ) ) {
|
||||
// return "Banned IP";
|
||||
//}
|
||||
// FIXME: what is fucking wrong with G_FilterPacket...
|
||||
//if ( G_FilterPacket( value ) ) {
|
||||
// return "Banned IP";
|
||||
//}
|
||||
|
||||
// we don't check password for bots and local client
|
||||
// NOTE: local client <-> "ip" "localhost"
|
||||
// this means this client is not running in our current process
|
||||
if( ( strcmp( ip, "localhost" ) != 0 ) )
|
||||
{
|
||||
// check for a password
|
||||
value = Info_ValueForKey( userinfo, "password" );
|
||||
if ( password->string[ 0 ] && Q_stricmp( password->string, "none" ) &&
|
||||
strcmp( password->string, value ) != 0 ) {
|
||||
return "Invalid password";
|
||||
}
|
||||
}
|
||||
// we don't check password for bots and local client
|
||||
// NOTE: local client <-> "ip" "localhost"
|
||||
// this means this client is not running in our current process
|
||||
if ((strcmp(ip, "localhost") != 0)) {
|
||||
// check for a password
|
||||
value = Info_ValueForKey(userinfo, "password");
|
||||
if (password->string[0] && Q_stricmp(password->string, "none") && strcmp(password->string, value) != 0) {
|
||||
return "Invalid password";
|
||||
}
|
||||
}
|
||||
|
||||
ent->client = game.clients + clientNum;
|
||||
client = ent->client;
|
||||
ent->client = game.clients + clientNum;
|
||||
client = ent->client;
|
||||
|
||||
// read or initialize the session data
|
||||
if ( firstTime )
|
||||
{
|
||||
memset( client, 0, sizeof( *client ) );
|
||||
G_InitSessionData( client, userinfo );
|
||||
}
|
||||
else
|
||||
{
|
||||
G_ReadSessionData( client );
|
||||
}
|
||||
// read or initialize the session data
|
||||
if (firstTime) {
|
||||
memset(client, 0, sizeof(*client));
|
||||
G_InitSessionData(client, userinfo);
|
||||
} else {
|
||||
G_ReadSessionData(client);
|
||||
}
|
||||
|
||||
Q_strncpyz( client->pers.ip, ip, sizeof( client->pers.ip ) );
|
||||
client->pers.port = atoi( port );
|
||||
Q_strncpyz(client->pers.ip, ip, sizeof(client->pers.ip));
|
||||
client->pers.port = atoi(port);
|
||||
|
||||
G_ClientUserinfoChanged( ent, userinfo );
|
||||
G_ClientUserinfoChanged(ent, userinfo);
|
||||
|
||||
#if 0
|
||||
if( isBot )
|
||||
@@ -926,17 +894,15 @@ const char *G_ClientConnect( int clientNum, qboolean firstTime ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// don't do the "xxx connected" messages if they were caried over from previous level
|
||||
if ( firstTime && g_gametype->integer )
|
||||
{
|
||||
if( dedicated->integer )
|
||||
{
|
||||
gi.Printf( "%s is preparing for deployment\n", client->pers.netname );
|
||||
}
|
||||
// don't do the "xxx connected" messages if they were caried over from previous level
|
||||
if (firstTime && g_gametype->integer) {
|
||||
if (dedicated->integer) {
|
||||
gi.Printf("%s is preparing for deployment\n", client->pers.netname);
|
||||
}
|
||||
|
||||
G_PrintToAllClients( va( "%s is preparing for deployment\n", client->pers.netname ) );
|
||||
}
|
||||
return NULL;
|
||||
G_PrintToAllClients(va("%s is preparing for deployment\n", client->pers.netname), 2);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -948,68 +914,80 @@ to be placed into the level. This will happen every level load,
|
||||
and on transition between teams, but doesn't happen on respawns
|
||||
============
|
||||
*/
|
||||
void G_ClientBegin( gentity_t *ent, usercmd_t *cmd )
|
||||
void G_ClientBegin(gentity_t *ent, usercmd_t *cmd)
|
||||
{
|
||||
try
|
||||
{
|
||||
assert( ent->s.number < game.maxclients );
|
||||
assert( ent->client != NULL );
|
||||
try {
|
||||
assert(ent->s.number < game.maxclients);
|
||||
assert(ent->client != NULL);
|
||||
|
||||
if( ent->inuse && ent->entity )
|
||||
{
|
||||
VectorClear(ent->client->cmd_angles);
|
||||
// the client has cleared the client side viewangles upon
|
||||
// connecting to the server, which is different than the
|
||||
// state when the game is saved, so we need to compensate
|
||||
// with deltaangles
|
||||
ent->entity->SetDeltaAngles();
|
||||
}
|
||||
else
|
||||
{
|
||||
// a spawn point will completely reinitialize the entity
|
||||
level.spawn_entnum = ent->s.number;
|
||||
if (ent->inuse && ent->entity) {
|
||||
VectorClear(ent->client->cmd_angles);
|
||||
// the client has cleared the client side viewangles upon
|
||||
// connecting to the server, which is different than the
|
||||
// state when the game is saved, so we need to compensate
|
||||
// with deltaangles
|
||||
ent->entity->SetDeltaAngles();
|
||||
} else {
|
||||
// a spawn point will completely reinitialize the entity
|
||||
level.spawn_entnum = ent->s.number;
|
||||
|
||||
if( level.m_bSpawnBot )
|
||||
{
|
||||
level.m_bSpawnBot = false;
|
||||
PlayerBot *player = new PlayerBot;
|
||||
}
|
||||
else
|
||||
{
|
||||
Player *player = new Player;
|
||||
}
|
||||
}
|
||||
if (level.m_bSpawnBot) {
|
||||
level.m_bSpawnBot = false;
|
||||
PlayerBot *player = new PlayerBot;
|
||||
} else {
|
||||
Player *player = new Player;
|
||||
}
|
||||
}
|
||||
|
||||
if( level.intermissiontime && ent->entity )
|
||||
{
|
||||
G_MoveClientToIntermission( ent->entity );
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->client->pers.enterTime = level.svsFloatTime;
|
||||
if (level.intermissiontime && ent->entity) {
|
||||
G_MoveClientToIntermission(ent->entity);
|
||||
} else {
|
||||
ent->client->pers.enterTime = level.svsFloatTime;
|
||||
|
||||
if( g_gametype->integer )
|
||||
{
|
||||
// send effect if in a multiplayer game
|
||||
if( dedicated->integer )
|
||||
{
|
||||
gi.Printf( "%s has entered the battle\n", ent->client->pers.netname );
|
||||
}
|
||||
if (g_gametype->integer) {
|
||||
// send effect if in a multiplayer game
|
||||
if (dedicated->integer) {
|
||||
gi.Printf("%s has entered the battle\n", ent->client->pers.netname);
|
||||
}
|
||||
|
||||
G_PrintToAllClients( va( "%s has entered the battle\n", ent->client->pers.netname ) );
|
||||
}
|
||||
}
|
||||
G_PrintToAllClients(va("%s has entered the battle\n", ent->client->pers.netname), 2);
|
||||
}
|
||||
}
|
||||
|
||||
// make sure all view stuff is valid
|
||||
if( ent->entity )
|
||||
{
|
||||
ent->entity->EndFrame();
|
||||
}
|
||||
}
|
||||
catch( const char *error )
|
||||
{
|
||||
G_ExitWithError( error );
|
||||
}
|
||||
// make sure all view stuff is valid
|
||||
if (ent->entity) {
|
||||
ent->entity->EndFrame();
|
||||
}
|
||||
} catch (const char *error) {
|
||||
G_ExitWithError(error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
G_SetClientConfigString
|
||||
============
|
||||
*/
|
||||
void G_SetClientConfigString(gentity_t *ent)
|
||||
{
|
||||
int num;
|
||||
const char *string;
|
||||
|
||||
if (!ent) {
|
||||
return;
|
||||
}
|
||||
|
||||
num = ent - g_entities;
|
||||
|
||||
if (ent->entity) {
|
||||
Player *pEnt = static_cast<Player *>(ent->entity);
|
||||
string = va("name\\%s\\team\\%i", ent->client->pers.netname, pEnt->GetTeam());
|
||||
} else {
|
||||
// No team
|
||||
string = va("name\\%s\\team\\0", ent->client->pers.netname);
|
||||
}
|
||||
|
||||
gi.setConfigstring(CS_PLAYERS + num, string);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1024,26 +1002,24 @@ call gi.DropClient(), which will call this and do
|
||||
server system housekeeping.
|
||||
============
|
||||
*/
|
||||
void G_ClientDisconnect( gentity_t *ent ) {
|
||||
try
|
||||
{
|
||||
if ( !ent || ( !ent->client ) || ( !ent->entity ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
void G_ClientDisconnect(gentity_t *ent)
|
||||
{
|
||||
try {
|
||||
if (!ent || (!ent->client) || (!ent->entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
G_PrintToAllClients( va( "%s has left the battle\n", ent->client->pers.netname ) );
|
||||
G_PrintToAllClients(va("%s has left the battle\n", ent->client->pers.netname), 2);
|
||||
|
||||
( ( Player * )ent->entity )->Disconnect();
|
||||
((Player *)ent->entity)->Disconnect();
|
||||
|
||||
delete ent->entity;
|
||||
ent->entity = NULL;
|
||||
}
|
||||
delete ent->entity;
|
||||
ent->entity = NULL;
|
||||
}
|
||||
|
||||
catch( const char *error )
|
||||
{
|
||||
G_ExitWithError( error );
|
||||
}
|
||||
catch (const char *error) {
|
||||
G_ExitWithError(error);
|
||||
}
|
||||
#if 0
|
||||
int i;
|
||||
|
||||
@@ -1071,12 +1047,12 @@ void G_ClientDisconnect( gentity_t *ent ) {
|
||||
// They don't get to take powerups with them!
|
||||
// Especially important for stuff like CTF flags
|
||||
TossClientItems( ent );
|
||||
#ifdef MISSIONPACK
|
||||
# ifdef MISSIONPACK
|
||||
TossClientPersistantPowerups( ent );
|
||||
if( g_gametype->integer == GT_HARVESTER ) {
|
||||
TossClientCubes( ent );
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
}
|
||||
|
||||
@@ -1100,5 +1076,3 @@ void G_ClientDisconnect( gentity_t *ent ) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+291
-334
@@ -32,44 +32,43 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
//==================================================================
|
||||
|
||||
// the "gameversion" client command will print this plus compile date
|
||||
#define GAMEVERSION BASEGAME
|
||||
#define GAMEVERSION "OPENMOHAA"
|
||||
|
||||
#define BODY_QUEUE_SIZE 8
|
||||
#define BODY_QUEUE_SIZE 8
|
||||
|
||||
#define INFINITE 1000000
|
||||
#define INFINITE 1000000
|
||||
|
||||
#define FRAMETIME level.frametime // float sec
|
||||
#define CARNAGE_REWARD_TIME 3000
|
||||
#define REWARD_SPRITE_TIME 2000
|
||||
#define FRAMETIME level.frametime // float sec
|
||||
#define CARNAGE_REWARD_TIME 3000
|
||||
#define REWARD_SPRITE_TIME 2000
|
||||
|
||||
#define INTERMISSION_DELAY_TIME 1000
|
||||
#define SP_INTERMISSION_DELAY_TIME 5000
|
||||
#define INTERMISSION_DELAY_TIME 1000
|
||||
#define SP_INTERMISSION_DELAY_TIME 5000
|
||||
|
||||
// flags
|
||||
#define FL_FLY (1<<0)
|
||||
#define FL_SWIM (1<<1) // implied immunity to drowining
|
||||
#define FL_INWATER (1<<2)
|
||||
#define FL_GODMODE (1<<3)
|
||||
#define FL_NOTARGET (1<<4)
|
||||
#define FL_PARTIALGROUND (1<<5) // not all corners are valid
|
||||
#define FL_TEAMSLAVE (1<<6) // not the first on the team
|
||||
#define FL_NO_KNOCKBACK (1<<7)
|
||||
#define FL_THINK (1<<8)
|
||||
#define FL_BLOOD (1<<9) // when hit, it should bleed.
|
||||
#define FL_DIE_GIBS (1<<10) // when it dies, it should gib
|
||||
#define FL_DIE_EXPLODE (1<<11) // when it dies, it will explode
|
||||
#define FL_ROTATEDBOUNDS (1<<12) // model uses rotated mins and maxs
|
||||
#define FL_DONTSAVE (1<<13) // don't add to the savegame
|
||||
#define FL_IMMOBILE (1<<14) // entity has been immobolized somehow
|
||||
#define FL_PARTIAL_IMMOBILE (1<<15) // entity has been immobolized somehow
|
||||
#define FL_ANIMATE (1<<16) // entity has been immobolized somehow
|
||||
#define FL_POSTTHINK (1<<17) // call a think function after the physics have been run
|
||||
#define FL_TOUCH_TRIGGERS (1<<18) // should this entity touch triggers
|
||||
#define FL_AUTOAIM (1<<19) // Autoaim on this entity
|
||||
#define FL_UNKNOWN (1<<20)
|
||||
#define FL_UNKNOWN2 (1<<21)
|
||||
#define FL_FLY (1 << 0)
|
||||
#define FL_SWIM (1 << 1) // implied immunity to drowining
|
||||
#define FL_INWATER (1 << 2)
|
||||
#define FL_GODMODE (1 << 3)
|
||||
#define FL_NOTARGET (1 << 4)
|
||||
#define FL_PARTIALGROUND (1 << 5) // not all corners are valid
|
||||
#define FL_TEAMSLAVE (1 << 6) // not the first on the team
|
||||
#define FL_NO_KNOCKBACK (1 << 7)
|
||||
#define FL_THINK (1 << 8)
|
||||
#define FL_BLOOD (1 << 9) // when hit, it should bleed.
|
||||
#define FL_DIE_GIBS (1 << 10) // when it dies, it should gib
|
||||
#define FL_DIE_EXPLODE (1 << 11) // when it dies, it will explode
|
||||
#define FL_ROTATEDBOUNDS (1 << 12) // model uses rotated mins and maxs
|
||||
#define FL_DONTSAVE (1 << 13) // don't add to the savegame
|
||||
#define FL_IMMOBILE (1 << 14) // entity has been immobolized somehow
|
||||
#define FL_PARTIAL_IMMOBILE (1 << 15) // entity has been immobolized somehow
|
||||
#define FL_POSTTHINK (1 << 17) // call a think function after the physics have been run
|
||||
#define FL_TOUCH_TRIGGERS (1 << 18) // should this entity touch triggers
|
||||
#define FL_AUTOAIM (1 << 19) // Autoaim on this entity
|
||||
#define FL_ANIMATE (1 << 20) // entity has been immobolized somehow
|
||||
#define FL_UNKNOWN2 (1 << 21)
|
||||
|
||||
#define SOUND_RADIUS 1500.0f // Sound travel distance for AI
|
||||
#define SOUND_RADIUS 1500.0f // Sound travel distance for AI
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -83,363 +82,322 @@ template<typename T>
|
||||
class Container;
|
||||
|
||||
typedef enum {
|
||||
SPECTATOR_NOT,
|
||||
SPECTATOR_FREE,
|
||||
SPECTATOR_FOLLOW,
|
||||
SPECTATOR_SCOREBOARD
|
||||
SPECTATOR_NOT,
|
||||
SPECTATOR_FREE,
|
||||
SPECTATOR_FOLLOW,
|
||||
SPECTATOR_SCOREBOARD
|
||||
} spectatorState_t;
|
||||
|
||||
typedef enum {
|
||||
TEAM_BEGIN, // Beginning a team game, spawn at base
|
||||
TEAM_ACTIVE // Now actively playing
|
||||
TEAM_BEGIN, // Beginning a team game, spawn at base
|
||||
TEAM_ACTIVE // Now actively playing
|
||||
} playerTeamStateState_t;
|
||||
|
||||
typedef struct {
|
||||
playerTeamStateState_t state;
|
||||
playerTeamStateState_t state;
|
||||
|
||||
int location;
|
||||
int location;
|
||||
|
||||
int captures;
|
||||
int basedefense;
|
||||
int carrierdefense;
|
||||
int flagrecovery;
|
||||
int fragcarrier;
|
||||
int assists;
|
||||
int captures;
|
||||
int basedefense;
|
||||
int carrierdefense;
|
||||
int flagrecovery;
|
||||
int fragcarrier;
|
||||
int assists;
|
||||
|
||||
float lasthurtcarrier;
|
||||
float lastreturnedflag;
|
||||
float flagsince;
|
||||
float lastfraggedcarrier;
|
||||
float lasthurtcarrier;
|
||||
float lastreturnedflag;
|
||||
float flagsince;
|
||||
float lastfraggedcarrier;
|
||||
} playerTeamState_t;
|
||||
|
||||
// the auto following clients don't follow a specific client
|
||||
// number, but instead follow the first two active players
|
||||
#define FOLLOW_ACTIVE1 -1
|
||||
#define FOLLOW_ACTIVE2 -2
|
||||
#define FOLLOW_ACTIVE1 -1
|
||||
#define FOLLOW_ACTIVE2 -2
|
||||
|
||||
// client data that stays across multiple levels or tournament restarts
|
||||
// this is achieved by writing all the data to cvar strings at game shutdown
|
||||
// time and reading them back at connection time. Anything added here
|
||||
// MUST be dealt with in G_InitSessionData() / G_ReadSessionData() / G_WriteSessionData()
|
||||
typedef struct {
|
||||
teamtype_t sessionTeam;
|
||||
int spectatorTime; // for determining next-in-line to play
|
||||
spectatorState_t spectatorState;
|
||||
int spectatorClient; // for chasecam and follow mode
|
||||
int wins, losses; // tournament stats
|
||||
qboolean teamLeader; // true when this client is a team leader
|
||||
teamtype_t sessionTeam;
|
||||
int spectatorTime; // for determining next-in-line to play
|
||||
spectatorState_t spectatorState;
|
||||
int spectatorClient; // for chasecam and follow mode
|
||||
int wins, losses; // tournament stats
|
||||
qboolean teamLeader; // true when this client is a team leader
|
||||
} clientSession_t;
|
||||
|
||||
//
|
||||
#define MAX_NETNAME 32
|
||||
#define MAX_VOTE_COUNT 3
|
||||
#define MAX_NETNAME 32
|
||||
#define MAX_VOTE_COUNT 3
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CS_FREE,
|
||||
CS_ZOMBIE,
|
||||
CS_CONNECTED,
|
||||
CS_PRIMED,
|
||||
CS_ACTIVE
|
||||
typedef enum {
|
||||
CS_FREE,
|
||||
CS_ZOMBIE,
|
||||
CS_CONNECTED,
|
||||
CS_PRIMED,
|
||||
CS_ACTIVE
|
||||
|
||||
} clientState_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WEAPON_MAIN,
|
||||
WEAPON_OFFHAND,
|
||||
WEAPON_ERROR
|
||||
} weaponhand_t;
|
||||
|
||||
#define NUM_ACTIVE_WEAPONS WEAPON_ERROR
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FIRE_PRIMARY,
|
||||
FIRE_SECONDARY,
|
||||
MAX_FIREMODES,
|
||||
FIRE_ERROR
|
||||
} firemode_t;
|
||||
|
||||
//
|
||||
// g_spawn.c
|
||||
//
|
||||
qboolean G_SpawnString( const char *key, const char *defaultString, char **out );
|
||||
qboolean G_SpawnString(const char *key, const char *defaultString, char **out);
|
||||
// spawn string returns a temporary reference, you must CopyString() if you want to keep it
|
||||
qboolean G_SpawnFloat( const char *key, const char *defaultString, float *out );
|
||||
qboolean G_SpawnInt( const char *key, const char *defaultString, int *out );
|
||||
qboolean G_SpawnVector( const char *key, const char *defaultString, float *out );
|
||||
void G_SpawnEntitiesFromString( void );
|
||||
char *G_NewString( const char *string );
|
||||
qboolean G_SpawnFloat(const char *key, const char *defaultString, float *out);
|
||||
qboolean G_SpawnInt(const char *key, const char *defaultString, int *out);
|
||||
qboolean G_SpawnVector(const char *key, const char *defaultString, float *out);
|
||||
void G_SpawnEntitiesFromString(void);
|
||||
char *G_NewString(const char *string);
|
||||
const char *G_FixTIKIPath(const char *in);
|
||||
void G_GetNullEntityState( entityState_t *nullState );
|
||||
void G_GetNullEntityState(entityState_t *nullState);
|
||||
|
||||
//
|
||||
// g_cmds.c
|
||||
//
|
||||
void Cmd_Score_f (gentity_t *ent);
|
||||
void StopFollowing( gentity_t *ent );
|
||||
void BroadcastTeamChange( gclient_t *client, int oldTeam );
|
||||
void SetTeam( gentity_t *ent, char *s );
|
||||
void Cmd_FollowCycle_f( gentity_t *ent, int dir );
|
||||
void Cmd_Score_f(gentity_t *ent);
|
||||
void StopFollowing(gentity_t *ent);
|
||||
void BroadcastTeamChange(gclient_t *client, int oldTeam);
|
||||
void SetTeam(gentity_t *ent, char *s);
|
||||
void Cmd_FollowCycle_f(gentity_t *ent, int dir);
|
||||
|
||||
//
|
||||
// g_items.c
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// g_utils.c
|
||||
//
|
||||
|
||||
float G_Random( void );
|
||||
float G_Random( float n );
|
||||
float G_CRandom( void );
|
||||
float G_CRandom( float n );
|
||||
float G_Random(void);
|
||||
float G_Random(float n);
|
||||
float G_CRandom(void);
|
||||
float G_CRandom(float n);
|
||||
|
||||
int G_ModelIndex( const char *name );
|
||||
int G_SoundIndex( const char *name );
|
||||
void G_TeamCommand( teamtype_t team, char *cmd );
|
||||
void G_KillBox (gentity_t *ent);
|
||||
qboolean M_CheckBottom( Entity *ent );
|
||||
gentity_t *G_PickTarget (char *targetname);
|
||||
void G_UseTargets (gentity_t *ent, gentity_t *activator);
|
||||
Vector G_GetMovedir( float angle );
|
||||
void G_SetMovedir ( vec3_t angles, vec3_t movedir);
|
||||
int G_ModelIndex(const char *name);
|
||||
int G_SoundIndex(const char *name);
|
||||
void G_TeamCommand(teamtype_t team, char *cmd);
|
||||
void G_KillBox(gentity_t *ent);
|
||||
qboolean M_CheckBottom(Entity *ent);
|
||||
gentity_t *G_PickTarget(char *targetname);
|
||||
void G_UseTargets(gentity_t *ent, gentity_t *activator);
|
||||
void G_SetMovedir(vec3_t angles, vec3_t movedir);
|
||||
|
||||
void G_InitGentity( gentity_t *e );
|
||||
gentity_t *G_Spawn (void);
|
||||
gentity_t *G_TempEntity( vec3_t origin, int event );
|
||||
void G_Sound( gentity_t *ent, int channel, int soundIndex );
|
||||
void G_FreeEntity( gentity_t *e );
|
||||
qboolean G_entitiesFree( void );
|
||||
void G_InitGentity(gentity_t *e);
|
||||
gentity_t *G_Spawn(void);
|
||||
gentity_t *G_TempEntity(vec3_t origin, int event);
|
||||
void G_Sound(gentity_t *ent, int channel, int soundIndex);
|
||||
void G_FreeEntity(gentity_t *e);
|
||||
qboolean G_entitiesFree(void);
|
||||
|
||||
Entity *G_NextEntity( Entity *ent );
|
||||
Entity *G_NextEntity(Entity *ent);
|
||||
|
||||
void G_CalcBoundsOfMove( Vector &start, Vector &end, Vector &mins, Vector &maxs, Vector *minbounds, Vector *maxbounds );
|
||||
void G_CalcBoundsOfMove(Vector& start, Vector& end, Vector& mins, Vector& maxs, Vector *minbounds, Vector *maxbounds);
|
||||
|
||||
void G_ShowTrace( trace_t *trace, gentity_t *passent, const char *reason );
|
||||
bool G_SightTrace(const Vector &start, const Vector &mins, const Vector &maxs, const Vector &end, Entity *passent, Entity *passent2, int contentmask, qboolean cylindrical, const char *reason );
|
||||
bool G_SightTrace( const Vector &start, const Vector &mins, const Vector &maxs, const Vector &end, gentity_t *passent, gentity_t *passent2, int contentmask, qboolean cylindrical, const char *reason );
|
||||
trace_t G_Trace(const Vector &start, const Vector &mins, const Vector &maxs, const Vector &end, Entity *passent, int contentmask, qboolean cylindrical, const char *reason, qboolean tracedeep = qfalse );
|
||||
trace_t G_Trace( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, gentity_t *passent, int contentmask, qboolean cylindrical, const char *reason, qboolean tracedeep = qfalse );
|
||||
void G_TraceEntities( Vector &start, Vector &mins, Vector &maxs, Vector &end, Container<Entity *>*victimlist, int contentmask, qboolean bIncludeTriggers = qfalse );
|
||||
float PlayersRangeFromSpot(Entity *ent);
|
||||
|
||||
float PlayersRangeFromSpot( Entity *ent );
|
||||
Entity *findradius(Entity *startent, Vector org, float rad);
|
||||
Entity *findclientsinradius(Entity *startent, Vector org, float rad);
|
||||
|
||||
Entity *findradius( Entity *startent, Vector org, float rad );
|
||||
Entity *findclientsinradius( Entity *startent, Vector org, float rad );
|
||||
void G_TouchTriggers(gentity_t *ent);
|
||||
void G_TouchSolids(gentity_t *ent);
|
||||
|
||||
Vector G_CalculateImpulse( const Vector &start, const Vector &end, float speed, float gravity );
|
||||
void G_CenterPrintToAllClients(const char *pszString);
|
||||
void G_PrintToAllClients(const char *pszString, int iType = 1);
|
||||
void G_PrintDeathMessage(
|
||||
const char *s1, const char *s2, const char *attackerName, const char *victimName, Player *victim, const char *type
|
||||
);
|
||||
void G_PrintDeathMessage_Old(const char *pszString);
|
||||
void G_WarnPlayer(class Player *player, const char *format, ...);
|
||||
|
||||
void G_TouchTriggers (gentity_t *ent);
|
||||
void G_TouchSolids (gentity_t *ent);
|
||||
|
||||
int MOD_NameToNum( const str &meansOfDeath );
|
||||
const char *MOD_NumToName( int meansOfDeath );
|
||||
qboolean MOD_matches( int incoming_damage, int damage_type );
|
||||
|
||||
void G_MissionFailed( void );
|
||||
void G_FadeOut( float delaytime );
|
||||
void G_FadeSound( float delaytime );
|
||||
void G_PlayerDied( float delaytime );
|
||||
void G_AutoFadeIn( void );
|
||||
void G_ClearFade( void );
|
||||
void G_StartCinematic( void );
|
||||
void G_StopCinematic( void );
|
||||
|
||||
void G_CenterPrintToAllClients( const char *pszString );
|
||||
void G_PrintToAllClients( const char *pszString, qboolean bBold = qtrue );
|
||||
void G_PrintDeathMessage( const char *pszString );
|
||||
void G_WarnPlayer( class Player *player, const char *format, ... );
|
||||
|
||||
int G_WeaponIndex( const char *name );
|
||||
int G_WeaponIndex(const char *name);
|
||||
|
||||
class SkelMat4;
|
||||
|
||||
orientation_t G_TIKI_Orientation( gentity_t *edict, int num );
|
||||
SkelMat4 *G_TIKI_Transform( gentity_t *edict, int num );
|
||||
qboolean G_TIKI_IsOnGround( gentity_t *edict, int num, float threshold );
|
||||
qboolean G_Command_ProcessFile( const char * filename, qboolean quiet );
|
||||
orientation_t G_TIKI_Orientation(gentity_t *edict, int num);
|
||||
SkelMat4 *G_TIKI_Transform(gentity_t *edict, int num);
|
||||
qboolean G_TIKI_IsOnGround(gentity_t *edict, int num, float threshold);
|
||||
qboolean G_Command_ProcessFile(const char *filename, qboolean quiet);
|
||||
|
||||
char *G_TimeString( float fTime );
|
||||
char *CanonicalTikiName( const char *szInName );
|
||||
char *G_TimeString(float fTime);
|
||||
char *CanonicalTikiName(const char *szInName);
|
||||
|
||||
float *tv (float x, float y, float z);
|
||||
char *vtos( const vec3_t v );
|
||||
float *tv(float x, float y, float z);
|
||||
char *vtos(const vec3_t v);
|
||||
|
||||
float vectoyaw( const vec3_t vec );
|
||||
void G_SetOrigin(gentity_t *ent, vec3_t origin);
|
||||
void AddRemap(const char *oldShader, const char *newShader, float timeOffset);
|
||||
const char *BuildShaderStateConfig(void);
|
||||
|
||||
void G_SetOrigin( gentity_t *ent, vec3_t origin );
|
||||
void AddRemap(const char *oldShader, const char *newShader, float timeOffset);
|
||||
const char *BuildShaderStateConfig( void );
|
||||
void G_DebugTargets(Entity *e, const str& from);
|
||||
void G_DebugDamage(float damage, Entity *victim, Entity *attacker, Entity *inflictor);
|
||||
void G_DebugString(Vector pos, float scale, float r, float g, float b, const char *pszText, ...);
|
||||
|
||||
firemode_t WeaponModeNameToNum( str mode );
|
||||
const char *WeaponHandNumToName( weaponhand_t hand );
|
||||
weaponhand_t WeaponHandNameToNum( str side );
|
||||
void G_DebugTargets( Entity *e, const str &from );
|
||||
void G_DebugDamage( float damage, Entity *victim, Entity *attacker, Entity *inflictor );
|
||||
void G_DebugString( Vector pos, float scale, float r, float g, float b, const char *pszText, ... );
|
||||
qboolean KillBox(Entity *ent);
|
||||
|
||||
qboolean KillBox( Entity *ent );
|
||||
void ChangeMusic(const char *current, const char *fallback, qboolean force);
|
||||
void ChangeMusicVolume(float volume, float fade_time);
|
||||
void RestoreMusicVolume(float fade_time);
|
||||
void ChangeSoundtrack(const char *soundtrack);
|
||||
void RestoreSoundtrack(void);
|
||||
int G_AIEventTypeFromString(const char *pszType);
|
||||
const char *G_AIEventStringFromType(int iType);
|
||||
float G_AIEventRadius(int iType);
|
||||
void G_BroadcastAIEvent(Entity *originator, Vector origin, char *pszType);
|
||||
void G_BroadcastAIEvent(Entity *originator, Vector origin, int iType, float radius);
|
||||
|
||||
void ChangeMusic( const char *current, const char *fallback, qboolean force );
|
||||
void ChangeMusicVolume( float volume, float fade_time );
|
||||
void RestoreMusicVolume( float fade_time );
|
||||
void ChangeSoundtrack( const char * soundtrack );
|
||||
void RestoreSoundtrack( void );
|
||||
int G_AIEventTypeFromString( const char *pszType );
|
||||
const char * G_AIEventStringFromType(int iType );
|
||||
float G_AIEventRadius( int iType );
|
||||
void G_BroadcastAIEvent( Entity *originator, Vector origin, char *pszType );
|
||||
void G_BroadcastAIEvent( Entity *originator, Vector origin, int iType, float radius );
|
||||
void CloneEntity(Entity *dest, Entity *src);
|
||||
void G_ArchiveEdict(Archiver& arc, gentity_t *edict);
|
||||
|
||||
void CloneEntity( Entity * dest, Entity * src );
|
||||
void G_ArchiveEdict( Archiver &arc, gentity_t *edict );
|
||||
const char *G_LocationNumToDispString(int iLocation);
|
||||
str G_WeaponClassNumToName(int num);
|
||||
int G_WeaponClassNameToNum(str name);
|
||||
|
||||
const char *G_LocationNumToDispString( int iLocation );
|
||||
str G_WeaponClassNumToName( int num );
|
||||
int G_WeaponClassNameToNum( str name );
|
||||
//Checks for the intermission to exit.
|
||||
void G_CheckIntermissionExit(void);
|
||||
void G_CheckStartRules(void);
|
||||
void G_CheckExitRules(void);
|
||||
|
||||
void G_MoveClientToIntermission( Entity *ent );
|
||||
void G_DisplayScores( Entity *ent );
|
||||
void G_HideScores( Entity *ent );
|
||||
void G_DisplayScoresToAllClients( void );
|
||||
void G_HideScoresToAllClients( void );
|
||||
// Update the time limit
|
||||
void G_UpdateMatchEndTime(void);
|
||||
|
||||
void G_MoveClientToIntermission(Entity *ent);
|
||||
void G_DisplayScores(Entity *ent);
|
||||
void G_HideScores(Entity *ent);
|
||||
void G_DisplayScoresToAllClients(void);
|
||||
void G_HideScoresToAllClients(void);
|
||||
|
||||
//
|
||||
// caching commands
|
||||
//
|
||||
void G_ProcessCacheInitCommands( dtiki_t *tiki );
|
||||
void CacheResource( const char * stuff );
|
||||
void G_ProcessCacheInitCommands(dtiki_t *tiki);
|
||||
|
||||
void G_SetTrajectory( gentity_t *ent, vec3_t org );
|
||||
void G_SetConstantLight (
|
||||
int * constantlight,
|
||||
float * red,
|
||||
float * green,
|
||||
float * blue,
|
||||
float * radius,
|
||||
int * lightstyle = NULL
|
||||
);
|
||||
void G_SetTrajectory(gentity_t *ent, vec3_t org);
|
||||
|
||||
//
|
||||
// g_combat.c
|
||||
//
|
||||
qboolean CanDamage (gentity_t *targ, vec3_t origin);
|
||||
void G_Damage (gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, vec3_t dir, vec3_t point, int damage, int dflags, int mod);
|
||||
qboolean G_RadiusDamage (vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int mod);
|
||||
int G_InvulnerabilityEffect( gentity_t *targ, vec3_t dir, vec3_t point, vec3_t impactpoint, vec3_t bouncedir );
|
||||
void body_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath );
|
||||
void TossClientItems( gentity_t *self );
|
||||
qboolean CanDamage(gentity_t *targ, vec3_t origin);
|
||||
void G_Damage(
|
||||
gentity_t *targ,
|
||||
gentity_t *inflictor,
|
||||
gentity_t *attacker,
|
||||
vec3_t dir,
|
||||
vec3_t point,
|
||||
int damage,
|
||||
int dflags,
|
||||
int mod
|
||||
);
|
||||
qboolean G_RadiusDamage(vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int mod);
|
||||
int G_InvulnerabilityEffect(gentity_t *targ, vec3_t dir, vec3_t point, vec3_t impactpoint, vec3_t bouncedir);
|
||||
void body_die(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath);
|
||||
void TossClientItems(gentity_t *self);
|
||||
#ifdef MISSIONPACK
|
||||
void TossClientPersistantPowerups( gentity_t *self );
|
||||
void TossClientPersistantPowerups(gentity_t *self);
|
||||
#endif
|
||||
void TossClientCubes( gentity_t *self );
|
||||
void TossClientCubes(gentity_t *self);
|
||||
|
||||
// damage flags
|
||||
#define DAMAGE_NONE 0
|
||||
#define DAMAGE_RADIUS 0x00000001 // damage was indirect
|
||||
#define DAMAGE_NO_ARMOR 0x00000002 // armour does not protect from this damage
|
||||
#define DAMAGE_ENERGY 0x00000004 // damage is from an energy based weapon
|
||||
#define DAMAGE_NO_KNOCKBACK 0x00000008 // do not affect velocity, just view angles
|
||||
#define DAMAGE_BULLET 0x00000010 // damage is from a bullet (used for ricochets)
|
||||
#define DAMAGE_NO_PROTECTION 0x00000020 // armor, shields, invulnerability, and godmode have no effect
|
||||
#define DAMAGE_NO_SKILL 0x00000040 // damage is not affected by skill level
|
||||
#define DAMAGE_NONE 0
|
||||
#define DAMAGE_RADIUS 0x00000001 // damage was indirect
|
||||
#define DAMAGE_NO_ARMOR 0x00000002 // armour does not protect from this damage
|
||||
#define DAMAGE_ENERGY 0x00000004 // damage is from an energy based weapon
|
||||
#define DAMAGE_NO_KNOCKBACK 0x00000008 // do not affect velocity, just view angles
|
||||
#define DAMAGE_BULLET 0x00000010 // damage is from a bullet (used for ricochets)
|
||||
#define DAMAGE_NO_PROTECTION 0x00000020 // armor, shields, invulnerability, and godmode have no effect
|
||||
#define DAMAGE_NO_SKILL 0x00000040 // damage is not affected by skill level
|
||||
|
||||
//
|
||||
// g_missile.c
|
||||
//
|
||||
void G_RunMissile( gentity_t *ent );
|
||||
void G_RunMissile(gentity_t *ent);
|
||||
|
||||
gentity_t *fire_blaster (gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
gentity_t *fire_plasma (gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir);
|
||||
gentity_t *fire_bfg (gentity_t *self, vec3_t start, vec3_t dir);
|
||||
gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir);
|
||||
gentity_t *fire_blaster(gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
gentity_t *fire_plasma(gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
gentity_t *fire_grenade(gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
gentity_t *fire_rocket(gentity_t *self, vec3_t start, vec3_t dir);
|
||||
gentity_t *fire_bfg(gentity_t *self, vec3_t start, vec3_t dir);
|
||||
gentity_t *fire_grapple(gentity_t *self, vec3_t start, vec3_t dir);
|
||||
#ifdef MISSIONPACK
|
||||
gentity_t *fire_nail( gentity_t *self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up );
|
||||
gentity_t *fire_prox( gentity_t *self, vec3_t start, vec3_t aimdir );
|
||||
gentity_t *fire_nail(gentity_t *self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up);
|
||||
gentity_t *fire_prox(gentity_t *self, vec3_t start, vec3_t aimdir);
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// g_mover.c
|
||||
//
|
||||
void G_RunMover( gentity_t *ent );
|
||||
void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace );
|
||||
void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator );
|
||||
void G_RunMover(gentity_t *ent);
|
||||
void Touch_DoorTrigger(gentity_t *ent, gentity_t *other, trace_t *trace);
|
||||
void Use_BinaryMover(gentity_t *ent, gentity_t *other, gentity_t *activator);
|
||||
|
||||
//
|
||||
// g_trigger.c
|
||||
//
|
||||
void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace );
|
||||
|
||||
void trigger_teleporter_touch(gentity_t *self, gentity_t *other, trace_t *trace);
|
||||
|
||||
//
|
||||
// g_misc.c
|
||||
//
|
||||
void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles );
|
||||
void TeleportPlayer(gentity_t *player, vec3_t origin, vec3_t angles);
|
||||
#ifdef MISSIONPACK
|
||||
void DropPortalSource( gentity_t *ent );
|
||||
void DropPortalDestination( gentity_t *ent );
|
||||
void DropPortalSource(gentity_t *ent);
|
||||
void DropPortalDestination(gentity_t *ent);
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// g_weapon.c
|
||||
//
|
||||
qboolean LogAccuracyHit( gentity_t *target, gentity_t *attacker );
|
||||
void SnapVectorTowards( vec3_t v, vec3_t to );
|
||||
qboolean CheckGauntletAttack( gentity_t *ent );
|
||||
void Weapon_HookFree (gentity_t *ent);
|
||||
void Weapon_HookThink (gentity_t *ent);
|
||||
void CalcMuzzlePoint( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint );
|
||||
qboolean LogAccuracyHit(gentity_t *target, gentity_t *attacker);
|
||||
void SnapVectorTowards(vec3_t v, vec3_t to);
|
||||
qboolean CheckGauntletAttack(gentity_t *ent);
|
||||
void Weapon_HookFree(gentity_t *ent);
|
||||
void Weapon_HookThink(gentity_t *ent);
|
||||
void CalcMuzzlePoint(gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint);
|
||||
|
||||
//
|
||||
// g_client.c
|
||||
//
|
||||
gentity_t *G_Find( gentity_t *from, int fieldofs, const char *match );
|
||||
teamtype_t TeamCount( int ignoreClientNum, int team );
|
||||
int TeamLeader( int team );
|
||||
teamtype_t PickTeam( int ignoreClientNum );
|
||||
void SetClientViewAngle( gentity_t *ent, vec3_t angle );
|
||||
class PlayerStart *SelectSpawnPoint( Player *player );
|
||||
void CopyToBodyQue( gentity_t *ent );
|
||||
void respawn (gentity_t *ent);
|
||||
void BeginIntermission (void);
|
||||
void InitClientPersistant (gclient_t *client);
|
||||
void InitClientResp (gclient_t *client);
|
||||
void InitBodyQue (void);
|
||||
void ClientSpawn( gentity_t *ent );
|
||||
void player_die (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod);
|
||||
void AddScore( gentity_t *ent, vec3_t origin, int score );
|
||||
void CalculateRanks( void );
|
||||
gentity_t *G_Find(gentity_t *from, int fieldofs, const char *match);
|
||||
teamtype_t TeamCount(int ignoreClientNum, int team);
|
||||
int TeamLeader(int team);
|
||||
teamtype_t PickTeam(int ignoreClientNum);
|
||||
void SetClientViewAngle(gentity_t *ent, vec3_t angle);
|
||||
class PlayerStart *SelectSpawnPoint(Player *player);
|
||||
void CopyToBodyQue(gentity_t *ent);
|
||||
void respawn(gentity_t *ent);
|
||||
void BeginIntermission(void);
|
||||
void InitClientPersistant(gclient_t *client);
|
||||
void InitClientResp(gclient_t *client);
|
||||
void InitBodyQue(void);
|
||||
void ClientSpawn(gentity_t *ent);
|
||||
void player_die(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod);
|
||||
void AddScore(gentity_t *ent, vec3_t origin, int score);
|
||||
void CalculateRanks(void);
|
||||
|
||||
//
|
||||
// g_svcmds.c
|
||||
//
|
||||
qboolean G_ConsoleCommand( void );
|
||||
void G_ProcessIPBans(void);
|
||||
qboolean G_FilterPacket (char *from);
|
||||
qboolean G_ConsoleCommand(void);
|
||||
void G_ProcessIPBans(void);
|
||||
qboolean G_FilterPacket(char *from);
|
||||
|
||||
//
|
||||
// g_weapon.c
|
||||
//
|
||||
void FireWeapon( gentity_t *ent );
|
||||
void FireWeapon(gentity_t *ent);
|
||||
#ifdef MISSIONPACK
|
||||
void G_StartKamikaze( gentity_t *ent );
|
||||
void G_StartKamikaze(gentity_t *ent);
|
||||
#endif
|
||||
|
||||
//
|
||||
// p_hud.c
|
||||
//
|
||||
void MoveClientToIntermission (gentity_t *client);
|
||||
void G_SetStats (gentity_t *ent);
|
||||
void DeathmatchScoreboardMessage (gentity_t *client);
|
||||
void MoveClientToIntermission(gentity_t *client);
|
||||
void G_SetStats(gentity_t *ent);
|
||||
void DeathmatchScoreboardMessage(gentity_t *client);
|
||||
|
||||
//
|
||||
// g_cmds.c
|
||||
@@ -449,129 +407,128 @@ void DeathmatchScoreboardMessage (gentity_t *client);
|
||||
// g_pweapon.c
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// g_main.c
|
||||
//
|
||||
void FindIntermissionPoint( void );
|
||||
void SetLeader(int team, int client);
|
||||
void CheckTeamLeader( int team );
|
||||
void G_RunThink (gentity_t *ent);
|
||||
void QDECL G_LogPrintf( const char *fmt, ... );
|
||||
void SendScoreboardMessageToAllClients( void );
|
||||
void QDECL G_Printf( const char *fmt, ... );
|
||||
void QDECL G_Error( const char *fmt, ... );
|
||||
void QDECL G_Error( errorParm_t type, const char *fmt, ... );
|
||||
void FindIntermissionPoint(void);
|
||||
void SetLeader(int team, int client);
|
||||
void CheckTeamLeader(int team);
|
||||
void G_RunThink(gentity_t *ent);
|
||||
void QDECL G_LogPrintf(const char *fmt, ...);
|
||||
void SendScoreboardMessageToAllClients(void);
|
||||
void QDECL G_Printf(const char *fmt, ...);
|
||||
void QDECL G_Error(const char *fmt, ...);
|
||||
void QDECL G_Error(errorParm_t type, const char *fmt, ...);
|
||||
|
||||
//
|
||||
// g_client.c
|
||||
//
|
||||
void G_BotConnect( int clientNum );
|
||||
const char *G_ClientConnect( int clientNum, qboolean firstTime );
|
||||
void G_ClientUserinfoChanged( gentity_t *ent, const char *userinfo );
|
||||
void G_ClientDisconnect( gentity_t *ent );
|
||||
void G_ClientBegin( gentity_t *ent, usercmd_t *cmd );
|
||||
void G_ClientCommand( gentity_t *ent );
|
||||
void G_BotConnect(int clientNum, const char* userinfo);
|
||||
const char *G_ClientConnect(int clientNum, qboolean firstTime);
|
||||
void G_ClientUserinfoChanged(gentity_t *ent, const char *userinfo);
|
||||
void G_ClientDisconnect(gentity_t *ent);
|
||||
void G_ClientBegin(gentity_t *ent, usercmd_t *cmd);
|
||||
void G_SetClientConfigString(gentity_t *ent);
|
||||
void G_ClientCommand(gentity_t *ent);
|
||||
|
||||
//
|
||||
// g_active.c
|
||||
//
|
||||
void G_ClientThink( gentity_t *ent, usercmd_t *cmd, usereyes_t *eyeinfo );
|
||||
void ClientEndFrame( gentity_t *ent );
|
||||
void G_ClientEndServerFrames( void );
|
||||
void G_RunClient( gentity_t *ent );
|
||||
void G_ClientThink(gentity_t *ent, usercmd_t *cmd, usereyes_t *eyeinfo);
|
||||
void ClientEndFrame(gentity_t *ent);
|
||||
void G_ClientEndServerFrames(void);
|
||||
void G_RunClient(gentity_t *ent);
|
||||
|
||||
//
|
||||
// g_team.c
|
||||
//
|
||||
qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 );
|
||||
void Team_CheckDroppedItem( gentity_t *dropped );
|
||||
qboolean CheckObeliskAttack( gentity_t *obelisk, gentity_t *attacker );
|
||||
qboolean OnSameTeam(gentity_t *ent1, gentity_t *ent2);
|
||||
void Team_CheckDroppedItem(gentity_t *dropped);
|
||||
qboolean CheckObeliskAttack(gentity_t *obelisk, gentity_t *attacker);
|
||||
|
||||
//
|
||||
// g_mem.c
|
||||
//
|
||||
void *G_Alloc( int size );
|
||||
void G_InitMemory( void );
|
||||
void Svcmd_GameMem_f( void );
|
||||
void *G_Alloc(int size);
|
||||
void G_InitMemory(void);
|
||||
void Svcmd_GameMem_f(void);
|
||||
|
||||
//
|
||||
// g_session.c
|
||||
//
|
||||
void G_ReadSessionData( gclient_t *client );
|
||||
void G_InitSessionData( gclient_t *client, char *userinfo );
|
||||
void G_ReadSessionData(gclient_t *client);
|
||||
void G_InitSessionData(gclient_t *client, const char *userinfo);
|
||||
|
||||
void G_InitWorldSession( void );
|
||||
void G_WriteSessionData( void );
|
||||
void G_InitWorldSession(void);
|
||||
void G_WriteSessionData(void);
|
||||
|
||||
//
|
||||
// g_arenas.c
|
||||
//
|
||||
void UpdateTournamentInfo( void );
|
||||
void SpawnModelsOnVictoryPads( void );
|
||||
void Svcmd_AbortPodium_f( void );
|
||||
void UpdateTournamentInfo(void);
|
||||
void SpawnModelsOnVictoryPads(void);
|
||||
void Svcmd_AbortPodium_f(void);
|
||||
|
||||
//
|
||||
// g_bot.c
|
||||
//
|
||||
void G_BotBegin( gentity_t *ent );
|
||||
void G_BotThink( gentity_t *ent, int msec );
|
||||
|
||||
typedef struct mmove_s {
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
|
||||
qboolean walking;
|
||||
qboolean groundPlane;
|
||||
vec3_t groundPlaneNormal;
|
||||
qboolean walking;
|
||||
qboolean groundPlane;
|
||||
vec3_t groundPlaneNormal;
|
||||
|
||||
float frametime;
|
||||
float frametime;
|
||||
|
||||
float desired_speed;
|
||||
int tracemask;
|
||||
float desired_dir[ 2 ];
|
||||
float desired_speed;
|
||||
int tracemask;
|
||||
float desired_dir[2];
|
||||
|
||||
int entityNum;
|
||||
int entityNum;
|
||||
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
|
||||
int numtouch;
|
||||
int touchents[ MAXTOUCH ];
|
||||
int numtouch;
|
||||
int touchents[MAXTOUCH];
|
||||
|
||||
qboolean hit_obstacle;
|
||||
vec3_t hit_origin;
|
||||
int hit_temp_obstacle;
|
||||
qboolean hit_obstacle;
|
||||
vec3_t hit_origin;
|
||||
int hit_temp_obstacle;
|
||||
|
||||
vec3_t obstacle_normal;
|
||||
vec3_t obstacle_normal;
|
||||
} mmove_t;
|
||||
|
||||
// g_mmove.cpp
|
||||
void MmoveSingle( mmove_t *mmove );
|
||||
void MmoveSingle(mmove_t *mmove);
|
||||
|
||||
// g_vmove.cpp
|
||||
void VmoveSingle( struct vmove_s *mmove );
|
||||
void VmoveSingle(struct vmove_s *mmove);
|
||||
|
||||
// ai_main.c
|
||||
#define MAX_FILEPATH 144
|
||||
#define MAX_FILEPATH 144
|
||||
|
||||
//bot settings
|
||||
typedef struct bot_settings_s
|
||||
{
|
||||
char characterfile[MAX_FILEPATH];
|
||||
float skill;
|
||||
char team[MAX_FILEPATH];
|
||||
typedef struct bot_settings_s {
|
||||
char characterfile[MAX_FILEPATH];
|
||||
float skill;
|
||||
char team[MAX_FILEPATH];
|
||||
} bot_settings_t;
|
||||
|
||||
int BotAISetup( int restart );
|
||||
int BotAIShutdown();
|
||||
int BotAILoadMap( int restart );
|
||||
int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean restart);
|
||||
int BotAIShutdownClient( int client, qboolean restart );
|
||||
int BotAIStartFrame( int time );
|
||||
int BotAISetup(int restart);
|
||||
int BotAIShutdown();
|
||||
int BotAILoadMap(int restart);
|
||||
int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean restart);
|
||||
int BotAIShutdownClient(int client, qboolean restart);
|
||||
int BotAIStartFrame(int time);
|
||||
void BotTestAAS(vec3_t origin);
|
||||
|
||||
extern gentity_t *g_entities;
|
||||
#define FOFS(x) ((size_t)&(((gentity_t *)0)->x))
|
||||
#define FOFS(x) ((size_t) & (((gentity_t *)0)->x))
|
||||
|
||||
#include "g_utils.h"
|
||||
|
||||
#endif /* g_local.h */
|
||||
+1390
-1132
File diff suppressed because it is too large.
Load diff
+16
-16
@@ -30,28 +30,28 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
class Player;
|
||||
|
||||
extern qboolean LoadingSavegame;
|
||||
extern qboolean LoadingServer;
|
||||
extern game_import_t gi;
|
||||
extern game_export_t globals;
|
||||
extern int g_protocol;
|
||||
extern qboolean LoadingSavegame;
|
||||
extern qboolean LoadingServer;
|
||||
extern game_import_t gi;
|
||||
extern game_export_t globals;
|
||||
extern int g_protocol;
|
||||
|
||||
extern qboolean g_iInThinks;
|
||||
extern qboolean g_bBeforeThinks;
|
||||
|
||||
extern gentity_t active_edicts;
|
||||
extern gentity_t free_edicts;
|
||||
extern gentity_t active_edicts;
|
||||
extern gentity_t free_edicts;
|
||||
|
||||
extern int sv_numtraces;
|
||||
extern int sv_numpmtraces;
|
||||
extern int sv_numtraces;
|
||||
extern int sv_numpmtraces;
|
||||
|
||||
extern usercmd_t *current_ucmd;
|
||||
extern usereyes_t *current_eyeinfo;
|
||||
extern Player *g_pPlayer;
|
||||
extern usercmd_t *current_ucmd;
|
||||
extern usereyes_t *current_eyeinfo;
|
||||
extern Player *g_pPlayer;
|
||||
|
||||
void G_ExitWithError( const char *error );
|
||||
void G_AllocGameData( void );
|
||||
void G_DeAllocGameData( void );
|
||||
void G_ClientDrawBoundingBoxes( void );
|
||||
void G_ExitWithError(const char *error);
|
||||
void G_AllocGameData(void);
|
||||
void G_DeAllocGameData(void);
|
||||
void G_ClientDrawBoundingBoxes(void);
|
||||
|
||||
#endif /* g_main.h */
|
||||
@@ -172,7 +172,7 @@ qboolean MM_SlideMove
|
||||
VectorMA( mm->origin, time_left, mm->velocity, end );
|
||||
|
||||
// see if we can make it there
|
||||
gi.Trace( &trace, mm->origin, mm->mins, mm->maxs, end, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &trace, mm->origin, mm->mins, mm->maxs, end, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
|
||||
if( trace.allsolid )
|
||||
break;
|
||||
@@ -379,7 +379,7 @@ void MM_GroundTrace
|
||||
point[ 1 ] = mm->origin[ 1 ];
|
||||
point[ 2 ] = mm->origin[ 2 ] - 0.25f;
|
||||
|
||||
gi.Trace( &mml.groundTrace, mm->origin, mm->mins, mm->maxs, point, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &mml.groundTrace, mm->origin, mm->mins, mm->maxs, point, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
MM_GroundTraceInternal();
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ void MM_StepSlideMove
|
||||
|
||||
VectorCopy( start_o, down );
|
||||
down[ 2 ] -= STEPSIZE;
|
||||
gi.Trace( &trace, start_o, mm->mins, mm->maxs, down, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &trace, start_o, mm->mins, mm->maxs, down, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
VectorSet( up, 0, 0, 1 );
|
||||
|
||||
// never step up when you still have up velocity
|
||||
@@ -460,7 +460,7 @@ void MM_StepSlideMove
|
||||
down[ 2 ] -= STEPSIZE * 2;
|
||||
|
||||
// test the player position if they were a stepheight higher
|
||||
gi.Trace( &trace, up, mm->mins, mm->maxs, up, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &trace, up, mm->mins, mm->maxs, up, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
if( trace.entityNum > ENTITYNUM_NONE )
|
||||
{
|
||||
VectorCopy( nostep_o, mm->origin );
|
||||
@@ -607,7 +607,7 @@ void MmoveSingle
|
||||
point[ 1 ] = mmove->origin[ 1 ];
|
||||
point[ 2 ] = mmove->origin[ 2 ] - 18.0f;
|
||||
|
||||
gi.Trace( &trace, mm->origin, mm->mins, mm->maxs, point, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &trace, mm->origin, mm->mins, mm->maxs, point, mm->entityNum, mm->tracemask, qtrue, qfalse );
|
||||
|
||||
if( trace.fraction < 1.0f && !trace.allsolid )
|
||||
{
|
||||
|
||||
@@ -588,7 +588,7 @@ retry:
|
||||
mask = MASK_SOLID;
|
||||
}
|
||||
|
||||
trace = G_Trace( start, ent->mins, ent->maxs, end, ent, mask, false, "G_PushEntity" );
|
||||
trace = G_Trace( start, ent->mins, ent->maxs, end, ent, mask, true, "G_PushEntity" );
|
||||
|
||||
edict = ent->edict;
|
||||
|
||||
@@ -1216,7 +1216,7 @@ void G_Physics_Toss
|
||||
onconveyor = ( basevel != vec_zero );
|
||||
|
||||
// if onground, return without moving
|
||||
if( ent->groundentity && !onconveyor && ( ent->movetype != MOVETYPE_VEHICLE ) )
|
||||
if( ent->groundentity && ent->groundentity->entity->movetype == MOVETYPE_NONE && !onconveyor && ( ent->movetype != MOVETYPE_VEHICLE ) )
|
||||
{
|
||||
if( ent->avelocity.length() )
|
||||
{
|
||||
@@ -1328,7 +1328,7 @@ void G_Physics_Toss
|
||||
|
||||
// check for water transition
|
||||
wasinwater = ( ent->watertype & MASK_WATER );
|
||||
ent->watertype = gi.PointContents( ent->origin, 0 );
|
||||
ent->watertype = gi.pointcontents( ent->origin, 0 );
|
||||
isinwater = ent->watertype & MASK_WATER;
|
||||
|
||||
if( isinwater )
|
||||
@@ -1418,7 +1418,7 @@ void G_CheckWater
|
||||
Entity *ent
|
||||
)
|
||||
{
|
||||
ent->watertype = gi.PointContents( ent->origin, 0 );
|
||||
ent->watertype = gi.pointcontents( ent->origin, 0 );
|
||||
if( ent->watertype & MASK_WATER )
|
||||
{
|
||||
ent->waterlevel = 1;
|
||||
|
||||
+2
-1
@@ -57,7 +57,8 @@ typedef enum
|
||||
MOVETYPE_SLIDE,
|
||||
MOVETYPE_GIB,
|
||||
MOVETYPE_VEHICLE,
|
||||
MOVETYPE_TURRET
|
||||
MOVETYPE_TURRET,
|
||||
MOVETYPE_PORTABLE_TURRET
|
||||
} movetype_t;
|
||||
|
||||
typedef struct
|
||||
|
||||
+18
-15
@@ -43,7 +43,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#define SVF_CLIENTMASK 0x00000002
|
||||
|
||||
#define SVF_BROADCAST 0x00000004 // send to all connected clients
|
||||
#define SVF_BOT 0x00000008 // set if the entity is a bot
|
||||
#define SVF_MONSTER 0x00000008 // set if the entity is a bot
|
||||
#define SVF_PORTAL 0x00000040 // merge a second pvs at origin2 into snapshots
|
||||
#define SVF_USE_CURRENT_ORIGIN 0x00000080 // entity->r.currentOrigin instead of entity->s.origin
|
||||
// for link position (missiles and movers)
|
||||
@@ -120,18 +120,18 @@ typedef struct {
|
||||
typedef struct {
|
||||
char userinfo[ MAX_INFO_STRING ];
|
||||
char netname[ MAX_NAME_LENGTH ];
|
||||
char playermodel[ MAX_QPATH ];
|
||||
char playergermanmodel[ MAX_QPATH ];
|
||||
char weapon[ MAX_QPATH ];
|
||||
char dm_playermodel[ MAX_QPATH ];
|
||||
char dm_playergermanmodel[ MAX_QPATH ];
|
||||
char dm_primary[ MAX_QPATH ];
|
||||
|
||||
float enterTime;
|
||||
|
||||
teamtype_t team;
|
||||
int kills;
|
||||
teamtype_t teamnum;
|
||||
int round_kills;
|
||||
|
||||
char ip[ 17 ];
|
||||
int port;
|
||||
} clientPersistant_t;
|
||||
} client_persistant_t;
|
||||
|
||||
|
||||
// this structure is cleared on each ClientSpawn(),
|
||||
@@ -143,7 +143,7 @@ struct gclient_s {
|
||||
#ifdef GAME_DLL
|
||||
// the rest of the structure is private to game
|
||||
int ping;
|
||||
clientPersistant_t pers;
|
||||
client_persistant_t pers;
|
||||
float cmd_angles[ 3 ];
|
||||
|
||||
int lastActiveTime;
|
||||
@@ -231,10 +231,11 @@ typedef struct gameImport_s
|
||||
void ( *Error )( int level, const char *format, ... );
|
||||
int ( *Milliseconds )( );
|
||||
const char * ( *LV_ConvertString )( const char *string );
|
||||
const char * ( *CL_LV_ConvertString )( const char *string );
|
||||
void * ( *Malloc )( size_t size );
|
||||
void ( *Free )( void *ptr );
|
||||
cvar_t * ( *Cvar_Get )( const char *varName, const char *varValue, int varFlags );
|
||||
void ( *Cvar_Set )( const char *varName, const char *varValue );
|
||||
void ( *cvar_set )( const char *varName, const char *varValue );
|
||||
cvar_t *( *cvar_set2 )( const char *varName, const char *varValue, qboolean force );
|
||||
cvar_t *( *NextCvar )( cvar_t *var );
|
||||
int ( *Argc )( );
|
||||
@@ -280,26 +281,27 @@ typedef struct gameImport_s
|
||||
void ( *SetBroadcastVisible )( const vec3_t pos, const vec3_t posB );
|
||||
void ( *SetBroadcastHearable )(const vec3_t pos, const vec3_t posB );
|
||||
void ( *SetBroadcastAll )( );
|
||||
void ( *SetConfigstring )( int index, const char *val );
|
||||
char *( *GetConfigstring )( int index );
|
||||
void ( *setConfigstring )( int index, const char *val );
|
||||
char *( *getConfigstring )( int index );
|
||||
void ( *SetUserinfo )( int index, const char *val );
|
||||
void ( *GetUserinfo )( int index, char *buffer, int bufferSize );
|
||||
void ( *SetBrushModel )( gentity_t *ent, const char *name );
|
||||
void ( *ModelBoundsFromName )(const char *name, vec3_t mins, vec3_t maxs );
|
||||
qboolean ( *SightTraceEntity )( gentity_t *touch, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int contentMask, qboolean cylinder );
|
||||
qboolean ( *SightTrace )( const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int passEntityNum2, int contentMask, qboolean cylinder );
|
||||
void ( *Trace )( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask, qboolean cylinder, qboolean traceDeep );
|
||||
void ( *trace )( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask, qboolean cylinder, qboolean traceDeep );
|
||||
baseshader_t * ( *GetShader )( int shaderNum );
|
||||
int ( *PointContents )( const vec3_t p, int passEntityNum );
|
||||
int ( *pointcontents )( const vec3_t p, int passEntityNum );
|
||||
int ( *PointBrushnum )(const vec3_t p, clipHandle_t model );
|
||||
void ( *AdjustAreaPortalState )( gentity_t *ent, qboolean open );
|
||||
int ( *AreaForPoint )( vec3_t pos );
|
||||
qboolean ( *AreasConnected )( int area1, int area2);
|
||||
qboolean ( *InPVS )( float *p1, float *p2 );
|
||||
void ( *LinkEntity )( gentity_t *gEnt );
|
||||
void ( *UnlinkEntity )( gentity_t *gEnt );
|
||||
void ( *linkentity )( gentity_t *gEnt );
|
||||
void ( *unlinkentity )( gentity_t *gEnt );
|
||||
int ( *AreaEntities )( const vec3_t mins, const vec3_t maxs, int *list, int maxcount );
|
||||
void ( *ClipToEntity )( trace_t *tr, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int entityNum, int contentMask );
|
||||
qboolean (*HitEntity)(gentity_t* pEnt, gentity_t* pOther);
|
||||
int ( *imageindex )( const char *name );
|
||||
int ( *itemindex )( const char *name );
|
||||
int ( *soundindex )( const char *name, int streamed );
|
||||
@@ -325,6 +327,7 @@ typedef struct gameImport_s
|
||||
void ( *Anim_Delta )( dtiki_t *tiki, int animNum, float *delta );
|
||||
qboolean ( *Anim_HasDelta )( dtiki_t *tiki, int animNum );
|
||||
void ( *Anim_DeltaOverTime )( dtiki_t *tiki, int animNum, float time1, float time2, float *delta );
|
||||
void ( *Anim_AngularDeltaOverTime )( dtiki_t *tiki, int animNum, float time1, float time2, float *delta );
|
||||
int ( *Anim_Flags )( dtiki_t *tiki, int animNum );
|
||||
int ( *Anim_FlagsSkel )( dtiki_t *tiki, int animNum );
|
||||
qboolean ( *Anim_HasCommands )( dtiki_t *tiki, int animNum );
|
||||
|
||||
@@ -45,10 +45,10 @@ Called on game shutdown
|
||||
*/
|
||||
void G_WriteClientSessionData( gclient_t *client )
|
||||
{
|
||||
gi.Cvar_Set( va( "session%i", ( int )( client - game.clients ) ),
|
||||
va( "%s %i %i", client->pers.weapon[ 0 ] ? client->pers.weapon : "-",
|
||||
client->pers.team,
|
||||
client->pers.kills ) );
|
||||
gi.cvar_set( va( "session%i", ( int )( client - game.clients ) ),
|
||||
va( "%s %i %i", client->pers.dm_primary[ 0 ] ? client->pers.dm_primary : "-",
|
||||
client->pers.teamnum,
|
||||
client->pers.round_kills) );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -68,10 +68,10 @@ void G_ReadSessionData( gclient_t *client )
|
||||
|
||||
session = gi.Cvar_Get(va("session%zi", client - game.clients), "", 0);
|
||||
|
||||
sscanf( session->string, "%s %i %i", client->pers.weapon, &client->pers.team, &client->pers.kills );
|
||||
if( client->pers.weapon[ 0 ] == '-' )
|
||||
sscanf( session->string, "%s %i %i", client->pers.dm_primary, &client->pers.teamnum, &client->pers.round_kills);
|
||||
if( client->pers.dm_primary[ 0 ] == '-' )
|
||||
{
|
||||
client->pers.weapon[ 0 ] = 0;
|
||||
client->pers.dm_primary[ 0 ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ G_InitSessionData
|
||||
Called on a first-time connect
|
||||
================
|
||||
*/
|
||||
void G_InitSessionData( gclient_t *client, char *userinfo )
|
||||
void G_InitSessionData( gclient_t *client, const char *userinfo )
|
||||
{
|
||||
G_WriteClientSessionData( client );
|
||||
}
|
||||
@@ -119,7 +119,7 @@ G_WriteSessionData
|
||||
void G_WriteSessionData( void ) {
|
||||
int i;
|
||||
|
||||
gi.Cvar_Set( "session", va( "%i", g_gametype->integer ) );
|
||||
gi.cvar_set( "session", va( "%i", g_gametype->integer ) );
|
||||
|
||||
for ( i = 0 ; i < game.maxclients ; i++ )
|
||||
{
|
||||
|
||||
@@ -564,7 +564,7 @@ Listener *SpawnArgs::SpawnInternal( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
ev = new Event( keyname, EV_SETTER );
|
||||
ev = new Event(eventnum);
|
||||
ev->AddString( value );
|
||||
|
||||
obj->PostEvent( ev, EV_SPAWNARG );
|
||||
@@ -1039,7 +1039,7 @@ qboolean G_CallSpawn( gentity_t *ent ) {
|
||||
}
|
||||
ent->s.frameInfo[0].weight = 1.f;
|
||||
G_SetOrigin( ent, ent->s.origin );
|
||||
gi.LinkEntity (ent);
|
||||
gi.linkentity (ent);
|
||||
return qtrue;
|
||||
#endif
|
||||
}
|
||||
@@ -1332,13 +1332,13 @@ void SP_worldspawn( void ) {
|
||||
gi.SetConfigstring( CS_MOTD, g_motd.string ); // message of the day
|
||||
|
||||
G_SpawnString( "gravity", "800", &s );
|
||||
gi.Cvar_Set( "g_gravity", s );
|
||||
gi.cvar_set( "g_gravity", s );
|
||||
|
||||
G_SpawnString( "enableDust", "0", &s );
|
||||
gi.Cvar_Set( "g_enableDust", s );
|
||||
gi.cvar_set( "g_enableDust", s );
|
||||
|
||||
G_SpawnString( "enableBreath", "0", &s );
|
||||
gi.Cvar_Set( "g_enableBreath", s );
|
||||
gi.cvar_set( "g_enableBreath", s );
|
||||
|
||||
for( i = 0; i < level.numSpawnVars; i++ )
|
||||
{
|
||||
@@ -1354,7 +1354,7 @@ void SP_worldspawn( void ) {
|
||||
// see if we want a warmup time
|
||||
gi.SetConfigstring( CS_WARMUP, "" );
|
||||
if ( g_restarted.integer ) {
|
||||
gi.Cvar_Set( "g_restarted", "0" );
|
||||
gi.cvar_set( "g_restarted", "0" );
|
||||
level.warmupTime = 0;
|
||||
} else if ( g_doWarmup.integer ) { // Turn it on
|
||||
level.warmupTime = -1;
|
||||
|
||||
+2040
-2530
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
class Archiver;
|
||||
class Entity;
|
||||
class SimpleEntity;
|
||||
class SimpleArchivedEntity;
|
||||
class ScriptThread;
|
||||
|
||||
void G_ArchiveEdict(Archiver& arc, gentity_t *edict);
|
||||
|
||||
void G_AllocDebugLines(void);
|
||||
void G_DeAllocDebugLines(void);
|
||||
|
||||
void G_TouchTriggers(Entity *ent);
|
||||
void G_TouchSolids(Entity *ent);
|
||||
|
||||
Entity *G_FindClass(Entity *ent, const char *classname);
|
||||
Entity *G_NextEntity(Entity *ent);
|
||||
|
||||
void G_CalcBoundsOfMove(Vector& start, Vector& end, Vector& mins, Vector& maxs, Vector *minbounds, Vector *maxbounds);
|
||||
|
||||
void G_ShowTrace(trace_t *trace, const gentity_t *passent, const char *reason);
|
||||
void G_ShowSightTrace(trace_t *trace, const gentity_t *passent, const char *reason);
|
||||
|
||||
bool G_SightTrace(
|
||||
const Vector& start,
|
||||
const Vector& mins,
|
||||
const Vector& maxs,
|
||||
const Vector& end,
|
||||
Entity *passent,
|
||||
Entity *passent2,
|
||||
int contentmask,
|
||||
qboolean cylindrical,
|
||||
const char *reason
|
||||
);
|
||||
bool G_SightTrace(
|
||||
const Vector& start,
|
||||
const Vector& mins,
|
||||
const Vector& maxs,
|
||||
const Vector& end,
|
||||
gentity_t *passent,
|
||||
gentity_t *passent2,
|
||||
int contentmask,
|
||||
qboolean cylindrical,
|
||||
const char *reason
|
||||
);
|
||||
|
||||
void G_PMDrawTrace(
|
||||
trace_t *results,
|
||||
const vec3_t start,
|
||||
const vec3_t mins,
|
||||
const vec3_t maxs,
|
||||
const vec3_t end,
|
||||
int passEntityNum,
|
||||
int contentMask,
|
||||
qboolean cylinder,
|
||||
qboolean traceDeep
|
||||
);
|
||||
|
||||
trace_t G_Trace(
|
||||
const Vector& start,
|
||||
const Vector& mins,
|
||||
const Vector& maxs,
|
||||
const Vector& end,
|
||||
const Entity *passent,
|
||||
int contentmask,
|
||||
qboolean cylindrical,
|
||||
const char *reason,
|
||||
qboolean tracedeep = qfalse
|
||||
);
|
||||
trace_t G_Trace(
|
||||
vec3_t start,
|
||||
vec3_t mins,
|
||||
vec3_t maxs,
|
||||
vec3_t end,
|
||||
const gentity_t *passent,
|
||||
int contentmask,
|
||||
qboolean cylindrical,
|
||||
const char *reason,
|
||||
qboolean tracedeep = qfalse
|
||||
);
|
||||
void G_TraceEntities(
|
||||
Vector & start,
|
||||
Vector & mins,
|
||||
Vector & maxs,
|
||||
Vector & end,
|
||||
Container<Entity *> *victimlist,
|
||||
int contentmask,
|
||||
qboolean bIncludeTriggers = qfalse
|
||||
);
|
||||
|
||||
void SelectSpawnPoint(Vector& org, Vector& angles, str& thread);
|
||||
|
||||
Entity *G_FindTarget(Entity *ent, const char *name);
|
||||
Entity *G_FindRandomTarget(const char *name);
|
||||
SimpleEntity *G_FindRandomSimpleTarget(const char *name);
|
||||
Entity *G_NextEntity(Entity *ent);
|
||||
|
||||
qboolean M_CheckBottom(Entity *ent);
|
||||
|
||||
Vector G_GetMovedir(float angle);
|
||||
qboolean KillBox(Entity *ent);
|
||||
qboolean IsNumeric(const char *str);
|
||||
|
||||
Entity *findradius(Entity *startent, Vector org, float rad);
|
||||
Entity *findclientsinradius(Entity *startent, Vector org, float rad);
|
||||
|
||||
Vector G_CalculateImpulse(Vector start, Vector end, float speed, float gravity);
|
||||
Vector G_PredictPosition(Vector start, Vector target, Vector targetvelocity, float speed);
|
||||
|
||||
qboolean G_LoadAndExecScript(const char *filename, const char *label = NULL, qboolean quiet = qfalse);
|
||||
ScriptThread *ExecuteThread(str thread_name, qboolean start = true);
|
||||
|
||||
int MOD_string_to_int(const str &immune_string);
|
||||
qboolean MOD_matches(int incoming_damage, int damage_type);
|
||||
|
||||
void G_MissionFailed(void);
|
||||
void G_FadeOut(float delaytime);
|
||||
void G_FadeSound(float delaytime);
|
||||
void G_RestartLevelWithDelay(float delaytime);
|
||||
void G_PlayerDied(float delaytime);
|
||||
void G_AutoFadeIn(void);
|
||||
void G_ClearFade(void);
|
||||
void G_StartCinematic(void);
|
||||
void G_StopCinematic(void);
|
||||
|
||||
// copy the entity exactly including all its children
|
||||
void CloneEntity(Entity *dest, Entity *src);
|
||||
|
||||
qboolean OnSameTeam(Entity *ent1, Entity *ent2);
|
||||
|
||||
//
|
||||
// caching commands
|
||||
//
|
||||
void CacheResource(const char *stuff);
|
||||
int modelIndex(const char *mdl);
|
||||
|
||||
void G_SetTrajectory(gentity_t *ent, vec3_t org);
|
||||
void G_SetConstantLight(
|
||||
int *constantlight, float *red, float *green, float *blue, float *radius, int *lightstyle = NULL
|
||||
);
|
||||
|
||||
void ChangeMusic(const char *current, const char *fallback, qboolean force);
|
||||
|
||||
void ChangeMusicVolume(float volume, float fade_time);
|
||||
|
||||
void RestoreMusicVolume(float fade_time);
|
||||
|
||||
void ChangeSoundtrack(const char *soundtrack);
|
||||
|
||||
void RestoreSoundtrack(void);
|
||||
|
||||
void G_BroadcastSound(Entity *ent, Vector origin, float radius = SOUND_RADIUS);
|
||||
|
||||
SimpleArchivedEntity *G_FindArchivedClass(SimpleArchivedEntity *ent, const char *classname);
|
||||
Entity *G_FindClass(Entity *ent, const char *classname);
|
||||
int G_GetClientNumber(gentity_t *ent);
|
||||
int G_GetClientNumber(Entity *ent);
|
||||
Entity *G_GetEntityByClient(int clientNum);
|
||||
int G_GetEntityIndex(int number);
|
||||
int G_GetEntityIndex(gentity_t *ent);
|
||||
gentity_t *G_GetGEntity(int id);
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Inline functions
|
||||
//
|
||||
//==================================================================
|
||||
|
||||
/*
|
||||
=================
|
||||
G_GetEntity
|
||||
|
||||
Takes an index to an entity and returns pointer to it.
|
||||
=================
|
||||
*/
|
||||
|
||||
inline Entity *G_GetEntity(int entnum)
|
||||
|
||||
{
|
||||
if ((entnum < 0) || (entnum >= globals.max_entities)) {
|
||||
gi.Error(ERR_DROP, "G_GetEntity: %d out of valid range.", entnum);
|
||||
}
|
||||
|
||||
return (Entity *)g_entities[entnum].entity;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
G_Random
|
||||
|
||||
Returns a number from 0<= num < 1
|
||||
|
||||
random()
|
||||
=================
|
||||
*/
|
||||
|
||||
inline float G_Random(void)
|
||||
|
||||
{
|
||||
return ((float)(rand() & 0x7fff)) / ((float)0x8000);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
G_Random
|
||||
|
||||
Returns a number from 0 <= num < n
|
||||
|
||||
random()
|
||||
=================
|
||||
*/
|
||||
|
||||
inline float G_Random(float n)
|
||||
|
||||
{
|
||||
return G_Random() * n;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
G_CRandom
|
||||
|
||||
Returns a number from -1 <= num < 1
|
||||
|
||||
crandom()
|
||||
=================
|
||||
*/
|
||||
|
||||
inline float G_CRandom(void)
|
||||
|
||||
{
|
||||
return G_Random(2) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
G_CRandom
|
||||
|
||||
Returns a number from -n <= num < n
|
||||
|
||||
crandom()
|
||||
=================
|
||||
*/
|
||||
|
||||
inline float G_CRandom(float n)
|
||||
|
||||
{
|
||||
return G_CRandom() * n;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
G_FixSlashes
|
||||
|
||||
Converts all backslashes in a string to forward slashes.
|
||||
Used to make filenames consistant.
|
||||
=================
|
||||
*/
|
||||
|
||||
inline str G_FixSlashes(const char *filename)
|
||||
|
||||
{
|
||||
int i;
|
||||
size_t len;
|
||||
str text;
|
||||
|
||||
if (filename) {
|
||||
// Convert all forward slashes to back slashes
|
||||
text = filename;
|
||||
len = text.length();
|
||||
for (i = 0; i < len; i++) {
|
||||
if (text[i] == '\\') {
|
||||
text[i] = '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
WEAPON_MAIN,
|
||||
WEAPON_OFFHAND,
|
||||
WEAPON_ERROR
|
||||
} weaponhand_t;
|
||||
|
||||
#define NUM_ACTIVE_WEAPONS WEAPON_ERROR
|
||||
|
||||
typedef enum {
|
||||
FIRE_PRIMARY,
|
||||
FIRE_SECONDARY,
|
||||
MAX_FIREMODES,
|
||||
FIRE_ERROR
|
||||
} firemode_t;
|
||||
|
||||
firemode_t WeaponModeNameToNum(str mode);
|
||||
const char *WeaponHandNumToName(weaponhand_t hand);
|
||||
weaponhand_t WeaponHandNameToNum(str side);
|
||||
void G_DebugTargets(Entity *e, str from);
|
||||
void G_DebugDamage(float damage, Entity *victim, Entity *attacker, Entity *inflictor);
|
||||
@@ -157,7 +157,7 @@ qboolean VM_SlideMove
|
||||
VectorMA( vm->vs->origin, time_left, vm->vs->velocity, end );
|
||||
|
||||
// see if we can make it there
|
||||
gi.Trace( &trace, vm->vs->origin, vm->mins, vm->maxs, end, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &trace, vm->vs->origin, vm->mins, vm->maxs, end, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
|
||||
if( trace.allsolid )
|
||||
break;
|
||||
@@ -351,7 +351,7 @@ void VM_GroundTrace
|
||||
point[ 1 ] = vm->vs->origin[ 1 ];
|
||||
point[ 2 ] = vm->vs->origin[ 2 ] - 0.25f;
|
||||
|
||||
gi.Trace( &vm->vs->groundTrace, vm->vs->origin, vm->mins, vm->maxs, point, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &vm->vs->groundTrace, vm->vs->origin, vm->mins, vm->maxs, point, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
VM_GroundTraceInternal();
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ void VM_StepSlideMove
|
||||
|
||||
VectorCopy( start_o, down );
|
||||
down[ 2 ] -= STEPSIZE;
|
||||
gi.Trace( &trace, start_o, vm->mins, vm->maxs, down, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &trace, start_o, vm->mins, vm->maxs, down, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
VectorSet( up, 0, 0, 1 );
|
||||
|
||||
// never step up when you still have up velocity
|
||||
@@ -432,7 +432,7 @@ void VM_StepSlideMove
|
||||
down[ 2 ] -= STEPSIZE * 2;
|
||||
|
||||
// test the player position if they were a stepheight higher
|
||||
gi.Trace( &trace, up, vm->mins, vm->maxs, up, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &trace, vm->vs->origin, vm->mins, vm->maxs, down, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
if( trace.entityNum > ENTITYNUM_NONE )
|
||||
{
|
||||
VectorCopy( nostep_o, vm->vs->origin );
|
||||
@@ -624,7 +624,7 @@ void VmoveSingle
|
||||
point[ 1 ] = vm->vs->origin[ 1 ];
|
||||
point[ 2 ] = vm->vs->origin[ 2 ] - 18.0f;
|
||||
|
||||
gi.Trace( &trace, vm->vs->origin, vm->mins, vm->maxs, point, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
gi.trace( &trace, vm->vs->origin, vm->mins, vm->maxs, point, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
|
||||
|
||||
if( trace.fraction < 1.0f && !trace.allsolid )
|
||||
{
|
||||
|
||||
Loaded 100 of 269 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user