mirror of
https://github.com/s1lentq/ReGameDLL_CS.git
synced 2025-05-12 06:49:32 +03:00
Compare commits
189 Commits
5.21.0.593
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
8d5aa54ceb | ||
|
a4f48f4e42 | ||
|
99d93ba8a7 | ||
|
5bf71bdb18 | ||
|
797c265db3 | ||
|
312dc3eb84 | ||
|
0fc5213049 | ||
|
f3d8d1b5fd | ||
|
a4d74392f0 | ||
|
35082b5f26 | ||
|
6f70d6dd8e | ||
|
f5cc6f3a8b | ||
|
d3fc7ac000 | ||
|
ce11175e89 | ||
|
b10f23e1e9 | ||
|
b44b09d07b | ||
|
d8faea0966 | ||
|
94a7eb4cbb | ||
|
518f142635 | ||
|
dbec1b589c | ||
|
316405b00d | ||
|
b8e9726347 | ||
|
6adb795fee | ||
|
756deb1ea9 | ||
|
a7395b054d | ||
|
b59bbb1c83 | ||
|
96b2ef2727 | ||
|
f63ad678c2 | ||
|
1579273f62 | ||
|
17ae24e012 | ||
|
1a17ef4e45 | ||
|
6f0d17bb74 | ||
|
8a77bba94d | ||
|
3efc5ad166 | ||
|
942f2e6637 | ||
|
df7944ab88 | ||
|
476b5f7afd | ||
|
7738142c69 | ||
|
535ea846a9 | ||
|
9b626b1d82 | ||
|
9b7b1695a9 | ||
|
3f628ea970 | ||
|
19714af6e6 | ||
|
3cf66de905 | ||
|
dc16b12d79 | ||
|
12f4e9bc79 | ||
|
a8fd512dad | ||
|
8b6d659077 | ||
|
4e1cb1091f | ||
|
b6c2c62e8b | ||
|
c7bd4af9b6 | ||
|
fee10d8ba8 | ||
|
c48be87474 | ||
|
77a3f2b25b | ||
|
279799bff9 | ||
|
17386acac4 | ||
|
11638cbb21 | ||
|
a47d55823f | ||
|
ff843fe478 | ||
|
9d9c2de1ff | ||
|
a202425dd7 | ||
|
576e967cbd | ||
|
1991434301 | ||
|
79cfd7103a | ||
|
30572ef0b6 | ||
|
8005dd9ca3 | ||
|
a94c7bd728 | ||
|
ad1c58cef5 | ||
|
fef9bf3a87 | ||
|
bdc96d26d9 | ||
|
c7be8bfe7c | ||
|
7372573c89 | ||
|
c08e6d0180 | ||
|
9f66264562 | ||
|
8706cc5a10 | ||
|
cabdc254c7 | ||
|
8ff1bf1232 | ||
|
8ec5b6cd0f | ||
|
4ecf42799d | ||
|
d7f22ae3ec | ||
|
75f142e18a | ||
|
8cd9086937 | ||
|
2a0e54bbf7 | ||
|
0626800fbb | ||
|
d5eb9c34d2 | ||
|
f24cccfe73 | ||
|
5117374a27 | ||
|
279bd6421b | ||
|
8c14d05168 | ||
|
1ae0091947 | ||
|
f711276d8a | ||
|
a546997723 | ||
|
92775824e6 | ||
|
5d2174fbbf | ||
|
4d90a5f4fa | ||
|
f4c4e891ac | ||
|
2489213127 | ||
|
fb9eb0db55 | ||
|
0bc4ff1d40 | ||
|
5287f2a415 | ||
|
0bbc4bd55d | ||
|
aec3ba2579 | ||
|
b34d564e3c | ||
|
a1af7ca426 | ||
|
bde6aa07bc | ||
|
2d957a7915 | ||
|
4b49f630da | ||
|
051dc0751a | ||
|
89dda43b21 | ||
|
02a0516c2f | ||
|
c0f47949ec | ||
|
e636cbc8f5 | ||
|
15df1a9cf2 | ||
|
71606f8f36 | ||
|
d3c0ec8aeb | ||
|
991573f165 | ||
|
6c9019bcc8 | ||
|
0e68bedf24 | ||
|
28e2bc45f6 | ||
|
b413577428 | ||
|
f63b154637 | ||
|
8c0b684046 | ||
|
abe648b9d6 | ||
|
db5cbee2b8 | ||
|
4928c56f21 | ||
|
f97c9d9f46 | ||
|
806f5651de | ||
|
85e882f4db | ||
|
8ed193d254 | ||
|
e6d25ba159 | ||
|
34e56f61f2 | ||
|
d98e8f8b60 | ||
|
a63bcf0a10 | ||
|
59362ec8d5 | ||
|
4f0818b7bf | ||
|
7c9582f44b | ||
|
0c29cf36fc | ||
|
5e2aadceac | ||
|
7ea9beffdf | ||
|
e5f546c453 | ||
|
6863777b81 | ||
|
f882e81efe | ||
|
d135a67bb7 | ||
|
556406009f | ||
|
15bca2eab9 | ||
|
fba9a335da | ||
|
193c1ed52a | ||
|
b10489f2e0 | ||
|
9ab1589d32 | ||
|
e3d70d2b14 | ||
|
2d0ac93f63 | ||
|
c87761e182 | ||
|
2857986cc7 | ||
|
96e2121c45 | ||
|
426c975a88 | ||
|
7e02dea4a0 | ||
|
a2678a18ed | ||
|
e422a37d8b | ||
|
2f50f5ab9d | ||
|
a9ec63df1b | ||
|
96ba309e4a | ||
|
3a0970a1cd | ||
|
ac07e89269 | ||
|
b962e0eb8e | ||
|
1e49d94792 | ||
|
71c4e21385 | ||
|
108db28143 | ||
|
67e7d87423 | ||
|
8a52b7e38d | ||
|
d7b44099e7 | ||
|
ee34b06605 | ||
|
7b7a1b9d94 | ||
|
1aae57fd17 | ||
|
728f1fcc67 | ||
|
e8bff71475 | ||
|
facc2be534 | ||
|
2e6e77906f | ||
|
f441279294 | ||
|
696f465977 | ||
|
f3723d7a04 | ||
|
02bb06a6ef | ||
|
53d26a7ea5 | ||
|
942776783b | ||
|
c526fa5885 | ||
|
ad13545dac | ||
|
718f0330f1 | ||
|
8a8f348755 | ||
|
11d6b086b4 | ||
|
8a18969be1 |
145
.github/workflows/build.yml
vendored
145
.github/workflows/build.yml
vendored
@ -24,23 +24,18 @@ jobs:
|
||||
buildTests: 'Tests'
|
||||
|
||||
steps:
|
||||
- name: Configure
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Nuget
|
||||
uses: nuget/setup-nuget@v1
|
||||
with:
|
||||
nuget-api-key: ${{ secrets.NuGetAPIKey }}
|
||||
nuget-version: '5.x'
|
||||
|
||||
- run: nuget restore '${{ env.solution }}'
|
||||
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v1.1.3
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
with:
|
||||
vs-version: '16.8'
|
||||
vs-version: '16'
|
||||
|
||||
- name: Build and Run unittests
|
||||
run: |
|
||||
@ -66,93 +61,76 @@ jobs:
|
||||
move msvc\${{ env.buildRelease }}\mp.pdb publish\debug\mp.pdb
|
||||
|
||||
- name: Deploy artifacts
|
||||
uses: actions/upload-artifact@v3.1.1
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: win32
|
||||
path: publish/*
|
||||
|
||||
testdemos:
|
||||
name: 'Test demos'
|
||||
runs-on: ubuntu-20.04
|
||||
container: s1lentq/testdemos:latest
|
||||
runs-on: ubuntu-latest
|
||||
container: rehldsorg/testdemos:latest
|
||||
needs: [windows]
|
||||
|
||||
env:
|
||||
WINEDEBUG: -all
|
||||
WINEDLLOVERRIDES: mshtml=
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: ../../../opt/HLDS
|
||||
working-directory: /opt/HLDS
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
test: [
|
||||
{ file: 'cstrike-basic-1', desc: 'CS: Testing jumping, scenarios, shooting etc' },
|
||||
]
|
||||
|
||||
steps:
|
||||
- name: Deploying windows artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: win32
|
||||
|
||||
- name: Play demos
|
||||
- name: Setup dependencies
|
||||
run: |
|
||||
chown root ~
|
||||
rsync -a deps/regamedll/* .
|
||||
mv $GITHUB_WORKSPACE/tests/mp.dll cstrike/dlls/mp.dll
|
||||
|
||||
descs=(
|
||||
"CS: Testing jumping, scenarios, shooting etc"
|
||||
)
|
||||
|
||||
demos=(
|
||||
"cstrike-basic-1"
|
||||
)
|
||||
|
||||
retVal=0
|
||||
for i in "${!demos[@]}"; do
|
||||
params=$(cat "testdemos/${demos[i]}.params")
|
||||
|
||||
echo -e "\e[1m[$((i + 1))/${#demos[@]}] \e[1;36m${descs[i]} testing...\e[0m"
|
||||
echo -e " - \e[0;33mParameters $params\e[0m"
|
||||
|
||||
wine hlds.exe --rehlds-enable-all-hooks --rehlds-test-play "testdemos/${demos[i]}.bin" $params &> result.log || retVal=$?
|
||||
|
||||
if [ $retVal -ne 777 ] && [ $retVal -ne 9 ]; then
|
||||
# Print with catchy messages
|
||||
while read line; do
|
||||
echo -e " \e[0;33m$line"
|
||||
done <<< $(cat result.log | sed '0,/demo failed/I!d;/wine:/d;/./,$!d')
|
||||
|
||||
echo " 🔸 🔸 🔸 🔸 🔸 🔸 🔸 🔸 🔸 🔸"
|
||||
while read line; do
|
||||
echo -e " \e[1;31m$line";
|
||||
done < rehlds_demo_error.txt
|
||||
echo -e " \e[30;41mExit code: $retVal\e[0m"
|
||||
echo -e "\e[1m[$((i + 1))/${#demos[@]}] \e[1;36m${descs[i]} testing...\e[1;31m Failed ❌"
|
||||
exit 6 # Test demo failed
|
||||
else
|
||||
# Print result HLDS console
|
||||
while read line; do
|
||||
echo -e " \e[0;33m$line"
|
||||
done <<< $(cat result.log | sed '/wine:/d;/./,$!d')
|
||||
echo -e " \e[30;43mExit code: $retVal\e[0m"
|
||||
echo -e "\e[1m[$((i + 1))/${#demos[@]}] \e[1;36m${descs[i]} testing...\e[1;32m Succeed ✔"
|
||||
fi
|
||||
done
|
||||
- name: Play test
|
||||
env:
|
||||
demo: ${{ matrix.test.file }}
|
||||
desc: ${{ matrix.test.desc }}
|
||||
run: ./runTest.sh
|
||||
|
||||
linux:
|
||||
name: 'Linux'
|
||||
runs-on: ubuntu-20.04
|
||||
container: s1lentq/linux86buildtools:latest
|
||||
runs-on: ubuntu-latest
|
||||
container: debian:11-slim
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
dpkg --add-architecture i386
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
gcc-multilib g++-multilib \
|
||||
build-essential \
|
||||
libc6-dev libc6-dev-i386 \
|
||||
git cmake rsync \
|
||||
g++ gcc
|
||||
|
||||
- name: Configure
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: Build and Run unittests
|
||||
run: |
|
||||
rm -rf build && CC=icc CXX=icpc cmake -DCMAKE_BUILD_TYPE=Unittests -B build && cmake --build build -j8
|
||||
rm -rf build && CC=gcc CXX=g++ cmake -DCMAKE_BUILD_TYPE=Unittests -B build && cmake --build build -j8
|
||||
retVal=0
|
||||
./build/regamedll/cs 2> /dev/null > result.log || retVal=$?
|
||||
while read line; do
|
||||
@ -173,17 +151,9 @@ jobs:
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Build using Intel C++ Compiler 19.0 (only for release)
|
||||
if: |
|
||||
github.event_name == 'release' &&
|
||||
github.event.action == 'published' &&
|
||||
startsWith(github.ref, 'refs/tags/')
|
||||
- name: Build using GCC Compiler
|
||||
run: |
|
||||
rm -rf build-icc && CC=icc CXX=icpc cmake -B build-icc && cmake --build build-icc -j8
|
||||
|
||||
- name: Build using GCC Compiler 9.3
|
||||
run: |
|
||||
rm -rf build-gcc && CC=gcc CXX=g++ cmake -B build-gcc && cmake --build build-gcc -j8
|
||||
rm -rf build && CC=gcc CXX=g++ cmake -B build && cmake --build build -j8
|
||||
|
||||
- name: Prepare CSSDK
|
||||
run: |
|
||||
@ -193,8 +163,7 @@ jobs:
|
||||
- name: Move files
|
||||
run: |
|
||||
mkdir -p publish/bin/linux32/cstrike/dlls
|
||||
mv build-icc/regamedll/cs.so publish/bin/linux32/cstrike/dlls/cs.so 2>/dev/null || true
|
||||
mv build-gcc/regamedll/cs.so publish/cs-gcc.so
|
||||
mv build/regamedll/cs.so publish/bin/linux32/cstrike/dlls/cs.so 2>/dev/null || true
|
||||
mv regamedll/version/appversion.h publish/appversion.h
|
||||
mv dist/ publish/
|
||||
|
||||
@ -202,7 +171,6 @@ jobs:
|
||||
run: |
|
||||
binaries=(
|
||||
"publish/bin/linux32/cstrike/dlls/cs.so"
|
||||
"publish/cs-gcc.so"
|
||||
)
|
||||
bash ./regamedll/version/glibc_test.sh ${binaries[@]}
|
||||
if [[ $? -ne 0 ]]; then
|
||||
@ -211,31 +179,25 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Deploy artifacts
|
||||
uses: actions/upload-artifact@v3.1.1
|
||||
uses: actions/upload-artifact@v4
|
||||
id: upload-job
|
||||
with:
|
||||
name: linux32
|
||||
path: publish/*
|
||||
|
||||
- name: Cleanup temporary artifacts
|
||||
if: success() && steps.upload-job.outcome == 'success'
|
||||
run: |
|
||||
rm -rf cssdk
|
||||
rm -f appversion.h
|
||||
|
||||
publish:
|
||||
name: 'Publish'
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [windows, testdemos, linux]
|
||||
|
||||
steps:
|
||||
- name: Deploying linux artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: linux32
|
||||
|
||||
- name: Deploying windows artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: win32
|
||||
|
||||
@ -265,7 +227,7 @@ jobs:
|
||||
7z a -tzip regamedll-bin-${{ env.APP_VERSION }}.zip bin/ cssdk/
|
||||
|
||||
- name: Publish artifacts
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
id: publish-job
|
||||
if: |
|
||||
startsWith(github.ref, 'refs/tags/') &&
|
||||
@ -276,8 +238,3 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.API_TOKEN }}
|
||||
|
||||
- name: Cleanup temporary artifacts
|
||||
if: success() && steps.publish-job.outcome == 'success'
|
||||
run: |
|
||||
rm -rf bin dist debug cssdk
|
||||
rm -f *.zip appversion.h
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
||||
*.bat
|
||||
*.log
|
||||
*.lnk
|
||||
*.aps
|
||||
**/msvc/Debug*
|
||||
**/msvc/Release*
|
||||
**/msvc/Tests
|
||||
|
33
README.md
33
README.md
@ -1,4 +1,4 @@
|
||||
# ReGameDLL_CS [](https://github.com/s1lentq/ReGameDLL_CS/releases/latest) []() [](http://isitmaintained.com/project/s1lentq/ReGameDLL_CS "Percentage of issues still open") [](https://www.gnu.org/licenses/gpl-3.0) <img align="right" src="https://cloud.githubusercontent.com/assets/5860435/20008568/b3623150-a2d3-11e6-85f3-0d6571045fc9.png" alt="Counter-Strike 1.6 GameDLL" />
|
||||
# ReGameDLL_CS [](https://github.com/s1lentq/ReGameDLL_CS/releases/latest)  [](http://isitmaintained.com/project/s1lentq/ReGameDLL_CS "Percentage of issues still open") [](https://www.gnu.org/licenses/gpl-3.0) <img align="right" src="https://cloud.githubusercontent.com/assets/5860435/20008568/b3623150-a2d3-11e6-85f3-0d6571045fc9.png" alt="Counter-Strike 1.6 GameDLL" />
|
||||
Reverse-engineered gamedll (mp.dll / Counter-Strike)
|
||||
|
||||
## What is this?
|
||||
@ -29,6 +29,7 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
|
||||
| swapteams | Swap the teams and restart the game (1 sec delay to restart by default).<br/> Args: <br/>`0` - swap teams without restart. <br/> `>0.001` - time delay in seconds to restart the round after swap. |
|
||||
| give | Give weapon command.<br/> Args:<br/><weapon_name><br/>Usage:<br/>`give weapon_ak47`<br/>`give weapon_usp`<br/><br/>NOTE: `sv_cheats 1` required. |
|
||||
| impulse 255 | Give all weapons.<br/><br/>NOTE: `sv_cheats 1` required. |
|
||||
| impulse 200 | Noclip with air acceleration.<br/><br/>NOTE: `sv_cheats 1` required. |
|
||||
|
||||
## Configuration (cvars)
|
||||
<details>
|
||||
@ -97,9 +98,11 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
|
||||
| mp_ct_give_player_knife | 1 | 0 | 1 | Whether Counter-Terrorist player spawn with knife. |
|
||||
| mp_ct_default_weapons_primary | "" | "" | - | The default primary (rifle) weapon that the CTs will spawn with. |
|
||||
| mp_ct_default_weapons_secondary | "usp" | "" | - | The default secondary (pistol) weapon that the CTs will spawn with. |
|
||||
| mp_default_weapons_random | 0 | 0 | 1 | Randomize default weapons (if there are multiple).<br/> `0` disabled<br/>`1` enabled |
|
||||
| mp_give_player_c4 | 1 | 0 | 1 | Whether this map should spawn a C4 bomb for a player or not.<br/> `0` disabled<br/>`1` enabled |
|
||||
| mp_weapons_allow_map_placed | 1 | 0 | 1 | When set, map weapons (located on the floor by map) will be shown.<br/> `0` hide all map weapons.<br/>`1` enabled<br/>`NOTE`: Effect will work after round restart. |
|
||||
| mp_free_armor | 0 | 0 | 2 | Give free armor on player spawn.<br/>`0` disabled <br/>`1` Give Kevlar <br/>`2` Give Kevlar + Helmet |
|
||||
| mp_team_flash | 1 | -1 | 1 | Sets the behaviour for Flashbangs on teammates.<br/>`-1` Don't affect teammates neither flash owner <br/>`0` Don't affect teammates <br/>`1` Affects teammates |
|
||||
| mp_fadetoblack | 0 | 0 | 2 | Observer's screen will fade to black on kill event or permanent.<br/> `0` No fade.<br/>`1` Fade to black and won't be able to watch anybody.<br/>`2` fade to black only on kill moment. |
|
||||
| mp_falldamage | 1 | 0 | 1 | Damage from falling.<br/>`0` disabled <br/>`1` enabled |
|
||||
| sv_allchat | 1 | 0 | 1 | Players can receive all other players text chat, team restrictions apply<br/>`0` disabled <br/>`1` enabled |
|
||||
@ -109,15 +112,37 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
|
||||
| mp_give_c4_frags | 3 | - | - | How many bonuses (frags) will get the player who defused or exploded the bomb. |
|
||||
| mp_hostages_rescued_ratio | 1.0 | 0.0 | 1.0 | Ratio of hostages rescued to win the round. |
|
||||
| mp_legacy_vehicle_block | 1 | 0 | 1 | Legacy func_vehicle behavior when blocked by another entity.<br/>`0` New behavior <br/>`1` Legacy behavior |
|
||||
| mp_dying_time | 3.0 | 0.0 | - | Time for switch to free observing after death.<br/>`0` - disable spectating around death.<br/>`>0.00001` - time delay to start spectate.<br/>`NOTE`: The countdown starts when the player’s death animation is finished. |
|
||||
| mp_deathmsg_flags | abc | 0 | - | Sets a flags for extra information in the player's death message.<br/>`0` disabled<br/>`a` position where the victim died<br/>`b` index of the assistant who helped the attacker kill the victim<br/>`c` rarity classification bits, e.g., `blinkill`, `noscope`, `penetrated`, etc. |
|
||||
| mp_assist_damage_threshold | 40 | 0 | 100 | Sets the percentage of damage needed to score an assist. |
|
||||
| mp_freezetime_duck | 1 | 0 | 1 | Allow players to duck during freezetime.<br/> `0` disabled<br/>`1` enabled |
|
||||
| mp_freezetime_jump | 1 | 0 | 1 | Allow players to jump during freezetime.<br/> `0` disabled<br/>`1` enabled |
|
||||
| mp_defuser_allocation | 0 | 0 | 2 | Give defuser on player spawn.<br/> `0` disabled<br/>`1` Random players. <br/>`2` All players. |
|
||||
| mp_location_area_info | 0 | 0 | 3 | Enable location area info.<br/> `0` disabled<br/>`1` show location below HUD radar.<br/>`2` show location in HUD chat. `NOT RECOMMENDED!` [:speech_balloon:](## "Not all client builds are compatible")<br/>`3` both displayed. `NOT RECOMMENDED!` [:speech_balloon:](## "Not all client builds are compatible")<br/><br/>`NOTE`: Navigation `maps/.nav` file required and should contain place names<br/>`NOTE`: If option `2` or `3` is enabled, be sure to enable `mp_chat_loc_fallback 1` |
|
||||
| mp_item_respawn_time | 30 | 0.0 | - | The respawn time for items (such as health packs, armor, etc.). |
|
||||
| mp_weapon_respawn_time | 20 | 0.0 | - | The respawn time for weapons. |
|
||||
| mp_ammo_respawn_time | 20 | 0.0 | - | The respawn time for ammunition. |
|
||||
| mp_vote_flags | km | 0 | - | Vote systems enabled in server.<br/>`0` voting disabled<br/>`k` votekick enabled via `vote` command<br/>`m` votemap enabled via `votemap` command |
|
||||
| mp_votemap_min_time | 180 | 0.0 | - | Minimum seconds that must elapse on map before `votemap` command can be used. |
|
||||
| mp_flymove_method | 0 | 0 | 1 | Set the method used for flymove calculations.<br/> `0` default method<br/>`1` alternative method (more accurate) |
|
||||
| mp_stamina_restore_rate | 0 | 0.0 | - | Framerate (FPS), that used as reference when restoring stamina (fuser2) after jump. |
|
||||
| mp_logkills | 1 | 0 | 1 | Log kills.<br/>`0` disabled <br/>`1` enabled |
|
||||
| mp_jump_height | 45 | 0.0 | - | Player jump height. |
|
||||
| bot_excellent_morale | 0 | 0 | 1 | Bots always have great morale regardless of defeat or victory. |
|
||||
| mp_randomspawn | 0 | 0 | 1 | Random player spawns<br/>`0` disabled <br/>`1` enabled<br/>`NOTE`: Navigation `maps/.nav` file required |
|
||||
| mp_playerid_showhealth | 1 | 0 | 2 | Player ID display mode.<br/>`0` don't show health<br/>`1` show health for teammates only (default CS behaviour)<br/>`2` show health for all players |
|
||||
| mp_playerid_field | 3 | 0 | 3 | Player ID field display mode.<br/>`0` don't show additional information<br/>`1` show team name<br/>`2` show health percentage<br/>`3` show both team name and health percentage |
|
||||
| mp_knockback | 170 | - | - | Knockback force applied to the victim when damaged by strong weapons (e.g. `AWP`, `AK47`).<br/>Works only if not crouching, and not hit in the legs.<br/>Set to `0` to disable. |
|
||||
|
||||
</details>
|
||||
|
||||
## How to install zBot for CS 1.6?
|
||||
* Extract all the files from an [archive](regamedll/extra/zBot/bot_profiles.zip?raw=true)
|
||||
* Enter `-bots` option at the command line HLDS
|
||||
* Enable CVar `bot_enable 1` in `cstrike/game_init.cfg` (if this config file does not exist, create it)
|
||||
|
||||
## How to install CSCZ hostage AI for CS 1.6?
|
||||
## How to install CS:CZ hostage AI for CS 1.6?
|
||||
* Extract all the files from an [archive](regamedll/extra/HostageImprov/host_improv.zip?raw=true)
|
||||
* Enter `-host-improv` option at the command line HLDS
|
||||
* Enable CVar `hostage_ai_enable 1` in `cstrike/game_init.cfg` (if this config file does not exist, create it)
|
||||
|
||||
## Build instructions
|
||||
### Checking requirements
|
||||
|
2
build.sh
2
build.sh
@ -33,7 +33,7 @@ main()
|
||||
case "$C" in
|
||||
("intel"|"icc") CC=icc CXX=icpc ;;
|
||||
("gcc"|"g++") CC=gcc CXX=g++ ;;
|
||||
("clang|llvm") CC=clang CXX=clang++ ;;
|
||||
("clang"|"llvm") CC=clang CXX=clang++ ;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
262
dist/delta.lst
vendored
Normal file
262
dist/delta.lst
vendored
Normal file
@ -0,0 +1,262 @@
|
||||
// structure name
|
||||
// none == no conditional encode routine
|
||||
// gamedll routine_name : before transmitting data, invoke the named function from the game .dll to reset fields as needed
|
||||
// clientdll routine_name : same as above, except the routine is called via the client.dll
|
||||
|
||||
clientdata_t none
|
||||
{
|
||||
DEFINE_DELTA( flTimeStepSound, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 24, 1024.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 24, 1024.0 ),
|
||||
DEFINE_DELTA( velocity[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( velocity[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
|
||||
DEFINE_DELTA( m_flNextAttack, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 24, 1024.0 ),
|
||||
DEFINE_DELTA( velocity[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
|
||||
DEFINE_DELTA( ammo_nails, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( ammo_shells, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( ammo_cells, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( ammo_rockets, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( m_iId, DT_INTEGER, 5, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( punchangle[2], DT_SIGNED | DT_FLOAT, 21, 8.0 ),
|
||||
DEFINE_DELTA( flags, DT_INTEGER, 32, 1.0 ), // Cut to 3 bits?
|
||||
DEFINE_DELTA( weaponanim, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( health, DT_FLOAT, 17, 1.0 ), // Cut # of bits?
|
||||
DEFINE_DELTA( maxspeed, DT_FLOAT, 16, 10.0 ),
|
||||
DEFINE_DELTA( flDuckTime, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( view_ofs[2], DT_SIGNED | DT_FLOAT, 10, 4.0 ),
|
||||
DEFINE_DELTA( punchangle[0], DT_SIGNED | DT_FLOAT, 26, 8192.0 ),
|
||||
DEFINE_DELTA( punchangle[1], DT_SIGNED | DT_FLOAT, 26, 8192.0 ),
|
||||
DEFINE_DELTA( viewmodel, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( weapons, DT_INTEGER, 32, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( pushmsec, DT_INTEGER, 11, 1.0 ),
|
||||
DEFINE_DELTA( deadflag, DT_INTEGER, 3, 1.0 ),
|
||||
DEFINE_DELTA( fov, DT_FLOAT, 8, 1.0 ),
|
||||
DEFINE_DELTA( physinfo, DT_STRING, 1, 1.0 ),
|
||||
DEFINE_DELTA( bInDuck, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( flSwimTime, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( waterjumptime, DT_INTEGER, 15, 1.0 ),
|
||||
DEFINE_DELTA( waterlevel, DT_INTEGER, 2, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( iuser1, DT_INTEGER, 3, 1.0 ),
|
||||
DEFINE_DELTA( iuser2, DT_INTEGER, 6, 1.0 ),
|
||||
DEFINE_DELTA( iuser3, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( iuser4, DT_INTEGER, 2, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( vuser2[0], DT_FLOAT, 9, 1.0 ),
|
||||
DEFINE_DELTA( vuser2[1], DT_FLOAT, 9, 1.0 ),
|
||||
DEFINE_DELTA( vuser2[2], DT_FLOAT, 9, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( vuser3[0], DT_FLOAT, 9, 1.0 ),
|
||||
DEFINE_DELTA( vuser3[1], DT_FLOAT, 9, 1.0 ),
|
||||
DEFINE_DELTA( vuser3[2], DT_FLOAT, 9, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( vuser4[0], DT_FLOAT, 9, 1.0 ),
|
||||
DEFINE_DELTA( vuser4[1], DT_FLOAT, 9, 1.0 ),
|
||||
|
||||
DEFINE_DELTA( fuser1, DT_FLOAT, 9, 1.0 ),
|
||||
DEFINE_DELTA( fuser2, DT_FLOAT, 14, 1.0 ),
|
||||
DEFINE_DELTA( fuser3, DT_FLOAT, 10, 1.0 )
|
||||
}
|
||||
|
||||
entity_state_t gamedll Entity_Encode
|
||||
{
|
||||
DEFINE_DELTA( animtime, DT_TIMEWINDOW_8, 8, 1.0 ),
|
||||
DEFINE_DELTA( frame, DT_FLOAT, 8, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( angles[0], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( angles[1], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( sequence, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( modelindex, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( movetype, DT_INTEGER, 4, 1.0 ),
|
||||
DEFINE_DELTA( solid, DT_SHORT, 3, 1.0 ),
|
||||
DEFINE_DELTA( mins[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( mins[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( mins[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
|
||||
DEFINE_DELTA( endpos[0], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( endpos[1], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( endpos[2], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( startpos[0], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( startpos[1], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( startpos[2], DT_SIGNED | DT_FLOAT, 13, 1.0 ),
|
||||
DEFINE_DELTA( impacttime, DT_TIMEWINDOW_BIG, 13, 100.0 ),
|
||||
DEFINE_DELTA( starttime, DT_TIMEWINDOW_BIG, 13, 100.0 ),
|
||||
|
||||
DEFINE_DELTA( weaponmodel, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( owner, DT_INTEGER, 5, 1.0 ),
|
||||
DEFINE_DELTA( effects, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( eflags, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( angles[2], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( colormap, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA( framerate, DT_SIGNED | DT_FLOAT, 8, 16.0 ),
|
||||
DEFINE_DELTA( skin, DT_SHORT | DT_SIGNED, 9, 1.0 ),
|
||||
DEFINE_DELTA( controller[0], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[1], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[2], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[3], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( blending[0], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( blending[1], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( body, DT_INTEGER, 18, 1.0 ),
|
||||
DEFINE_DELTA( rendermode, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderamt, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderfx, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( scale, DT_FLOAT, 16, 256.0 ),
|
||||
DEFINE_DELTA( rendercolor.r, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.g, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.b, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( aiment, DT_INTEGER, 11, 1.0 ),
|
||||
DEFINE_DELTA( basevelocity[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( basevelocity[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( basevelocity[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
|
||||
DEFINE_DELTA( iuser4, DT_INTEGER, 2, 1.0 )
|
||||
}
|
||||
|
||||
entity_state_player_t gamedll Player_Encode
|
||||
{
|
||||
DEFINE_DELTA( animtime, DT_TIMEWINDOW_8, 8, 1.0 ),
|
||||
DEFINE_DELTA( frame, DT_FLOAT, 8, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 24, 32.0 ),
|
||||
DEFINE_DELTA( angles[0], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( angles[1], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 24, 32.0 ),
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 24, 32.0 ),
|
||||
DEFINE_DELTA( gaitsequence, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( sequence, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( modelindex, DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( movetype, DT_INTEGER, 4, 1.0 ),
|
||||
DEFINE_DELTA( solid, DT_SHORT, 3, 1.0 ),
|
||||
DEFINE_DELTA( mins[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( mins[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( mins[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( maxs[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( weaponmodel, DT_INTEGER, 10, 1.0 ),
|
||||
// DEFINE_DELTA( team, DT_INTEGER, 4, 1.0 )
|
||||
// DEFINE_DELTA( playerclass, DT_INTEGER, 4, 1.0 )
|
||||
DEFINE_DELTA( owner, DT_INTEGER, 5, 1.0 ),
|
||||
DEFINE_DELTA( effects, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA( angles[2], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( colormap, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA( framerate, DT_SIGNED | DT_FLOAT, 8, 16.0 ),
|
||||
DEFINE_DELTA( skin, DT_SHORT | DT_SIGNED, 9, 1.0 ),
|
||||
DEFINE_DELTA( controller[0], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[1], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[2], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( controller[3], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( blending[0], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( blending[1], DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( body, DT_INTEGER, 9, 1.0 ),
|
||||
DEFINE_DELTA( rendermode, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderamt, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderfx, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( scale, DT_FLOAT, 16, 256.0 ),
|
||||
DEFINE_DELTA( rendercolor.r, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.g, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.b, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( friction, DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( usehull, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( gravity, DT_SIGNED | DT_FLOAT, 16, 32.0 ),
|
||||
DEFINE_DELTA( aiment, DT_INTEGER, 11, 1.0 ),
|
||||
DEFINE_DELTA( basevelocity[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( basevelocity[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( basevelocity[2], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( spectator, DT_INTEGER, 1, 1.0 )
|
||||
|
||||
DEFINE_DELTA( iuser4, DT_INTEGER, 2, 1.0 )
|
||||
}
|
||||
|
||||
custom_entity_state_t gamedll Custom_Encode
|
||||
{
|
||||
DEFINE_DELTA( rendermode, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( angles[0], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( angles[1], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( angles[2], DT_SIGNED | DT_FLOAT, 17, 8.0 ),
|
||||
DEFINE_DELTA( sequence, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA( skin, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA( modelindex, DT_INTEGER, 16, 1.0 ),
|
||||
DEFINE_DELTA_POST( scale, DT_FLOAT, 8, 1.0, 0.1 ),
|
||||
DEFINE_DELTA( body, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.r, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.g, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( rendercolor.b, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderfx, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( renderamt, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( frame, DT_FLOAT, 8, 1.0 ),
|
||||
DEFINE_DELTA_POST( animtime, DT_FLOAT, 8, 1.0, 0.1 )
|
||||
}
|
||||
|
||||
usercmd_t none
|
||||
{
|
||||
DEFINE_DELTA( lerp_msec, DT_SHORT, 9, 1.0 ),
|
||||
DEFINE_DELTA( msec, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( viewangles[1], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( viewangles[0], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( buttons, DT_SHORT, 16, 1.0 ),
|
||||
DEFINE_DELTA( forwardmove, DT_SIGNED | DT_FLOAT, 12, 1.0 ),
|
||||
DEFINE_DELTA( lightlevel, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( sidemove, DT_SIGNED | DT_FLOAT, 12, 1.0 ),
|
||||
DEFINE_DELTA( upmove, DT_SIGNED | DT_FLOAT, 12, 1.0 ),
|
||||
DEFINE_DELTA( impulse, DT_BYTE, 8, 1.0 ),
|
||||
DEFINE_DELTA( viewangles[2], DT_ANGLE, 16, 1.0 ),
|
||||
DEFINE_DELTA( impact_index, DT_INTEGER, 6, 1.0 ),
|
||||
DEFINE_DELTA( impact_position[0], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( impact_position[1], DT_SIGNED | DT_FLOAT, 16, 8.0 ),
|
||||
DEFINE_DELTA( impact_position[2], DT_SIGNED | DT_FLOAT, 16, 8.0 )
|
||||
}
|
||||
|
||||
weapon_data_t none
|
||||
{
|
||||
DEFINE_DELTA( m_flTimeWeaponIdle, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_flNextPrimaryAttack, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_flNextReload, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_fNextAimBonus, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_flNextSecondaryAttack, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_iClip, DT_SIGNED | DT_INTEGER, 10, 1.0 ),
|
||||
DEFINE_DELTA( m_flPumpTime, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_fInSpecialReload, DT_INTEGER, 2, 1.0 ),
|
||||
DEFINE_DELTA( m_fReloadTime, DT_FLOAT, 16, 100.0 ),
|
||||
DEFINE_DELTA( m_fInReload, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( m_fAimedDamage, DT_FLOAT, 22, 1000.0 ),
|
||||
DEFINE_DELTA( m_fInZoom, DT_INTEGER, 8, 1.0 ),
|
||||
DEFINE_DELTA( m_iWeaponState, DT_INTEGER, 7, 1.0 )
|
||||
DEFINE_DELTA( m_iId, DT_INTEGER, 5, 1.0 )
|
||||
DEFINE_DELTA( fuser1, DT_SIGNED | DT_FLOAT, 22, 1000.0 ),
|
||||
DEFINE_DELTA( fuser2, DT_SIGNED | DT_FLOAT, 22, 128.0 ),
|
||||
DEFINE_DELTA( fuser3, DT_SIGNED | DT_FLOAT, 22, 128.0 ),
|
||||
DEFINE_DELTA( iuser1, DT_SIGNED | DT_INTEGER, 16, 128.0 )
|
||||
}
|
||||
|
||||
event_t none
|
||||
{
|
||||
DEFINE_DELTA( entindex, DT_INTEGER, 11, 1.0 ),
|
||||
DEFINE_DELTA( bparam1, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( bparam2, DT_INTEGER, 1, 1.0 ),
|
||||
DEFINE_DELTA( origin[0], DT_SIGNED | DT_FLOAT, 26, 8192.0 ),
|
||||
DEFINE_DELTA( origin[1], DT_SIGNED | DT_FLOAT, 26, 8192.0 ),
|
||||
DEFINE_DELTA( origin[2], DT_SIGNED | DT_FLOAT, 26, 8192.0 ),
|
||||
DEFINE_DELTA( fparam1, DT_FLOAT | DT_SIGNED, 20, 100.0 ),
|
||||
DEFINE_DELTA( fparam2, DT_FLOAT | DT_SIGNED, 20, 100.0 ),
|
||||
DEFINE_DELTA( iparam1, DT_INTEGER | DT_SIGNED, 18, 1.0 ),
|
||||
DEFINE_DELTA( iparam2, DT_INTEGER | DT_SIGNED, 18, 1.0 ),
|
||||
DEFINE_DELTA( angles[0], DT_SIGNED | DT_FLOAT, 26, 8192.0 ),
|
||||
DEFINE_DELTA( angles[1], DT_SIGNED | DT_FLOAT, 26, 8192.0 ),
|
||||
DEFINE_DELTA( angles[2], DT_SIGNED | DT_FLOAT, 26, 8192.0 ),
|
||||
DEFINE_DELTA( ducking, DT_INTEGER, 1, 1.0 )
|
||||
}
|
168
dist/game.cfg
vendored
168
dist/game.cfg
vendored
@ -466,6 +466,13 @@ mp_ct_default_weapons_primary ""
|
||||
// Default value: "usp"
|
||||
mp_ct_default_weapons_secondary "usp"
|
||||
|
||||
// Randomize default weapons (if there are multiple)
|
||||
// 0 - disabled (default behaviour)
|
||||
// 1 - enabled
|
||||
//
|
||||
// Default value: "0"
|
||||
mp_default_weapons_random "0"
|
||||
|
||||
// Give the player free armor on player spawn
|
||||
// 0 - No armor (default behavior)
|
||||
// 1 - Give Kevlar
|
||||
@ -474,6 +481,14 @@ mp_ct_default_weapons_secondary "usp"
|
||||
// Default value: "0"
|
||||
mp_free_armor "0"
|
||||
|
||||
// Sets the behaviour for Flashbangs on teammates.
|
||||
// -1 - Don't affect teammates neither flash owner
|
||||
// 0 - Don't affect teammates
|
||||
// 1 - Affects teammates (default behaviour)
|
||||
//
|
||||
// Default value: "1"
|
||||
mp_team_flash "1"
|
||||
|
||||
// Players can receive all other players text chat, team restrictions apply.
|
||||
// 0 - disabled (default behaviour)
|
||||
// 1 - enabled
|
||||
@ -513,7 +528,7 @@ mp_give_c4_frags "3"
|
||||
// Default value: "1.0"
|
||||
mp_hostages_rescued_ratio "1.0"
|
||||
|
||||
// Legacy func_vehicle behavior when blocked by another entity.
|
||||
// Legacy func_vehicle behavior when blocked by another entity.
|
||||
// New one is more useful for playing multiplayer.
|
||||
//
|
||||
// 0 - New behavior
|
||||
@ -521,3 +536,154 @@ mp_hostages_rescued_ratio "1.0"
|
||||
//
|
||||
// Default value: "1"
|
||||
mp_legacy_vehicle_block "1"
|
||||
|
||||
// Time for switch to free observing after death.
|
||||
// NOTE: The countdown starts when the player’s death animation is finished.
|
||||
// 0 - disable spectating around death
|
||||
// >0.00001 - time delay to start spectate
|
||||
//
|
||||
// Default value: "3.0"
|
||||
mp_dying_time "3.0"
|
||||
|
||||
// Sets a flags for extra information in the player's death message
|
||||
//
|
||||
// a - Position where the victim died
|
||||
// b - Index of the assistant who helped the attacker kill the victim
|
||||
// c - Rarity classification bits, e.g., blinkill, noscope, penetrated, etc
|
||||
//
|
||||
// Set to "0" to send no extra information about death
|
||||
//
|
||||
// Default value: "abc"
|
||||
mp_deathmsg_flags "abc"
|
||||
|
||||
// Sets the percentage of damage needed to score an assist
|
||||
//
|
||||
// Default value: "40"
|
||||
mp_assist_damage_threshold "40"
|
||||
|
||||
// Allow players to duck during freezetime
|
||||
// 0 - disabled
|
||||
// 1 - enabled (default behaviour)
|
||||
//
|
||||
// Default value: "1"
|
||||
mp_freezetime_duck "1"
|
||||
|
||||
// Allow players to jump during freezetime
|
||||
// 0 - disabled
|
||||
// 1 - enabled (default behaviour)
|
||||
//
|
||||
// Default value: "1"
|
||||
mp_freezetime_jump "1"
|
||||
|
||||
// Give defuser on player spawn
|
||||
// 0 - No free defusers (default behavior)
|
||||
// 1 - Random players
|
||||
// 2 - All players
|
||||
//
|
||||
// Default value: "0"
|
||||
mp_defuser_allocation "0"
|
||||
|
||||
// Enable location area info
|
||||
// 0 - disabled (default behavior)
|
||||
// 1 - show location below HUD radar
|
||||
// 2 - show location in HUD chat (NOT RECOMMENDED! Not all client builds are compatible)
|
||||
// 3 - both displayed (NOT RECOMMENDED! Not all client builds are compatible)
|
||||
//
|
||||
// NOTE: Navigation maps/.nav file required and should contain place names
|
||||
// NOTE: If option 2 or 3 is enabled, be sure to enable mp_chat_loc_fallback 1
|
||||
//
|
||||
// Default value: "0"
|
||||
mp_location_area_info "0"
|
||||
|
||||
// The respawn time for items (such as health packs, armor, etc.).
|
||||
// 0 - disable delay
|
||||
//
|
||||
// Default value: "30"
|
||||
mp_item_respawn_time "30"
|
||||
|
||||
// The respawn time for weapons.
|
||||
// 0 - disable delay
|
||||
//
|
||||
// Default value: "20"
|
||||
mp_weapon_respawn_time "20"
|
||||
|
||||
// The respawn time for ammunition.
|
||||
// 0 - disable delay
|
||||
//
|
||||
// Default value: "20"
|
||||
mp_ammo_respawn_time "20"
|
||||
|
||||
// Vote systems enabled in server
|
||||
//
|
||||
// k - votekick enabled via vote command
|
||||
// m - votemap enabled via votemap command
|
||||
//
|
||||
// Set to "0" to disable voting systems
|
||||
//
|
||||
// Default value: "km"
|
||||
mp_vote_flags "km"
|
||||
|
||||
// Minimum seconds that must elapse on map before votemap command can be used
|
||||
//
|
||||
// Default value: "180"
|
||||
mp_votemap_min_time "180"
|
||||
|
||||
// Set the method used for flymove calculations.
|
||||
// 0 - default method
|
||||
// 1 - alternative method (more accurate)
|
||||
//
|
||||
// Default value: "0"
|
||||
mp_flymove_method "0"
|
||||
|
||||
// Framerate (FPS), that is used as a reference when restoring stamina (fuser2) after a jump.
|
||||
// 0 - disabled
|
||||
//
|
||||
// Default value: "0"
|
||||
mp_stamina_restore_rate "0"
|
||||
|
||||
// Player jump height
|
||||
//
|
||||
// Default value: "45"
|
||||
mp_jump_height "45"
|
||||
|
||||
// Bots always have great morale regardless of defeat or victory.
|
||||
// 0 - disabled (default behaviour)
|
||||
// 1 - enabled
|
||||
//
|
||||
// Default value: "0"
|
||||
bot_excellent_morale "0"
|
||||
|
||||
// Random player spawns
|
||||
// 0 - disabled (default behaviour)
|
||||
// 1 - enabled
|
||||
//
|
||||
// NOTE: Navigation "maps/.nav" file required
|
||||
//
|
||||
// Default value: "0"
|
||||
mp_randomspawn "0"
|
||||
|
||||
// Player ID display mode
|
||||
//
|
||||
// 0 - don't show health (default behaviour)
|
||||
// 1 - show health for teammates only (default CS behaviour)
|
||||
// 2 - show health for all players
|
||||
//
|
||||
// Default value: "1"
|
||||
mp_playerid_showhealth "1"
|
||||
|
||||
// Player ID field display mode
|
||||
//
|
||||
// 0 - don't show additional information
|
||||
// 1 - show team name
|
||||
// 2 - show health percentage
|
||||
// 3 - show both team name and health percentage
|
||||
//
|
||||
// Default value: "3"
|
||||
mp_playerid_field "3"
|
||||
|
||||
// Knockback force applied to the victim when damaged by strong weapons (e.g. AWP, AK47).
|
||||
// Works only if not crouching, and not hit in the legs.
|
||||
// Set to "0" to disable.
|
||||
//
|
||||
// Default: "170"
|
||||
mp_knockback "170"
|
||||
|
15
dist/game_init.cfg
vendored
15
dist/game_init.cfg
vendored
@ -1,3 +1,18 @@
|
||||
// Enables ZBots for the server
|
||||
// NOTE: ZBots are always enabled on a listen server, regardless of this cvar
|
||||
// 0 - disabled
|
||||
// 1 - enabled
|
||||
//
|
||||
// Default value: "0"
|
||||
bot_enable "0"
|
||||
|
||||
// Enables the improve AI for hostages from CS:CZ
|
||||
// 0 - disabled (classic hostage)
|
||||
// 1 - enabled (improved hostage)
|
||||
//
|
||||
// Default value: "0"
|
||||
hostage_ai_enable "0"
|
||||
|
||||
// Sets mins/maxs hull bounds for the player.
|
||||
// 0 - disabled (default behaviour, sets engine)
|
||||
// 1 - enabled (sets gamedll)
|
||||
|
@ -20,18 +20,47 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(regamedll CXX)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
option(DEBUG "Build with debug information." OFF)
|
||||
option(USE_STATIC_LIBSTDC "Enables static linking libstdc++." OFF)
|
||||
option(USE_LEGACY_LIBC "Enables linking against legacy libc (<= 2.15) for compat with older distros (Debian 8/Ubuntu 16.04/Centos 7)." OFF)
|
||||
option(XASH_COMPAT "Enable Xash3D FWGS compatiblity (support for it's 64-bit ABI support and crossplatform library suffix)")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Avoid -rdynamic -fPIC options
|
||||
set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "")
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||
if (NOT XASH_COMPAT)
|
||||
set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "")
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||
endif()
|
||||
|
||||
set(COMPILE_FLAGS "-m32 -U_FORTIFY_SOURCE")
|
||||
set(LINK_FLAGS "-m32 -s")
|
||||
set(COMPILE_FLAGS "-U_FORTIFY_SOURCE")
|
||||
set(LINK_LIBS dl)
|
||||
|
||||
# do not strip debuginfo during link
|
||||
if (NOT DEBUG)
|
||||
set(LINK_FLAGS "-s")
|
||||
endif()
|
||||
|
||||
# add -m32 flag only on 64-bit systems, if building for 64-bit wasn't enabled with XASH_COMPAT
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
if (XASH_COMPAT)
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} -DXASH_64BIT")
|
||||
else()
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} -m32")
|
||||
set(LINK_FLAGS "${LINK_FLAGS} -m32")
|
||||
list(APPEND LINK_LIBS aelf32)
|
||||
set(CMAKE_SIZEOF_VOID_P 4)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(XASH_COMPAT)
|
||||
# Xash3D FWGS Library Naming Scheme compliance
|
||||
# see documentation: https://github.com/FWGS/xash3d-fwgs/blob/master/Documentation/extensions/library-naming.md
|
||||
include(LibraryNaming)
|
||||
endif()
|
||||
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wall -fno-exceptions -fno-builtin -Wno-unknown-pragmas")
|
||||
|
||||
@ -45,7 +74,7 @@ else()
|
||||
endif()
|
||||
|
||||
# Check Intel C++ compiler
|
||||
if ("$ENV{CXX}" MATCHES "icpc")
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
|
||||
#
|
||||
# -fp-model=precise
|
||||
# ICC uses -fp-model fast=1 by default for more aggressive optimizations on floating-point calculations
|
||||
@ -73,11 +102,15 @@ if ("$ENV{CXX}" MATCHES "icpc")
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} -ipo")
|
||||
set(LINK_FLAGS "${LINK_FLAGS} -ipo")
|
||||
endif()
|
||||
else()
|
||||
# Produce code optimized for the most common IA32/AMD64/EM64T processors.
|
||||
# As new processors are deployed in the marketplace, the behavior of this option will change.
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
if (NOT XASH_COMPAT OR XASH_AMD64 OR XASH_X86)
|
||||
# Produce code optimized for the most common IA32/AMD64/EM64T processors.
|
||||
# As new processors are deployed in the marketplace, the behavior of this option will change.
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} \
|
||||
-mtune=generic -msse3")
|
||||
endif()
|
||||
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} \
|
||||
-mtune=generic -msse3\
|
||||
-fpermissive -fno-sized-deallocation\
|
||||
-Wno-delete-non-virtual-dtor -Wno-invalid-offsetof\
|
||||
-Wno-unused-variable -Wno-unused-value -Wno-unused-result -Wno-unused-function\
|
||||
@ -85,7 +118,7 @@ else()
|
||||
-Wno-sign-compare -Wno-format -Wno-ignored-attributes -Wno-strict-aliasing")
|
||||
|
||||
# Check Clang compiler
|
||||
if ("$ENV{CXX}" MATCHES "clang")
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} \
|
||||
-Wno-unused-local-typedef\
|
||||
-Wno-unused-private-field\
|
||||
@ -100,16 +133,11 @@ else()
|
||||
|
||||
# GCC >= 8.3
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-stringop-truncation -Wno-format-truncation -Wno-class-memaccess")
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-stringop-truncation -Wno-format-truncation -Wno-class-memaccess -fcf-protection=none")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# GCC >= 8.3
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)
|
||||
set(COMPILE_FLAGS "${COMPILE_FLAGS} -fcf-protection=none")
|
||||
endif()
|
||||
|
||||
if (NOT DEBUG)
|
||||
set(LINK_FLAGS "${LINK_FLAGS} \
|
||||
-Wl,-gc-sections -Wl,--version-script=\"${PROJECT_SOURCE_DIR}/../version_script.lds\"")
|
||||
@ -161,6 +189,9 @@ set(SHARED_SRCS
|
||||
"public/FileSystem.cpp"
|
||||
"public/interface.cpp"
|
||||
"public/MemPool.cpp"
|
||||
"public/MemPool.cpp"
|
||||
"public/tier0/dbg.cpp"
|
||||
"public/tier0/platform_posix.cpp"
|
||||
)
|
||||
|
||||
set(GAMEDLL_SRCS
|
||||
@ -226,6 +257,7 @@ set(GAMEDLL_SRCS
|
||||
"dlls/API/CSEntity.cpp"
|
||||
"dlls/API/CSPlayer.cpp"
|
||||
"dlls/API/CSPlayerItem.cpp"
|
||||
"dlls/API/CSPlayerWeapon.cpp"
|
||||
"dlls/addons/item_airbox.cpp"
|
||||
"dlls/addons/point_command.cpp"
|
||||
"dlls/addons/trigger_random.cpp"
|
||||
@ -342,6 +374,7 @@ target_compile_definitions(regamedll PRIVATE
|
||||
_strnicmp=strncasecmp
|
||||
_strdup=strdup
|
||||
_unlink=unlink
|
||||
_snprintf=snprintf
|
||||
_vsnprintf=vsnprintf
|
||||
_write=write
|
||||
_close=close
|
||||
@ -358,26 +391,49 @@ target_sources(regamedll PRIVATE
|
||||
${UNITTESTS_SRCS}>
|
||||
)
|
||||
|
||||
target_link_libraries(regamedll PRIVATE
|
||||
dl
|
||||
aelf32
|
||||
if (CMAKE_BUILD_TYPE MATCHES Unittests)
|
||||
list(APPEND LINK_LIBS cppunitlite)
|
||||
elseif (USE_LEGACY_LIBC)
|
||||
list(APPEND LINK_LIBS libc-2.15.so)
|
||||
endif()
|
||||
|
||||
$<$<CONFIG:Unittests>:cppunitlite>
|
||||
)
|
||||
target_link_libraries(regamedll PRIVATE ${LINK_LIBS})
|
||||
|
||||
if (USE_STATIC_LIBSTDC)
|
||||
target_compile_definitions(regamedll PRIVATE BUILD_STATIC_LIBSTDC)
|
||||
set(LINK_FLAGS "${LINK_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
|
||||
set(LINK_FLAGS "${LINK_FLAGS} \
|
||||
-Wl,-rpath,'$ORIGIN/.' \
|
||||
-L${PROJECT_SOURCE_DIR}/lib/linux32")
|
||||
set(LINK_FLAGS "${LINK_FLAGS} -Wl,-rpath,'$ORIGIN/.'")
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(LINK_FLAGS "${LINK_FLAGS} -L${PROJECT_SOURCE_DIR}/lib/linux32")
|
||||
endif()
|
||||
|
||||
set_target_properties(regamedll PROPERTIES
|
||||
OUTPUT_NAME cs
|
||||
PREFIX ""
|
||||
COMPILE_FLAGS ${COMPILE_FLAGS}
|
||||
LINK_FLAGS ${LINK_FLAGS}
|
||||
POSITION_INDEPENDENT_CODE OFF
|
||||
)
|
||||
|
||||
if (XASH_COMPAT)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
set_target_properties(regamedll PROPERTIES
|
||||
OUTPUT_NAME server)
|
||||
else()
|
||||
set_target_properties(regamedll PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME cs${POSTFIX})
|
||||
endif()
|
||||
else()
|
||||
set_target_properties(regamedll PROPERTIES
|
||||
OUTPUT_NAME cs
|
||||
PREFIX ""
|
||||
POSITION_INDEPENDENT_CODE OFF)
|
||||
endif()
|
||||
|
||||
install(TARGETS regamedll
|
||||
RUNTIME DESTINATION "cstrike/dlls/"
|
||||
LIBRARY DESTINATION "cstrike/dlls/"
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
|
||||
GROUP_READ GROUP_EXECUTE
|
||||
WORLD_READ WORLD_EXECUTE)
|
||||
|
198
regamedll/cmake/LibraryNaming.cmake
Normal file
198
regamedll/cmake/LibraryNaming.cmake
Normal file
@ -0,0 +1,198 @@
|
||||
include(CheckSymbolExists)
|
||||
|
||||
macro(check_build_target symbol)
|
||||
check_symbol_exists(${symbol} "build.h" ${symbol})
|
||||
endmacro()
|
||||
|
||||
macro(check_group_build_target symbol group)
|
||||
if(NOT ${group})
|
||||
check_build_target(${symbol})
|
||||
if(${symbol})
|
||||
set(${group} TRUE)
|
||||
endif()
|
||||
else()
|
||||
set(${symbol} FALSE)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# So there is a problem:
|
||||
# 1. Number of these symbols only grows, as we support more and more ports
|
||||
# 2. CMake was written by morons and can't check these symbols in parallel
|
||||
# 3. MSVC is very slow at everything (startup, parsing, generating error)
|
||||
|
||||
# Solution: group these symbols and set variable if one of them was found
|
||||
# this way we can reorder to reorder them by most common configurations
|
||||
# but we can't generate this list anymore! ... OR IS IT ???
|
||||
|
||||
# Well, after reordering positions in engine's buildenums.h, we can partially autogenerate this list!
|
||||
# echo "check_build_target(XASH_64BIT)"
|
||||
# grep "#define PLATFORM" buildenums.h | cut -d' ' -f 2 | cut -d_ -f 2- | awk '{ print "check_group_build_target(XASH_" $1 " XASH_PLATFORM)" }'
|
||||
# grep "#define ARCHITECTURE" buildenums.h | cut -d' ' -f 2 | cut -d_ -f 2- | awk '{ print "check_group_build_target(XASH_" $1 " XASH_ARCHITECTURE)"
|
||||
# grep "#define ENDIAN" buildenums.h | cut -d' ' -f 2 | cut -d_ -f 2- | awk '{ print "check_group_build_target(XASH_" $1 "_ENDIAN XASH_ENDIANNESS)"}'
|
||||
# echo "if(XASH_ARM)"
|
||||
# grep '^#undef XASH' build.h | grep "XASH_ARM[v_]" | awk '{ print "check_build_target(" $2 ")"}'
|
||||
# echo "endif()"
|
||||
# echo "if(XASH_RISCV)"
|
||||
# grep '^#undef XASH' build.h | grep "XASH_RISCV_" | awk '{ print "check_build_target(" $2 ")"}'
|
||||
# echo "endif()"
|
||||
|
||||
# NOTE: Android must have priority over Linux to work correctly!
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES "${PROJECT_SOURCE_DIR}/public/")
|
||||
check_build_target(XASH_64BIT)
|
||||
check_group_build_target(XASH_WIN32 XASH_PLATFORM)
|
||||
check_group_build_target(XASH_ANDROID XASH_PLATFORM)
|
||||
check_group_build_target(XASH_LINUX XASH_PLATFORM)
|
||||
check_group_build_target(XASH_FREEBSD XASH_PLATFORM)
|
||||
check_group_build_target(XASH_APPLE XASH_PLATFORM)
|
||||
check_group_build_target(XASH_NETBSD XASH_PLATFORM)
|
||||
check_group_build_target(XASH_OPENBSD XASH_PLATFORM)
|
||||
check_group_build_target(XASH_EMSCRIPTEN XASH_PLATFORM)
|
||||
check_group_build_target(XASH_DOS4GW XASH_PLATFORM)
|
||||
check_group_build_target(XASH_HAIKU XASH_PLATFORM)
|
||||
check_group_build_target(XASH_SERENITY XASH_PLATFORM)
|
||||
check_group_build_target(XASH_IRIX XASH_PLATFORM)
|
||||
check_group_build_target(XASH_NSWITCH XASH_PLATFORM)
|
||||
check_group_build_target(XASH_PSVITA XASH_PLATFORM)
|
||||
check_group_build_target(XASH_WASI XASH_PLATFORM)
|
||||
check_group_build_target(XASH_SUNOS XASH_PLATFORM)
|
||||
check_group_build_target(XASH_X86 XASH_ARCHITECTURE)
|
||||
check_group_build_target(XASH_AMD64 XASH_ARCHITECTURE)
|
||||
check_group_build_target(XASH_ARM XASH_ARCHITECTURE)
|
||||
check_group_build_target(XASH_MIPS XASH_ARCHITECTURE)
|
||||
check_group_build_target(XASH_PPC XASH_ARCHITECTURE)
|
||||
check_group_build_target(XASH_JS XASH_ARCHITECTURE)
|
||||
check_group_build_target(XASH_E2K XASH_ARCHITECTURE)
|
||||
check_group_build_target(XASH_RISCV XASH_ARCHITECTURE)
|
||||
check_group_build_target(XASH_LITTLE_ENDIAN XASH_ENDIANNESS)
|
||||
check_group_build_target(XASH_BIG_ENDIAN XASH_ENDIANNESS)
|
||||
if(XASH_ARM)
|
||||
check_build_target(XASH_ARM_HARDFP)
|
||||
check_build_target(XASH_ARM_SOFTFP)
|
||||
check_build_target(XASH_ARMv4)
|
||||
check_build_target(XASH_ARMv5)
|
||||
check_build_target(XASH_ARMv6)
|
||||
check_build_target(XASH_ARMv7)
|
||||
check_build_target(XASH_ARMv8)
|
||||
endif()
|
||||
if(XASH_RISCV)
|
||||
check_build_target(XASH_RISCV_DOUBLEFP)
|
||||
check_build_target(XASH_RISCV_SINGLEFP)
|
||||
check_build_target(XASH_RISCV_SOFTFP)
|
||||
endif()
|
||||
unset(CMAKE_REQUIRED_INCLUDES)
|
||||
|
||||
# engine/common/build.c
|
||||
if(XASH_ANDROID)
|
||||
set(BUILDOS "android")
|
||||
elseif(XASH_WIN32 OR XASH_LINUX OR XASH_APPLE)
|
||||
set(BUILDOS "") # no prefix for default OS
|
||||
elseif(XASH_FREEBSD)
|
||||
set(BUILDOS "freebsd")
|
||||
elseif(XASH_NETBSD)
|
||||
set(BUILDOS "netbsd")
|
||||
elseif(XASH_OPENBSD)
|
||||
set(BUILDOS "openbsd")
|
||||
elseif(XASH_EMSCRIPTEN)
|
||||
set(BUILDOS "emscripten")
|
||||
elseif(XASH_DOS4GW)
|
||||
set(BUILDOS "DOS4GW")
|
||||
elseif(XASH_HAIKU)
|
||||
set(BUILDOS "haiku")
|
||||
elseif(XASH_SERENITY)
|
||||
set(BUILDOS "serenityos")
|
||||
elseif(XASH_NSWITCH)
|
||||
set(BUILDOS "nswitch")
|
||||
elseif(XASH_PSVITA)
|
||||
set(BUILDOS "psvita")
|
||||
elseif(XASH_IRIX)
|
||||
set(BUILDOS "irix")
|
||||
elseif(XASH_WASI)
|
||||
set(BUILDOS "wasi")
|
||||
elseif(XASH_SUNOS)
|
||||
set(BUILDOS "sunos")
|
||||
else()
|
||||
message(SEND_ERROR "Place your operating system name here! If this is a mistake, try to fix conditions above and report a bug")
|
||||
endif()
|
||||
|
||||
if(XASH_AMD64)
|
||||
set(BUILDARCH "amd64")
|
||||
elseif(XASH_X86)
|
||||
if(XASH_WIN32 OR XASH_LINUX OR XASH_APPLE)
|
||||
set(BUILDARCH "") # no prefix for default OS
|
||||
else()
|
||||
set(BUILDARCH "i386")
|
||||
endif()
|
||||
elseif(XASH_ARM AND XASH_64BIT)
|
||||
set(BUILDARCH "arm64")
|
||||
elseif(XASH_ARM)
|
||||
set(BUILDARCH "armv")
|
||||
if(XASH_ARMv8)
|
||||
set(BUILDARCH "${BUILDARCH}8_32")
|
||||
elseif(XASH_ARMv7)
|
||||
set(BUILDARCH "${BUILDARCH}7")
|
||||
elseif(XASH_ARMv6)
|
||||
set(BUILDARCH "${BUILDARCH}6")
|
||||
elseif(XASH_ARMv5)
|
||||
set(BUILDARCH "${BUILDARCH}5")
|
||||
elseif(XASH_ARMv4)
|
||||
set(BUILDARCH "${BUILDARCH}4")
|
||||
else()
|
||||
message(SEND_ERROR "Unknown ARM")
|
||||
endif()
|
||||
|
||||
if(XASH_ARM_HARDFP)
|
||||
set(BUILDARCH "${BUILDARCH}hf")
|
||||
else()
|
||||
set(BUILDARCH "${BUILDARCH}l")
|
||||
endif()
|
||||
elseif(XASH_MIPS)
|
||||
set(BUILDARCH "mips")
|
||||
if(XASH_64BIT)
|
||||
set(BUILDARCH "${BUILDARCH}64")
|
||||
endif()
|
||||
|
||||
if(XASH_LITTLE_ENDIAN)
|
||||
set(BUILDARCH "${BUILDARCH}el")
|
||||
endif()
|
||||
elseif(XASH_RISCV)
|
||||
set(BUILDARCH "riscv")
|
||||
if(XASH_64BIT)
|
||||
set(BUILDARCH "${BUILDARCH}64")
|
||||
else()
|
||||
set(BUILDARCH "${BUILDARCH}32")
|
||||
endif()
|
||||
|
||||
if(XASH_RISCV_DOUBLEFP)
|
||||
set(BUILDARCH "${BUILDARCH}d")
|
||||
elseif(XASH_RISCV_SINGLEFP)
|
||||
set(BUILDARCH "${BUILDARCH}f")
|
||||
endif()
|
||||
elseif(XASH_JS)
|
||||
set(BUILDARCH "javascript")
|
||||
elseif(XASH_E2K)
|
||||
set(BUILDARCH "e2k")
|
||||
elseif(XASH_PPC)
|
||||
set(BUILDARCH "ppc")
|
||||
if(XASH_64BIT)
|
||||
set(BUILDARCH "${BUILDARCH}64")
|
||||
endif()
|
||||
|
||||
if(XASH_LITTLE_ENDIAN)
|
||||
set(BUILDARCH "${BUILDARCH}el")
|
||||
endif()
|
||||
else()
|
||||
message(SEND_ERROR "Place your architecture name here! If this is a mistake, try to fix conditions above and report a bug")
|
||||
endif()
|
||||
|
||||
if(BUILDOS STREQUAL "android")
|
||||
set(POSTFIX "") # force disable for Android, as Android ports aren't distributed in normal way and doesn't follow library naming
|
||||
elseif(BUILDOS AND BUILDARCH)
|
||||
set(POSTFIX "_${BUILDOS}_${BUILDARCH}")
|
||||
elseif(BUILDARCH)
|
||||
set(POSTFIX "_${BUILDARCH}")
|
||||
else()
|
||||
set(POSTFIX "")
|
||||
endif()
|
||||
|
||||
message(STATUS "Library postfix: " ${POSTFIX})
|
@ -158,6 +158,11 @@
|
||||
#define EF_FORCEVISIBILITY BIT(11) // force visibility
|
||||
#define EF_OWNER_VISIBILITY BIT(12) // visibility for owner
|
||||
#define EF_OWNER_NO_VISIBILITY BIT(13) // no visibility for owner
|
||||
#define EF_NOSLERP BIT(14) // no slerp flag for this entity (addtofullpack)
|
||||
#define EF_FOLLOWKEEPRENDER BIT(15) // the entity following will not copy the render (like it follows nothing)
|
||||
|
||||
// Custom flags that aren't handled by the client
|
||||
#define EF_CUSTOM_BITS (EF_FORCEVISIBILITY | EF_OWNER_VISIBILITY | EF_OWNER_NO_VISIBILITY | EF_NOSLERP | EF_FOLLOWKEEPRENDER)
|
||||
|
||||
// state->eflags values
|
||||
#define EFLAG_SLERP 1 // do studio interpolation of this entity
|
||||
|
@ -30,40 +30,133 @@
|
||||
|
||||
CReGameHookchains g_ReGameHookchains;
|
||||
|
||||
int EXT_FUNC Cmd_Argc_api() {
|
||||
void EXT_FUNC Regamedll_ChangeString_api(char *&dest, const char *source)
|
||||
{
|
||||
size_t len = Q_strlen(source);
|
||||
if (dest == nullptr || Q_strlen(dest) != len) {
|
||||
delete [] dest;
|
||||
dest = new char [len + 1];
|
||||
}
|
||||
|
||||
Q_strcpy(dest, source);
|
||||
}
|
||||
|
||||
void EXT_FUNC RadiusDamage_api(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType)
|
||||
{
|
||||
RadiusDamage(vecSrc, pevInflictor, pevAttacker, flDamage, flRadius, iClassIgnore, bitsDamageType);
|
||||
}
|
||||
|
||||
void EXT_FUNC ClearMultiDamage_api()
|
||||
{
|
||||
ClearMultiDamage();
|
||||
}
|
||||
|
||||
void EXT_FUNC ApplyMultiDamage_api(entvars_t *pevInflictor, entvars_t *pevAttacker)
|
||||
{
|
||||
ApplyMultiDamage(pevInflictor, pevAttacker);
|
||||
}
|
||||
|
||||
void EXT_FUNC AddMultiDamage_api(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType)
|
||||
{
|
||||
AddMultiDamage(pevInflictor, pEntity, flDamage, bitsDamageType);
|
||||
}
|
||||
|
||||
int EXT_FUNC Cmd_Argc_api()
|
||||
{
|
||||
return CMD_ARGC_();
|
||||
}
|
||||
|
||||
const char *EXT_FUNC Cmd_Argv_api(int i) {
|
||||
const char *EXT_FUNC Cmd_Argv_api(int i)
|
||||
{
|
||||
return CMD_ARGV_(i);
|
||||
}
|
||||
|
||||
CGrenade *PlantBomb_api(entvars_t *pevOwner, Vector &vecStart, Vector &vecVelocity) {
|
||||
CGrenade *EXT_FUNC PlantBomb_api(entvars_t *pevOwner, Vector &vecStart, Vector &vecVelocity)
|
||||
{
|
||||
return CGrenade::ShootSatchelCharge(pevOwner, vecStart, vecVelocity);
|
||||
}
|
||||
|
||||
CGib *SpawnHeadGib_api(entvars_t *pevVictim) {
|
||||
CGib *EXT_FUNC SpawnHeadGib_api(entvars_t *pevVictim)
|
||||
{
|
||||
return CGib::SpawnHeadGib(pevVictim);
|
||||
}
|
||||
|
||||
void SpawnRandomGibs_api(entvars_t *pevVictim, int cGibs, int human) {
|
||||
void EXT_FUNC SpawnRandomGibs_api(entvars_t *pevVictim, int cGibs, int human)
|
||||
{
|
||||
CGib::SpawnRandomGibs(pevVictim, cGibs, human);
|
||||
}
|
||||
|
||||
void EXT_FUNC UTIL_RestartOther_api(const char *szClassname)
|
||||
{
|
||||
UTIL_RestartOther(szClassname);
|
||||
}
|
||||
|
||||
void EXT_FUNC UTIL_ResetEntities_api()
|
||||
{
|
||||
UTIL_ResetEntities();
|
||||
}
|
||||
|
||||
void EXT_FUNC UTIL_RemoveOther_api(const char *szClassname, int nCount)
|
||||
{
|
||||
UTIL_RemoveOther(szClassname, nCount);
|
||||
}
|
||||
|
||||
void EXT_FUNC UTIL_DecalTrace_api(TraceResult *pTrace, int decalNumber)
|
||||
{
|
||||
UTIL_DecalTrace(pTrace, decalNumber);
|
||||
}
|
||||
|
||||
void EXT_FUNC UTIL_Remove_api(CBaseEntity *pEntity)
|
||||
{
|
||||
UTIL_Remove(pEntity);
|
||||
}
|
||||
|
||||
int EXT_FUNC AddAmmoNameToAmmoRegistry_api(const char *szAmmoname)
|
||||
{
|
||||
return AddAmmoNameToAmmoRegistry(szAmmoname);
|
||||
}
|
||||
|
||||
void EXT_FUNC TextureTypePlaySound_api(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int iBulletType)
|
||||
{
|
||||
TEXTURETYPE_PlaySound(ptr, vecSrc, vecEnd, iBulletType);
|
||||
}
|
||||
|
||||
CWeaponBox *EXT_FUNC CreateWeaponBox_api(CBasePlayerItem *pItem, CBasePlayer *pPlayerOwner, const char *modelName, Vector &origin, Vector &angles, Vector &velocity, float lifeTime, bool packAmmo)
|
||||
{
|
||||
return CreateWeaponBox(pItem, pPlayerOwner, modelName, origin, angles, velocity, lifeTime < 0.0 ? CGameRules::GetItemKillDelay() : lifeTime, packAmmo);
|
||||
}
|
||||
|
||||
CGrenade *EXT_FUNC SpawnGrenade_api(WeaponIdType weaponId, entvars_t *pevOwner, Vector &vecSrc, Vector &vecThrow, float time, int iTeam, unsigned short usEvent)
|
||||
{
|
||||
switch (weaponId)
|
||||
{
|
||||
case WEAPON_HEGRENADE:
|
||||
return CGrenade::ShootTimed2(pevOwner, vecSrc, vecThrow, time, iTeam, usEvent);
|
||||
case WEAPON_FLASHBANG:
|
||||
return CGrenade::ShootTimed(pevOwner, vecSrc, vecThrow, time);
|
||||
case WEAPON_SMOKEGRENADE:
|
||||
return CGrenade::ShootSmokeGrenade(pevOwner, vecSrc, vecThrow, time, usEvent);
|
||||
case WEAPON_C4:
|
||||
return CGrenade::ShootSatchelCharge(pevOwner, vecSrc, vecThrow);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ReGameFuncs_t g_ReGameApiFuncs = {
|
||||
&CREATE_NAMED_ENTITY,
|
||||
CREATE_NAMED_ENTITY,
|
||||
|
||||
&Regamedll_ChangeString_api,
|
||||
Regamedll_ChangeString_api,
|
||||
|
||||
&RadiusDamage_api,
|
||||
&ClearMultiDamage_api,
|
||||
&ApplyMultiDamage_api,
|
||||
&AddMultiDamage_api,
|
||||
RadiusDamage_api,
|
||||
ClearMultiDamage_api,
|
||||
ApplyMultiDamage_api,
|
||||
AddMultiDamage_api,
|
||||
|
||||
&UTIL_FindEntityByString,
|
||||
UTIL_FindEntityByString,
|
||||
|
||||
&AddEntityHashValue,
|
||||
&RemoveEntityHashValue,
|
||||
AddEntityHashValue,
|
||||
RemoveEntityHashValue,
|
||||
|
||||
Cmd_Argc_api,
|
||||
Cmd_Argv_api,
|
||||
@ -76,6 +169,13 @@ ReGameFuncs_t g_ReGameApiFuncs = {
|
||||
UTIL_RestartOther_api,
|
||||
UTIL_ResetEntities_api,
|
||||
UTIL_RemoveOther_api,
|
||||
UTIL_DecalTrace_api,
|
||||
UTIL_Remove_api,
|
||||
|
||||
AddAmmoNameToAmmoRegistry_api,
|
||||
TextureTypePlaySound_api,
|
||||
CreateWeaponBox_api,
|
||||
SpawnGrenade_api,
|
||||
};
|
||||
|
||||
GAMEHOOK_REGISTRY(CBasePlayer_Spawn);
|
||||
@ -209,6 +309,35 @@ GAMEHOOK_REGISTRY(CBasePlayer_DeathSound);
|
||||
GAMEHOOK_REGISTRY(CBasePlayer_JoiningThink);
|
||||
|
||||
GAMEHOOK_REGISTRY(FreeGameRules);
|
||||
GAMEHOOK_REGISTRY(PM_LadderMove);
|
||||
GAMEHOOK_REGISTRY(PM_WaterJump);
|
||||
GAMEHOOK_REGISTRY(PM_CheckWaterJump);
|
||||
GAMEHOOK_REGISTRY(PM_Jump);
|
||||
GAMEHOOK_REGISTRY(PM_Duck);
|
||||
GAMEHOOK_REGISTRY(PM_UnDuck);
|
||||
GAMEHOOK_REGISTRY(PM_PlayStepSound);
|
||||
GAMEHOOK_REGISTRY(PM_AirAccelerate);
|
||||
GAMEHOOK_REGISTRY(ClearMultiDamage);
|
||||
GAMEHOOK_REGISTRY(AddMultiDamage);
|
||||
GAMEHOOK_REGISTRY(ApplyMultiDamage);
|
||||
GAMEHOOK_REGISTRY(BuyItem);
|
||||
GAMEHOOK_REGISTRY(CSGameRules_Think);
|
||||
GAMEHOOK_REGISTRY(CSGameRules_TeamFull);
|
||||
GAMEHOOK_REGISTRY(CSGameRules_TeamStacked);
|
||||
GAMEHOOK_REGISTRY(CSGameRules_PlayerGotWeapon);
|
||||
GAMEHOOK_REGISTRY(CBotManager_OnEvent);
|
||||
GAMEHOOK_REGISTRY(CBasePlayer_CheckTimeBasedDamage);
|
||||
GAMEHOOK_REGISTRY(CBasePlayer_EntSelectSpawnPoint);
|
||||
GAMEHOOK_REGISTRY(CBasePlayerWeapon_ItemPostFrame);
|
||||
GAMEHOOK_REGISTRY(CBasePlayerWeapon_KickBack);
|
||||
GAMEHOOK_REGISTRY(CBasePlayerWeapon_SendWeaponAnim);
|
||||
GAMEHOOK_REGISTRY(CSGameRules_SendDeathMessage);
|
||||
|
||||
GAMEHOOK_REGISTRY(CBasePlayer_PlayerDeathThink);
|
||||
GAMEHOOK_REGISTRY(CBasePlayer_Observer_Think);
|
||||
GAMEHOOK_REGISTRY(CBasePlayer_RemoveAllItems);
|
||||
GAMEHOOK_REGISTRY(CBasePlayer_UpdateStatusBar);
|
||||
GAMEHOOK_REGISTRY(CBasePlayer_TakeDamageImpulse);
|
||||
|
||||
int CReGameApi::GetMajorVersion() {
|
||||
return REGAMEDLL_API_VERSION_MAJOR;
|
||||
@ -271,48 +400,4 @@ bool CReGameApi::BGetIGameRules(const char *pchVersion) const
|
||||
return false;
|
||||
}
|
||||
|
||||
EXT_FUNC void Regamedll_ChangeString_api(char *&dest, const char *source)
|
||||
{
|
||||
size_t len = Q_strlen(source);
|
||||
if (dest == nullptr || Q_strlen(dest) != len) {
|
||||
delete [] dest;
|
||||
dest = new char [len + 1];
|
||||
}
|
||||
|
||||
Q_strcpy(dest, source);
|
||||
}
|
||||
|
||||
EXT_FUNC void RadiusDamage_api(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType)
|
||||
{
|
||||
RadiusDamage(vecSrc, pevInflictor, pevAttacker, flDamage, flRadius, iClassIgnore, bitsDamageType);
|
||||
}
|
||||
|
||||
EXT_FUNC void ClearMultiDamage_api()
|
||||
{
|
||||
ClearMultiDamage();
|
||||
}
|
||||
|
||||
EXT_FUNC void ApplyMultiDamage_api(entvars_t *pevInflictor, entvars_t *pevAttacker)
|
||||
{
|
||||
ApplyMultiDamage(pevInflictor, pevAttacker);
|
||||
}
|
||||
|
||||
EXT_FUNC void AddMultiDamage_api(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType)
|
||||
{
|
||||
AddMultiDamage(pevInflictor, pEntity, flDamage, bitsDamageType);
|
||||
}
|
||||
|
||||
EXT_FUNC void UTIL_RestartOther_api(const char *szClassname) {
|
||||
UTIL_RestartOther(szClassname);
|
||||
}
|
||||
|
||||
EXT_FUNC void UTIL_ResetEntities_api() {
|
||||
UTIL_ResetEntities();
|
||||
}
|
||||
|
||||
EXT_FUNC void UTIL_RemoveOther_api(const char *szClassname, int nCount)
|
||||
{
|
||||
UTIL_RemoveOther(szClassname, nCount);
|
||||
}
|
||||
|
||||
EXPOSE_SINGLE_INTERFACE(CReGameApi, IReGameApi, VRE_GAMEDLL_API_VERSION);
|
||||
|
@ -458,8 +458,8 @@ typedef IHookChainClassImpl<void, class CHalfLifeMultiplay> CReGameHook_CSGameRu
|
||||
typedef IHookChainRegistryClassEmptyImpl<void, class CHalfLifeMultiplay> CReGameHookRegistry_CSGameRules_RemoveGuns;
|
||||
|
||||
// CHalfLifeMultiplay::GiveC4 hook
|
||||
typedef IHookChainClassImpl<void, class CHalfLifeMultiplay> CReGameHook_CSGameRules_GiveC4;
|
||||
typedef IHookChainRegistryClassEmptyImpl<void, class CHalfLifeMultiplay> CReGameHookRegistry_CSGameRules_GiveC4;
|
||||
typedef IHookChainClassImpl<CBasePlayer *, class CHalfLifeMultiplay> CReGameHook_CSGameRules_GiveC4;
|
||||
typedef IHookChainRegistryClassEmptyImpl<CBasePlayer *, class CHalfLifeMultiplay> CReGameHookRegistry_CSGameRules_GiveC4;
|
||||
|
||||
// CHalfLifeMultiplay::ChangeLevel hook
|
||||
typedef IHookChainClassImpl<void, class CHalfLifeMultiplay> CReGameHook_CSGameRules_ChangeLevel;
|
||||
@ -645,6 +645,118 @@ typedef IHookChainRegistryClassImpl<void, CBasePlayer> CReGameHookRegistry_CBase
|
||||
typedef IHookChainImpl<void, CGameRules **> CReGameHook_FreeGameRules;
|
||||
typedef IHookChainRegistryImpl<void, CGameRules **> CReGameHookRegistry_FreeGameRules;
|
||||
|
||||
// PM_LadderMove hook
|
||||
typedef IHookChainImpl<void, struct physent_s *> CReGameHook_PM_LadderMove;
|
||||
typedef IHookChainRegistryImpl<void, struct physent_s *> CReGameHookRegistry_PM_LadderMove;
|
||||
|
||||
// PM_WaterJump hook
|
||||
typedef IHookChainImpl<void> CReGameHook_PM_WaterJump;
|
||||
typedef IHookChainRegistryImpl<void> CReGameHookRegistry_PM_WaterJump;
|
||||
|
||||
// PM_CheckWaterJump hook
|
||||
typedef IHookChainImpl<void> CReGameHook_PM_CheckWaterJump;
|
||||
typedef IHookChainRegistryImpl<void> CReGameHookRegistry_PM_CheckWaterJump;
|
||||
|
||||
// PM_Jump hook
|
||||
typedef IHookChainImpl<void> CReGameHook_PM_Jump;
|
||||
typedef IHookChainRegistryImpl<void> CReGameHookRegistry_PM_Jump;
|
||||
|
||||
// PM_Duck hook
|
||||
typedef IHookChainImpl<void> CReGameHook_PM_Duck;
|
||||
typedef IHookChainRegistryImpl<void> CReGameHookRegistry_PM_Duck;
|
||||
|
||||
// PM_UnDuck hook
|
||||
typedef IHookChainImpl<void> CReGameHook_PM_UnDuck;
|
||||
typedef IHookChainRegistryImpl<void> CReGameHookRegistry_PM_UnDuck;
|
||||
|
||||
// PM_PlayStepSound hook
|
||||
typedef IHookChainImpl<void, int, float> CReGameHook_PM_PlayStepSound;
|
||||
typedef IHookChainRegistryImpl<void, int, float> CReGameHookRegistry_PM_PlayStepSound;
|
||||
|
||||
// PM_AirAccelerate hook
|
||||
typedef IHookChainImpl<void, vec_t *, float, float> CReGameHook_PM_AirAccelerate;
|
||||
typedef IHookChainRegistryImpl<void, vec_t *, float, float> CReGameHookRegistry_PM_AirAccelerate;
|
||||
|
||||
// ClearMultiDamage hook
|
||||
typedef IHookChainImpl<void> CReGameHook_ClearMultiDamage;
|
||||
typedef IHookChainRegistryImpl<void> CReGameHookRegistry_ClearMultiDamage;
|
||||
|
||||
// AddMultiDamage hook
|
||||
typedef IHookChainImpl<void, entvars_t *, CBaseEntity *, float, int> CReGameHook_AddMultiDamage;
|
||||
typedef IHookChainRegistryImpl<void, entvars_t *, CBaseEntity *, float, int> CReGameHookRegistry_AddMultiDamage;
|
||||
|
||||
// ApplyMultiDamage hook
|
||||
typedef IHookChainImpl<void, entvars_t *, entvars_t *> CReGameHook_ApplyMultiDamage;
|
||||
typedef IHookChainRegistryImpl<void, entvars_t *, entvars_t *> CReGameHookRegistry_ApplyMultiDamage;
|
||||
|
||||
// BuyItem hook
|
||||
typedef IHookChainImpl<void, CBasePlayer *, int> CReGameHook_BuyItem;
|
||||
typedef IHookChainRegistryImpl<void, CBasePlayer *, int> CReGameHookRegistry_BuyItem;
|
||||
|
||||
// CHalfLifeMultiplay::Think hook
|
||||
typedef IHookChainClassImpl<void, class CHalfLifeMultiplay> CReGameHook_CSGameRules_Think;
|
||||
typedef IHookChainRegistryClassEmptyImpl<void, class CHalfLifeMultiplay> CReGameHookRegistry_CSGameRules_Think;
|
||||
|
||||
// CHalfLifeMultiplay::TeamFull hook
|
||||
typedef IHookChainClassImpl<BOOL, class CHalfLifeMultiplay, int> CReGameHook_CSGameRules_TeamFull;
|
||||
typedef IHookChainRegistryClassEmptyImpl<BOOL, class CHalfLifeMultiplay, int> CReGameHookRegistry_CSGameRules_TeamFull;
|
||||
|
||||
// CHalfLifeMultiplay::TeamStacked hook
|
||||
typedef IHookChainClassImpl<BOOL, class CHalfLifeMultiplay, int, int> CReGameHook_CSGameRules_TeamStacked;
|
||||
typedef IHookChainRegistryClassEmptyImpl<BOOL, class CHalfLifeMultiplay, int, int> CReGameHookRegistry_CSGameRules_TeamStacked;
|
||||
|
||||
// CHalfLifeMultiplay::PlayerGotWeapon hook
|
||||
typedef IHookChainClassImpl<void, class CHalfLifeMultiplay, CBasePlayer *, CBasePlayerItem *> CReGameHook_CSGameRules_PlayerGotWeapon;
|
||||
typedef IHookChainRegistryClassEmptyImpl<void, class CHalfLifeMultiplay, CBasePlayer *, CBasePlayerItem *> CReGameHookRegistry_CSGameRules_PlayerGotWeapon;
|
||||
|
||||
// CHalfLifeMultiplay::SendDeathMessage hook
|
||||
typedef IHookChainClassImpl<void, class CHalfLifeMultiplay, CBaseEntity *, CBasePlayer *, CBasePlayer *, entvars_t *, const char *, int, int> CReGameHook_CSGameRules_SendDeathMessage;
|
||||
typedef IHookChainRegistryClassEmptyImpl<void, class CHalfLifeMultiplay, CBaseEntity *, CBasePlayer *, CBasePlayer *, entvars_t *, const char *, int, int> CReGameHookRegistry_CSGameRules_SendDeathMessage;
|
||||
|
||||
// CBotManager::OnEvent hook
|
||||
typedef IHookChainClassImpl<void, CBotManager, GameEventType, CBaseEntity *, CBaseEntity *> CReGameHook_CBotManager_OnEvent;
|
||||
typedef IHookChainRegistryClassEmptyImpl<void, CBotManager, GameEventType, CBaseEntity*, CBaseEntity*> CReGameHookRegistry_CBotManager_OnEvent;
|
||||
|
||||
// CBasePlayer::CheckTimeBasedDamage hook
|
||||
typedef IHookChainClassImpl<void, CBasePlayer> CReGameHook_CBasePlayer_CheckTimeBasedDamage;
|
||||
typedef IHookChainRegistryClassImpl<void, CBasePlayer> CReGameHookRegistry_CBasePlayer_CheckTimeBasedDamage;
|
||||
|
||||
// CBasePlayer::EntSelectSpawnPoint hook
|
||||
typedef IHookChainClassImpl<edict_t *, CBasePlayer> CReGameHook_CBasePlayer_EntSelectSpawnPoint;
|
||||
typedef IHookChainRegistryClassImpl<edict_t *, CBasePlayer> CReGameHookRegistry_CBasePlayer_EntSelectSpawnPoint;
|
||||
|
||||
// CBasePlayerWeapon::ItemPostFrame hook
|
||||
typedef IHookChainClassImpl<void, CBasePlayerWeapon> CReGameHook_CBasePlayerWeapon_ItemPostFrame;
|
||||
typedef IHookChainRegistryClassImpl<void, CBasePlayerWeapon> CReGameHookRegistry_CBasePlayerWeapon_ItemPostFrame;
|
||||
|
||||
// CBasePlayerWeapon::KickBack hook
|
||||
typedef IHookChainClassImpl<void, CBasePlayerWeapon, float, float, float, float, float, float, int> CReGameHook_CBasePlayerWeapon_KickBack;
|
||||
typedef IHookChainRegistryClassImpl<void, CBasePlayerWeapon, float, float, float, float, float, float, int> CReGameHookRegistry_CBasePlayerWeapon_KickBack;
|
||||
|
||||
// CBasePlayerWeapon::SendWeaponAnim hook
|
||||
typedef IHookChainClassImpl<void, CBasePlayerWeapon, int, int> CReGameHook_CBasePlayerWeapon_SendWeaponAnim;
|
||||
typedef IHookChainRegistryClassImpl<void, CBasePlayerWeapon, int, int> CReGameHookRegistry_CBasePlayerWeapon_SendWeaponAnim;
|
||||
|
||||
// CBasePlayer::PlayerDeathThink hook
|
||||
typedef IHookChainClassImpl<void, CBasePlayer> CReGameHook_CBasePlayer_PlayerDeathThink;
|
||||
typedef IHookChainRegistryClassImpl<void, CBasePlayer> CReGameHookRegistry_CBasePlayer_PlayerDeathThink;
|
||||
|
||||
// CBasePlayer::Observer_Think hook
|
||||
typedef IHookChainClassImpl<void, CBasePlayer> CReGameHook_CBasePlayer_Observer_Think;
|
||||
typedef IHookChainRegistryClassImpl<void, CBasePlayer> CReGameHookRegistry_CBasePlayer_Observer_Think;
|
||||
|
||||
// CBasePlayer::RemoveAllItems hook
|
||||
typedef IHookChainClassImpl<void, CBasePlayer, BOOL> CReGameHook_CBasePlayer_RemoveAllItems;
|
||||
typedef IHookChainRegistryClassImpl<void, CBasePlayer, BOOL> CReGameHookRegistry_CBasePlayer_RemoveAllItems;
|
||||
|
||||
// CBasePlayer::UpdateStatusBar hook
|
||||
typedef IHookChainClassImpl<void, CBasePlayer> CReGameHook_CBasePlayer_UpdateStatusBar;
|
||||
typedef IHookChainRegistryClassImpl<void, CBasePlayer> CReGameHookRegistry_CBasePlayer_UpdateStatusBar;
|
||||
|
||||
// CBasePlayer::TakeDamageImpulse hook
|
||||
typedef IHookChainClassImpl<void, CBasePlayer, CBasePlayer *, float, float> CReGameHook_CBasePlayer_TakeDamageImpulse;
|
||||
typedef IHookChainRegistryClassImpl<void, CBasePlayer, CBasePlayer *, float, float> CReGameHookRegistry_CBasePlayer_TakeDamageImpulse;
|
||||
|
||||
class CReGameHookchains: public IReGameHookchains {
|
||||
public:
|
||||
// CBasePlayer virtual
|
||||
@ -779,6 +891,35 @@ public:
|
||||
CReGameHookRegistry_CBasePlayer_JoiningThink m_CBasePlayer_JoiningThink;
|
||||
|
||||
CReGameHookRegistry_FreeGameRules m_FreeGameRules;
|
||||
CReGameHookRegistry_PM_LadderMove m_PM_LadderMove;
|
||||
CReGameHookRegistry_PM_WaterJump m_PM_WaterJump;
|
||||
CReGameHookRegistry_PM_CheckWaterJump m_PM_CheckWaterJump;
|
||||
CReGameHookRegistry_PM_Jump m_PM_Jump;
|
||||
CReGameHookRegistry_PM_Duck m_PM_Duck;
|
||||
CReGameHookRegistry_PM_UnDuck m_PM_UnDuck;
|
||||
CReGameHookRegistry_PM_PlayStepSound m_PM_PlayStepSound;
|
||||
CReGameHookRegistry_PM_AirAccelerate m_PM_AirAccelerate;
|
||||
CReGameHookRegistry_ClearMultiDamage m_ClearMultiDamage;
|
||||
CReGameHookRegistry_AddMultiDamage m_AddMultiDamage;
|
||||
CReGameHookRegistry_ApplyMultiDamage m_ApplyMultiDamage;
|
||||
CReGameHookRegistry_BuyItem m_BuyItem;
|
||||
CReGameHookRegistry_CSGameRules_Think m_CSGameRules_Think;
|
||||
CReGameHookRegistry_CSGameRules_TeamFull m_CSGameRules_TeamFull;
|
||||
CReGameHookRegistry_CSGameRules_TeamStacked m_CSGameRules_TeamStacked;
|
||||
CReGameHookRegistry_CSGameRules_PlayerGotWeapon m_CSGameRules_PlayerGotWeapon;
|
||||
CReGameHookRegistry_CBotManager_OnEvent m_CBotManager_OnEvent;
|
||||
CReGameHookRegistry_CBasePlayer_CheckTimeBasedDamage m_CBasePlayer_CheckTimeBasedDamage;
|
||||
CReGameHookRegistry_CBasePlayer_EntSelectSpawnPoint m_CBasePlayer_EntSelectSpawnPoint;
|
||||
CReGameHookRegistry_CBasePlayerWeapon_ItemPostFrame m_CBasePlayerWeapon_ItemPostFrame;
|
||||
CReGameHookRegistry_CBasePlayerWeapon_KickBack m_CBasePlayerWeapon_KickBack;
|
||||
CReGameHookRegistry_CBasePlayerWeapon_SendWeaponAnim m_CBasePlayerWeapon_SendWeaponAnim;
|
||||
CReGameHookRegistry_CSGameRules_SendDeathMessage m_CSGameRules_SendDeathMessage;
|
||||
|
||||
CReGameHookRegistry_CBasePlayer_PlayerDeathThink m_CBasePlayer_PlayerDeathThink;
|
||||
CReGameHookRegistry_CBasePlayer_Observer_Think m_CBasePlayer_Observer_Think;
|
||||
CReGameHookRegistry_CBasePlayer_RemoveAllItems m_CBasePlayer_RemoveAllItems;
|
||||
CReGameHookRegistry_CBasePlayer_UpdateStatusBar m_CBasePlayer_UpdateStatusBar;
|
||||
CReGameHookRegistry_CBasePlayer_TakeDamageImpulse m_CBasePlayer_TakeDamageImpulse;
|
||||
|
||||
public:
|
||||
virtual IReGameHookRegistry_CBasePlayer_Spawn *CBasePlayer_Spawn();
|
||||
@ -912,6 +1053,35 @@ public:
|
||||
virtual IReGameHookRegistry_CBasePlayer_JoiningThink *CBasePlayer_JoiningThink();
|
||||
|
||||
virtual IReGameHookRegistry_FreeGameRules *FreeGameRules();
|
||||
virtual IReGameHookRegistry_PM_LadderMove *PM_LadderMove();
|
||||
virtual IReGameHookRegistry_PM_WaterJump *PM_WaterJump();
|
||||
virtual IReGameHookRegistry_PM_CheckWaterJump *PM_CheckWaterJump();
|
||||
virtual IReGameHookRegistry_PM_Jump *PM_Jump();
|
||||
virtual IReGameHookRegistry_PM_Duck *PM_Duck();
|
||||
virtual IReGameHookRegistry_PM_UnDuck *PM_UnDuck();
|
||||
virtual IReGameHookRegistry_PM_PlayStepSound *PM_PlayStepSound();
|
||||
virtual IReGameHookRegistry_PM_AirAccelerate *PM_AirAccelerate();
|
||||
virtual IReGameHookRegistry_ClearMultiDamage *ClearMultiDamage();
|
||||
virtual IReGameHookRegistry_AddMultiDamage *AddMultiDamage();
|
||||
virtual IReGameHookRegistry_ApplyMultiDamage *ApplyMultiDamage();
|
||||
virtual IReGameHookRegistry_BuyItem *BuyItem();
|
||||
virtual IReGameHookRegistry_CSGameRules_Think *CSGameRules_Think();
|
||||
virtual IReGameHookRegistry_CSGameRules_TeamFull *CSGameRules_TeamFull();
|
||||
virtual IReGameHookRegistry_CSGameRules_TeamStacked *CSGameRules_TeamStacked();
|
||||
virtual IReGameHookRegistry_CSGameRules_PlayerGotWeapon *CSGameRules_PlayerGotWeapon();
|
||||
virtual IReGameHookRegistry_CBotManager_OnEvent *CBotManager_OnEvent();
|
||||
virtual IReGameHookRegistry_CBasePlayer_CheckTimeBasedDamage *CBasePlayer_CheckTimeBasedDamage();
|
||||
virtual IReGameHookRegistry_CBasePlayer_EntSelectSpawnPoint *CBasePlayer_EntSelectSpawnPoint();
|
||||
virtual IReGameHookRegistry_CBasePlayerWeapon_ItemPostFrame *CBasePlayerWeapon_ItemPostFrame();
|
||||
virtual IReGameHookRegistry_CBasePlayerWeapon_KickBack *CBasePlayerWeapon_KickBack();
|
||||
virtual IReGameHookRegistry_CBasePlayerWeapon_SendWeaponAnim *CBasePlayerWeapon_SendWeaponAnim();
|
||||
virtual IReGameHookRegistry_CSGameRules_SendDeathMessage *CSGameRules_SendDeathMessage();
|
||||
|
||||
virtual IReGameHookRegistry_CBasePlayer_PlayerDeathThink *CBasePlayer_PlayerDeathThink();
|
||||
virtual IReGameHookRegistry_CBasePlayer_Observer_Think *CBasePlayer_Observer_Think();
|
||||
virtual IReGameHookRegistry_CBasePlayer_RemoveAllItems *CBasePlayer_RemoveAllItems();
|
||||
virtual IReGameHookRegistry_CBasePlayer_UpdateStatusBar *CBasePlayer_UpdateStatusBar();
|
||||
virtual IReGameHookRegistry_CBasePlayer_TakeDamageImpulse *CBasePlayer_TakeDamageImpulse();
|
||||
};
|
||||
|
||||
extern CReGameHookchains g_ReGameHookchains;
|
||||
@ -938,14 +1108,3 @@ public:
|
||||
EXT_FUNC virtual bool BGetICSEntity(const char *pchVersion) const;
|
||||
EXT_FUNC virtual bool BGetIGameRules(const char *pchVersion) const;
|
||||
};
|
||||
|
||||
void Regamedll_ChangeString_api(char *&dest, const char *source);
|
||||
void RadiusDamage_api(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType);
|
||||
|
||||
void ClearMultiDamage_api();
|
||||
void ApplyMultiDamage_api(entvars_t *pevInflictor, entvars_t *pevAttacker);
|
||||
void AddMultiDamage_api(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType);
|
||||
|
||||
void UTIL_RestartOther_api(const char *szClassname);
|
||||
void UTIL_ResetEntities_api();
|
||||
void UTIL_RemoveOther_api(const char *szClassname, int nCount = 0);
|
||||
|
@ -30,15 +30,15 @@
|
||||
|
||||
void CCSEntity::FireBullets(int iShots, Vector &vecSrc, Vector &vecDirShooting, Vector &vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker)
|
||||
{
|
||||
m_pContainingEntity->FireBullets(iShots, vecSrc, vecDirShooting, vecSpread, flDistance, iBulletType, iTracerFreq, iDamage, pevAttacker);
|
||||
BaseEntity()->FireBullets(iShots, vecSrc, vecDirShooting, vecSpread, flDistance, iBulletType, iTracerFreq, iDamage, pevAttacker);
|
||||
}
|
||||
|
||||
void CCSEntity::FireBuckshots(ULONG cShots, Vector &vecSrc, Vector &vecDirShooting, Vector &vecSpread, float flDistance, int iTracerFreq, int iDamage, entvars_t *pevAttacker)
|
||||
{
|
||||
m_pContainingEntity->FireBuckshots(cShots, vecSrc, vecDirShooting, vecSpread, flDistance, iTracerFreq, iDamage, pevAttacker);
|
||||
BaseEntity()->FireBuckshots(cShots, vecSrc, vecDirShooting, vecSpread, flDistance, iTracerFreq, iDamage, pevAttacker);
|
||||
}
|
||||
|
||||
Vector CCSEntity::FireBullets3(Vector &vecSrc, Vector &vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand)
|
||||
{
|
||||
return m_pContainingEntity->FireBullets3(vecSrc, vecDirShooting, vecSpread, flDistance, iPenetration, iBulletType, iDamage, flRangeModifier, pevAttacker, bPistol, shared_rand);
|
||||
return BaseEntity()->FireBullets3(vecSrc, vecDirShooting, vecSpread, flDistance, iPenetration, iBulletType, iDamage, flRangeModifier, pevAttacker, bPistol, shared_rand);
|
||||
}
|
||||
|
@ -43,8 +43,10 @@ EXT_FUNC bool CCSPlayer::JoinTeam(TeamName team)
|
||||
pPlayer->pev->deadflag = DEAD_DEAD;
|
||||
pPlayer->pev->health = 0;
|
||||
|
||||
if (pPlayer->m_bHasC4)
|
||||
pPlayer->DropPlayerItem("weapon_c4");
|
||||
|
||||
pPlayer->RemoveAllItems(TRUE);
|
||||
pPlayer->m_bHasC4 = false;
|
||||
|
||||
pPlayer->m_iTeam = SPECTATOR;
|
||||
pPlayer->m_iJoiningState = JOINED;
|
||||
@ -58,7 +60,7 @@ EXT_FUNC bool CCSPlayer::JoinTeam(TeamName team)
|
||||
pPlayer->StartObserver(pentSpawnSpot->v.origin, pentSpawnSpot->v.angles);
|
||||
|
||||
// do we have fadetoblack on? (need to fade their screen back in)
|
||||
if (fadetoblack.value)
|
||||
if (fadetoblack.value == FADETOBLACK_STAY)
|
||||
{
|
||||
UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 0.001, 0, 0, FFADE_IN);
|
||||
}
|
||||
@ -153,15 +155,7 @@ EXT_FUNC bool CCSPlayer::RemovePlayerItemEx(const char* pszItemName, bool bRemov
|
||||
if (!pPlayer->m_bHasDefuser)
|
||||
return false;
|
||||
|
||||
pPlayer->m_bHasDefuser = false;
|
||||
pPlayer->pev->body = 0;
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pPlayer->pev);
|
||||
WRITE_BYTE(STATUSICON_HIDE);
|
||||
WRITE_STRING("defuser");
|
||||
MESSAGE_END();
|
||||
|
||||
pPlayer->SendItemStatus();
|
||||
pPlayer->RemoveDefuser();
|
||||
}
|
||||
// item_longjump
|
||||
else if (FStrEq(pszItemName, "longjump"))
|
||||
@ -225,38 +219,20 @@ EXT_FUNC bool CCSPlayer::RemovePlayerItemEx(const char* pszItemName, bool bRemov
|
||||
return true; // ammo was reduced, this will be considered a successful result
|
||||
}
|
||||
|
||||
if (bRemoveAmmo) {
|
||||
pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()] = 0;
|
||||
}
|
||||
|
||||
if (pItem == pPlayer->m_pActiveItem) {
|
||||
((CBasePlayerWeapon *)pItem)->RetireWeapon();
|
||||
}
|
||||
|
||||
if (bRemoveAmmo) {
|
||||
pPlayer->m_rgAmmo[ pItem->PrimaryAmmoIndex() ] = 0;
|
||||
if (pItem->CanHolster() && pItem != pPlayer->m_pActiveItem && !(pPlayer->pev->weapons &(1 << pItem->m_iId))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pPlayer->RemovePlayerItem(pItem))
|
||||
{
|
||||
if (FClassnameIs(pItem->pev, "weapon_c4")) {
|
||||
pPlayer->m_bHasC4 = false;
|
||||
pPlayer->pev->body = 0;
|
||||
pPlayer->SetBombIcon(FALSE);
|
||||
pPlayer->SetProgressBarTime(0);
|
||||
}
|
||||
|
||||
pPlayer->pev->weapons &= ~(1 << pItem->m_iId);
|
||||
// No more weapon
|
||||
if ((pPlayer->pev->weapons & ~(1 << WEAPON_SUIT)) == 0) {
|
||||
pPlayer->m_iHideHUD |= HIDEHUD_WEAPONS;
|
||||
}
|
||||
|
||||
pItem->Kill();
|
||||
|
||||
if (!pPlayer->m_rgpPlayerItems[PRIMARY_WEAPON_SLOT]) {
|
||||
pPlayer->m_bHasPrimary = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return pItem->DestroyItem();
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -273,11 +249,13 @@ EXT_FUNC CBaseEntity *CCSPlayer::GiveNamedItemEx(const char *pszName)
|
||||
|
||||
if (FStrEq(pszName, "weapon_c4")) {
|
||||
pPlayer->m_bHasC4 = true;
|
||||
pPlayer->SetBombIcon();
|
||||
|
||||
if (pPlayer->m_iTeam == TERRORIST) {
|
||||
pPlayer->pev->body = 1;
|
||||
}
|
||||
|
||||
pPlayer->SetBombIcon();
|
||||
|
||||
} else if (FStrEq(pszName, "weapon_shield")) {
|
||||
pPlayer->DropPrimary();
|
||||
pPlayer->DropPlayerItem("weapon_elite");
|
||||
@ -290,7 +268,7 @@ EXT_FUNC CBaseEntity *CCSPlayer::GiveNamedItemEx(const char *pszName)
|
||||
|
||||
EXT_FUNC bool CCSPlayer::IsConnected() const
|
||||
{
|
||||
return m_pContainingEntity->has_disconnected == false;
|
||||
return BaseEntity()->has_disconnected == false;
|
||||
}
|
||||
|
||||
EXT_FUNC void CCSPlayer::SetAnimation(PLAYER_ANIM playerAnim)
|
||||
@ -318,14 +296,14 @@ EXT_FUNC void CCSPlayer::GiveShield(bool bDeploy)
|
||||
BasePlayer()->GiveShield(bDeploy);
|
||||
}
|
||||
|
||||
EXT_FUNC void CCSPlayer::DropShield(bool bDeploy)
|
||||
EXT_FUNC CBaseEntity *CCSPlayer::DropShield(bool bDeploy)
|
||||
{
|
||||
BasePlayer()->DropShield(bDeploy);
|
||||
return BasePlayer()->DropShield(bDeploy);
|
||||
}
|
||||
|
||||
EXT_FUNC void CCSPlayer::DropPlayerItem(const char *pszItemName)
|
||||
EXT_FUNC CBaseEntity *CCSPlayer::DropPlayerItem(const char *pszItemName)
|
||||
{
|
||||
BasePlayer()->DropPlayerItem(pszItemName);
|
||||
return BasePlayer()->DropPlayerItem(pszItemName);
|
||||
}
|
||||
|
||||
EXT_FUNC bool CCSPlayer::RemoveShield()
|
||||
@ -434,6 +412,11 @@ EXT_FUNC void CCSPlayer::Observer_SetMode(int iMode)
|
||||
BasePlayer()->Observer_SetMode(iMode);
|
||||
}
|
||||
|
||||
EXT_FUNC void CCSPlayer::Observer_FindNextPlayer(bool bReverse, const char *name)
|
||||
{
|
||||
BasePlayer()->Observer_FindNextPlayer(bReverse, name);
|
||||
}
|
||||
|
||||
EXT_FUNC bool CCSPlayer::SelectSpawnSpot(const char *pEntClassName, CBaseEntity *&pSpot)
|
||||
{
|
||||
return BasePlayer()->SelectSpawnSpot(pEntClassName, pSpot);
|
||||
@ -556,6 +539,11 @@ EXT_FUNC bool CCSPlayer::CheckActivityInGame()
|
||||
return (fabs(deltaYaw) >= 0.1f && fabs(deltaPitch) >= 0.1f);
|
||||
}
|
||||
|
||||
EXT_FUNC void CCSPlayer::TakeDamageImpulse(CBasePlayer *pAttacker, float flKnockbackForce, float flVelModifier)
|
||||
{
|
||||
BasePlayer()->TakeDamageImpulse(pAttacker, flKnockbackForce, flVelModifier);
|
||||
}
|
||||
|
||||
void CCSPlayer::ResetVars()
|
||||
{
|
||||
m_szModel[0] = '\0';
|
||||
@ -574,10 +562,24 @@ void CCSPlayer::ResetVars()
|
||||
m_bSpawnProtectionEffects = false;
|
||||
}
|
||||
|
||||
// Resets all stats
|
||||
void CCSPlayer::ResetAllStats()
|
||||
{
|
||||
// Resets the kill history for this player
|
||||
for (int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
m_iNumKilledByUnanswered[i] = 0;
|
||||
m_bPlayerDominated[i] = false;
|
||||
}
|
||||
|
||||
m_DamageList.Clear();
|
||||
}
|
||||
|
||||
void CCSPlayer::OnSpawn()
|
||||
{
|
||||
m_bGameForcingRespawn = false;
|
||||
m_flRespawnPending = 0.0f;
|
||||
m_DamageList.Clear();
|
||||
}
|
||||
|
||||
void CCSPlayer::OnKilled()
|
||||
@ -595,3 +597,34 @@ void CCSPlayer::OnKilled()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CCSPlayer::OnConnect()
|
||||
{
|
||||
ResetVars();
|
||||
ResetAllStats();
|
||||
m_iUserID = GETPLAYERUSERID(BasePlayer()->edict());
|
||||
}
|
||||
|
||||
// Remember this amount of damage that we dealt for stats
|
||||
void CCSPlayer::RecordDamage(CBasePlayer *pAttacker, float flDamage, float flFlashDurationTime)
|
||||
{
|
||||
if (!pAttacker || !pAttacker->IsPlayer())
|
||||
return;
|
||||
|
||||
int attackerIndex = pAttacker->entindex() - 1;
|
||||
if (attackerIndex < 0 || attackerIndex >= MAX_CLIENTS)
|
||||
return;
|
||||
|
||||
CCSPlayer *pCSAttacker = pAttacker->CSPlayer();
|
||||
|
||||
// Accumulate damage
|
||||
CDamageRecord_t &record = m_DamageList[attackerIndex];
|
||||
if (record.flDamage > 0 && record.userId != pCSAttacker->m_iUserID)
|
||||
record.flDamage = 0; // reset damage if attacker became another client
|
||||
|
||||
record.flDamage += flDamage;
|
||||
record.userId = pCSAttacker->m_iUserID;
|
||||
|
||||
if (flFlashDurationTime > 0)
|
||||
record.flFlashDurationTime = gpGlobals->time + flFlashDurationTime;
|
||||
}
|
||||
|
54
regamedll/dlls/API/CSPlayerWeapon.cpp
Normal file
54
regamedll/dlls/API/CSPlayerWeapon.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
EXT_FUNC BOOL CCSPlayerWeapon::DefaultDeploy(char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal)
|
||||
{
|
||||
return BasePlayerWeapon()->DefaultDeploy(szViewModel, szWeaponModel, iAnim, szAnimExt, skiplocal);
|
||||
}
|
||||
|
||||
EXT_FUNC int CCSPlayerWeapon::DefaultReload(int iClipSize, int iAnim, float fDelay)
|
||||
{
|
||||
return BasePlayerWeapon()->DefaultReload(iClipSize, iAnim, fDelay);
|
||||
}
|
||||
|
||||
EXT_FUNC bool CCSPlayerWeapon::DefaultShotgunReload(int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1, const char *pszReloadSound2)
|
||||
{
|
||||
return BasePlayerWeapon()->DefaultShotgunReload(iAnim, iStartAnim, fDelay, fStartDelay, pszReloadSound1, pszReloadSound2);
|
||||
}
|
||||
|
||||
EXT_FUNC void CCSPlayerWeapon::KickBack(float up_base, float lateral_base, float up_modifier, float lateral_modifier, float up_max, float lateral_max, int direction_change)
|
||||
{
|
||||
BasePlayerWeapon()->KickBack(up_base, lateral_base, up_modifier, lateral_modifier, up_max, lateral_max, direction_change);
|
||||
}
|
||||
|
||||
EXT_FUNC void CCSPlayerWeapon::SendWeaponAnim(int iAnim, int skiplocal)
|
||||
{
|
||||
BasePlayerWeapon()->SendWeaponAnim(iAnim, skiplocal);
|
||||
}
|
@ -10,7 +10,11 @@ void CBasePlayerAmmo::Spawn()
|
||||
|
||||
SetTouch(&CBasePlayerAmmo::DefaultTouch);
|
||||
|
||||
if (g_pGameRules->IsMultiplayer())
|
||||
if (g_pGameRules->IsMultiplayer()
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
&& g_pGameRules->AmmoShouldRespawn(this) == GR_AMMO_RESPAWN_NO
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SetThink(&CBaseEntity::SUB_Remove);
|
||||
pev->nextthink = gpGlobals->time + 2.0f;
|
||||
@ -20,7 +24,7 @@ void CBasePlayerAmmo::Spawn()
|
||||
BOOL CBasePlayerAmmo::AddAmmo(CBaseEntity *pOther)
|
||||
{
|
||||
auto ammoInfo = GetAmmoInfo(pev->classname);
|
||||
if (pOther->GiveAmmo(ammoInfo->buyClipSize, ammoInfo->ammoName2) == -1)
|
||||
if (!ammoInfo || pOther->GiveAmmo(ammoInfo->buyClipSize, ammoInfo->ammoName2) == -1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -179,6 +179,11 @@ NOXREF int CBaseAnimating::GetBodygroup(int iGroup)
|
||||
return ::GetBodygroup(GET_MODEL_PTR(ENT(pev)), pev, iGroup);
|
||||
}
|
||||
|
||||
float CBaseAnimating::GetSequenceDuration() const
|
||||
{
|
||||
return ::GetSequenceDuration(GET_MODEL_PTR(ENT(pev)), pev);
|
||||
}
|
||||
|
||||
int CBaseAnimating::ExtractBbox(int sequence, float *mins, float *maxs)
|
||||
{
|
||||
return ::ExtractBbox(GET_MODEL_PTR(ENT(pev)), sequence, mins, maxs);
|
||||
|
@ -12,7 +12,7 @@ server_studio_api_t IEngineStudio;
|
||||
studiohdr_t *g_pstudiohdr;
|
||||
|
||||
float (*g_pRotationMatrix)[3][4];
|
||||
float (*g_pBoneTransform)[128][3][4];
|
||||
float (*g_pBoneTransform)[MAXSTUDIOBONES][3][4];
|
||||
|
||||
int ExtractBbox(void *pmodel, int sequence, float *mins, float *maxs)
|
||||
{
|
||||
@ -246,6 +246,21 @@ void GetSequenceInfo(void *pmodel, entvars_t *pev, float *pflFrameRate, float *p
|
||||
*pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1);
|
||||
}
|
||||
|
||||
float GetSequenceDuration(void *pmodel, entvars_t *pev)
|
||||
{
|
||||
studiohdr_t *pstudiohdr = (studiohdr_t *)pmodel;
|
||||
if (!pstudiohdr)
|
||||
return 0; // model ptr is not valid
|
||||
|
||||
if (pev->sequence < 0 || pev->sequence >= pstudiohdr->numseq)
|
||||
return 0; // sequence is not valid
|
||||
|
||||
// get current sequence time
|
||||
mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + int(pev->sequence);
|
||||
|
||||
return pseqdesc->numframes / pseqdesc->fps;
|
||||
}
|
||||
|
||||
int GetSequenceFlags(void *pmodel, entvars_t *pev)
|
||||
{
|
||||
studiohdr_t *pstudiohdr = (studiohdr_t *)pmodel;
|
||||
@ -522,7 +537,7 @@ C_DLLEXPORT int Server_GetBlendingInterface(int version, struct sv_blending_inte
|
||||
IEngineStudio.Mod_Extradata = ((struct server_studio_api_s *)pstudio)->Mod_Extradata;
|
||||
|
||||
g_pRotationMatrix = (float (*)[3][4])rotationmatrix;
|
||||
g_pBoneTransform = (float (*)[128][3][4])bonetransform;
|
||||
g_pBoneTransform = (float (*)[MAXSTUDIOBONES][3][4])bonetransform;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -532,7 +547,9 @@ void AngleQuaternion(vec_t *angles, vec_t *quaternion)
|
||||
{
|
||||
static const ALIGN16_BEG size_t ps_signmask[4] ALIGN16_END = { 0x80000000, 0, 0x80000000, 0 };
|
||||
|
||||
__m128 a = _mm_loadu_ps(angles);
|
||||
vec4_t _ps_angles = { angles[0], angles[1], angles[2], 0.0f };
|
||||
|
||||
__m128 a = _mm_loadu_ps(_ps_angles);
|
||||
a = _mm_mul_ps(a, _mm_load_ps(_ps_0p5)); //a *= 0.5
|
||||
__m128 s, c;
|
||||
sincos_ps(a, &s, &c);
|
||||
|
@ -42,6 +42,7 @@ int LookupActivity(void *pmodel, entvars_t *pev, int activity);
|
||||
int LookupActivityHeaviest(void *pmodel, entvars_t *pev, int activity);
|
||||
int LookupSequence(void *pmodel, const char *label);
|
||||
void GetSequenceInfo(void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed);
|
||||
float GetSequenceDuration(void *pmodel, entvars_t *pev);
|
||||
int GetSequenceFlags(void *pmodel, entvars_t *pev);
|
||||
float SetController(void *pmodel, entvars_t *pev, int iController, float flValue);
|
||||
float SetBlending(void *pmodel, entvars_t *pev, int iBlender, float flValue);
|
||||
|
@ -451,17 +451,13 @@ BOOL CBaseMonster::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, f
|
||||
|
||||
if (pev->health <= 0.0f)
|
||||
{
|
||||
g_pevLastInflictor = pevInflictor;
|
||||
|
||||
if (bitsDamageType & DMG_ALWAYSGIB)
|
||||
Killed(pevAttacker, GIB_ALWAYS);
|
||||
|
||||
KilledInflicted(pevInflictor, pevAttacker, GIB_ALWAYS);
|
||||
else if (bitsDamageType & DMG_NEVERGIB)
|
||||
Killed(pevAttacker, GIB_NEVER);
|
||||
KilledInflicted(pevInflictor, pevAttacker, GIB_NEVER);
|
||||
else
|
||||
Killed(pevAttacker, GIB_NORMAL);
|
||||
KilledInflicted(pevInflictor, pevAttacker, GIB_NORMAL);
|
||||
|
||||
g_pevLastInflictor = nullptr;
|
||||
return FALSE;
|
||||
}
|
||||
if ((pev->flags & FL_MONSTER) && !FNullEnt(pevAttacker))
|
||||
|
@ -43,10 +43,7 @@ int GetBotFollowCount(CBasePlayer *pLeader)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (FStrEq(STRING(pPlayer->pev->netname), ""))
|
||||
@ -429,6 +426,20 @@ bool CCSBot::StayOnNavMesh()
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
void CCSBot::Kill()
|
||||
{
|
||||
m_LastHitGroup = HITGROUP_GENERIC;
|
||||
|
||||
// have the player kill himself
|
||||
pev->health = 0.0f;
|
||||
Killed(VARS(eoNullEntity), GIB_NEVER);
|
||||
|
||||
if (CSGameRules()->m_pVIP == this)
|
||||
CSGameRules()->m_iConsecutiveVIP = 10;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CCSBot::Panic(CBasePlayer *pEnemy)
|
||||
{
|
||||
if (IsSurprised())
|
||||
@ -671,10 +682,7 @@ CBasePlayer *CCSBot::GetImportantEnemy(bool checkVisibility) const
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (FStrEq(STRING(pPlayer->pev->netname), ""))
|
||||
@ -892,3 +900,129 @@ float CCSBot::GetRangeToFarthestEscortedHostage() const
|
||||
|
||||
return away.m_farRange;
|
||||
}
|
||||
|
||||
// Remove all occurrences of a given area from the path list
|
||||
void CCSBot::RemovePath(CNavArea *area)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < m_pathLength)
|
||||
{
|
||||
if (m_path[i].area == area)
|
||||
{
|
||||
// If this area is linked to a ladder, clear the reference
|
||||
if (m_path[i].ladder == m_pathLadder)
|
||||
m_pathLadder = nullptr;
|
||||
|
||||
m_pathLength--;
|
||||
|
||||
// adjust the current path index if the removed element is being used
|
||||
if (i == m_pathIndex)
|
||||
{
|
||||
if (i > 0)
|
||||
m_pathIndex = i - 1;
|
||||
else
|
||||
m_pathIndex = 0;
|
||||
}
|
||||
|
||||
if (m_pathLength != i)
|
||||
Q_memmove(&m_path[i], &m_path[i + 1], (m_pathLength - i) * sizeof(m_path[0]));
|
||||
|
||||
// clear the slot
|
||||
Q_memset(&m_path[m_pathLength], 0, sizeof(m_path[m_pathLength]));
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove a hiding spot from the checked spots list
|
||||
void CCSBot::RemoveHidingSpot(HidingSpot *spot)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < m_checkedHidingSpotCount)
|
||||
{
|
||||
if (m_checkedHidingSpot[i].spot == spot)
|
||||
{
|
||||
m_checkedHidingSpotCount--;
|
||||
|
||||
if (m_checkedHidingSpotCount != i)
|
||||
Q_memmove(&m_checkedHidingSpot[i], &m_checkedHidingSpot[i + 1], (m_checkedHidingSpotCount - i) * sizeof(m_checkedHidingSpot[0]));
|
||||
|
||||
// clear the slot
|
||||
Q_memset(&m_checkedHidingSpot[m_checkedHidingSpotCount], 0, sizeof(m_checkedHidingSpot[m_checkedHidingSpotCount]));
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle navigation-related cleanup when a nav area, spot, or encounter is destroyed
|
||||
void CCSBot::OnDestroyNavDataNotify(NavNotifyDestroyType navNotifyType, void *dead)
|
||||
{
|
||||
switch (navNotifyType)
|
||||
{
|
||||
case NAV_NOTIFY_DESTROY_AREA:
|
||||
{
|
||||
CNavArea *area = static_cast<CNavArea *>(dead);
|
||||
|
||||
// If the destroyed area was linked to a spot encounter, clear it
|
||||
if (m_spotEncounter)
|
||||
{
|
||||
if (m_spotEncounter->from.area == area || m_spotEncounter->to.area == area)
|
||||
m_spotEncounter = nullptr;
|
||||
}
|
||||
|
||||
RemovePath(area);
|
||||
|
||||
// Invalidate any references to the destroyed area
|
||||
|
||||
if (m_noiseArea == area)
|
||||
m_noiseArea = nullptr;
|
||||
|
||||
if (m_currentArea == area)
|
||||
m_currentArea = nullptr;
|
||||
|
||||
if (m_lastKnownArea == area)
|
||||
m_lastKnownArea = nullptr;
|
||||
|
||||
if (m_hideState.GetSearchArea() == area)
|
||||
m_hideState.SetSearchArea(nullptr);
|
||||
|
||||
if (m_huntState.GetHuntArea() == area)
|
||||
m_huntState.ClearHuntArea();
|
||||
|
||||
break;
|
||||
}
|
||||
case NAV_NOTIFY_DESTROY_SPOT_ENCOUNTER:
|
||||
{
|
||||
CNavArea *area = static_cast<CNavArea *>(dead);
|
||||
|
||||
// Remove the encounter if it references the destroyed area
|
||||
if (m_spotEncounter && area->HasSpotEncounter(m_spotEncounter))
|
||||
m_spotEncounter = nullptr;
|
||||
|
||||
break;
|
||||
}
|
||||
case NAV_NOTIFY_DESTROY_SPOT:
|
||||
{
|
||||
HidingSpot *spot = static_cast<HidingSpot *>(dead);
|
||||
|
||||
// Remove the destroyed hiding spot from the spot order list
|
||||
if (m_spotEncounter)
|
||||
{
|
||||
SpotOrderList &spotOrderList = m_spotEncounter->spotList;
|
||||
spotOrderList.erase(std::remove_if(spotOrderList.begin(), spotOrderList.end(), [&](SpotOrder &spotOrder) {
|
||||
return spotOrder.spot == spot;
|
||||
}
|
||||
), spotOrderList.end());
|
||||
}
|
||||
|
||||
RemoveHidingSpot(spot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,9 +42,6 @@ enum
|
||||
BOT_PROGGRESS_HIDE, // hide status bar progress
|
||||
};
|
||||
|
||||
extern int _navAreaCount;
|
||||
extern int _currentIndex;
|
||||
|
||||
class CCSBot;
|
||||
class BotChatterInterface;
|
||||
|
||||
@ -74,6 +71,7 @@ public:
|
||||
virtual const char *GetName() const { return "Hunt"; }
|
||||
|
||||
void ClearHuntArea() { m_huntArea = nullptr; }
|
||||
CNavArea *GetHuntArea() { return m_huntArea; }
|
||||
|
||||
private:
|
||||
CNavArea *m_huntArea;
|
||||
@ -207,6 +205,7 @@ public:
|
||||
const Vector &GetHidingSpot() const { return m_hidingSpot; }
|
||||
|
||||
void SetSearchArea(CNavArea *area) { m_searchFromArea = area; }
|
||||
CNavArea *GetSearchArea() { return m_searchFromArea; }
|
||||
void SetSearchRange(float range) { m_range = range; }
|
||||
|
||||
void SetDuration(float time) { m_duration = time; }
|
||||
@ -378,6 +377,10 @@ public:
|
||||
|
||||
bool IsBuying() const;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
void Kill();
|
||||
#endif
|
||||
|
||||
void Panic(CBasePlayer *pEnemy); // look around in panic
|
||||
void Follow(CBasePlayer *pPlayer); // begin following given Player
|
||||
void ContinueFollowing(); // continue following our leader after finishing what we were doing
|
||||
@ -532,12 +535,21 @@ public:
|
||||
bool IsAwareOfEnemyDeath() const; // return true if we *noticed* that our enemy died
|
||||
int GetLastVictimID() const; // return the ID (entindex) of the last victim we killed, or zero
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
bool CanSeeSniper(void) const; ///< return true if we can see an enemy sniper
|
||||
bool HasSeenSniperRecently(void) const; ///< return true if we have seen a sniper recently
|
||||
#endif
|
||||
|
||||
// navigation
|
||||
bool HasPath() const;
|
||||
void DestroyPath();
|
||||
|
||||
float GetFeetZ() const; // return Z of bottom of feet
|
||||
|
||||
void OnDestroyNavDataNotify(NavNotifyDestroyType navNotifyType, void *dead);
|
||||
void RemovePath(CNavArea *area);
|
||||
void RemoveHidingSpot(HidingSpot *spot);
|
||||
|
||||
enum PathResult
|
||||
{
|
||||
PROGRESSING, // we are moving along the path
|
||||
@ -920,6 +932,11 @@ private:
|
||||
|
||||
float m_fireWeaponTimestamp;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
bool m_isEnemySniperVisible; ///< do we see an enemy sniper right now
|
||||
CountdownTimer m_sawEnemySniperTimer; ///< tracking time since saw enemy sniper
|
||||
#endif
|
||||
|
||||
// reaction time system
|
||||
enum { MAX_ENEMY_QUEUE = 20 };
|
||||
struct ReactionState
|
||||
@ -970,7 +987,6 @@ private:
|
||||
const CNavNode *m_navNodeList;
|
||||
CNavNode *m_currentNode;
|
||||
NavDirType m_generationDir;
|
||||
NavAreaList::iterator m_analyzeIter;
|
||||
|
||||
enum ProcessType
|
||||
{
|
||||
@ -1109,6 +1125,11 @@ inline bool CCSBot::IsAtBombsite()
|
||||
|
||||
inline CCSBot::MoraleType CCSBot::GetMorale() const
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (cv_bot_excellent_morale.value != 0.0f)
|
||||
return EXCELLENT;
|
||||
#endif
|
||||
|
||||
return m_morale;
|
||||
}
|
||||
|
||||
@ -1250,6 +1271,18 @@ inline int CCSBot::GetLastVictimID() const
|
||||
return m_lastVictimID;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
inline bool CCSBot::CanSeeSniper(void) const
|
||||
{
|
||||
return m_isEnemySniperVisible;
|
||||
}
|
||||
|
||||
inline bool CCSBot::HasSeenSniperRecently(void) const
|
||||
{
|
||||
return !m_sawEnemySniperTimer.IsElapsed();
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool CCSBot::HasPath() const
|
||||
{
|
||||
return m_pathLength != 0;
|
||||
|
@ -65,10 +65,7 @@ void BotMeme::Transmit(CCSBot *pSender) const
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (FStrEq(STRING(pPlayer->pev->netname), ""))
|
||||
@ -249,6 +246,17 @@ void BotHostageBeingTakenMeme::Interpret(CCSBot *pSender, CCSBot *pReceiver) con
|
||||
pReceiver->GetChatter()->Say("Affirmative");
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* A teammate warned about snipers, so we shouldn't warn again for awhile
|
||||
*/
|
||||
void BotWarnSniperMeme::Interpret(CCSBot* sender, CCSBot* receiver) const
|
||||
{
|
||||
receiver->GetChatter()->FriendSpottedSniper();
|
||||
}
|
||||
#endif
|
||||
|
||||
BotSpeakable::BotSpeakable()
|
||||
{
|
||||
m_phrase = nullptr;
|
||||
@ -467,6 +475,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
|
||||
phraseData = SharedParse(phraseData);
|
||||
if (!phraseData)
|
||||
{
|
||||
if (phrase) delete phrase;
|
||||
CONSOLE_ECHO("Error parsing '%s' - expected identifier\n", filename);
|
||||
FREE_FILE(phraseDataFile);
|
||||
return false;
|
||||
@ -540,8 +549,13 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex)
|
||||
else if (!Q_stricmp("UNDEFINED", token))
|
||||
placeCriteria = UNDEFINED_PLACE;
|
||||
else
|
||||
{
|
||||
placeCriteria = TheBotPhrases->NameToID(token);
|
||||
|
||||
if (!TheBotPhrases->IsValid() && placeCriteria == UNDEFINED_PLACE)
|
||||
placeCriteria = TheNavAreaGrid.NameToID(token);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1267,6 +1281,9 @@ void BotChatterInterface::Reset()
|
||||
m_planInterval.Invalidate();
|
||||
m_encourageTimer.Invalidate();
|
||||
m_escortingHostageTimer.Invalidate();
|
||||
#ifdef REGAMEDLL_ADD
|
||||
m_warnSniperTimer.Invalidate();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Register a statement for speaking
|
||||
@ -1520,10 +1537,7 @@ BotStatement *BotChatterInterface::GetActiveStatement()
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (FStrEq(STRING(pPlayer->pev->netname), ""))
|
||||
@ -1626,6 +1640,42 @@ void BotChatterInterface::EnemySpotted()
|
||||
AddStatement(say);
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* If a friend warned of snipers, don't warn again for awhile
|
||||
*/
|
||||
void BotChatterInterface::FriendSpottedSniper(void)
|
||||
{
|
||||
m_warnSniperTimer.Start(60.0f);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* Warn of an enemy sniper
|
||||
*/
|
||||
void BotChatterInterface::SpottedSniper(void)
|
||||
{
|
||||
if (!m_warnSniperTimer.IsElapsed())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_me->GetFriendsRemaining() == 0)
|
||||
{
|
||||
// no-one to warn
|
||||
return;
|
||||
}
|
||||
|
||||
BotStatement* say = new BotStatement(this, REPORT_INFORMATION, 10.0f);
|
||||
|
||||
say->AppendPhrase(TheBotPhrases->GetPhrase("SniperWarning"));
|
||||
say->AttachMeme(new BotWarnSniperMeme());
|
||||
|
||||
AddStatement(say);
|
||||
}
|
||||
#endif
|
||||
|
||||
NOXREF void BotChatterInterface::Clear(Place place)
|
||||
{
|
||||
BotStatement *say = new BotStatement(this, REPORT_INFORMATION, 10.0f);
|
||||
|
@ -140,6 +140,14 @@ public:
|
||||
virtual void Interpret(CCSBot *pSender, CCSBot *pReceiver) const; // cause the given bot to act on this meme
|
||||
};
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
class BotWarnSniperMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
virtual void Interpret(CCSBot* sender, CCSBot* receiver) const; ///< cause the given bot to act on this meme
|
||||
};
|
||||
#endif
|
||||
|
||||
enum BotStatementType
|
||||
{
|
||||
REPORT_VISIBLE_ENEMIES,
|
||||
@ -255,6 +263,8 @@ public:
|
||||
Place NameToID(const char *name) const;
|
||||
const char *IDToName(Place id) const;
|
||||
|
||||
bool IsValid() const { return !m_placeList.empty(); }
|
||||
|
||||
// given a name, return the associated phrase collection
|
||||
const BotPhrase *GetPhrase(const char *name) const;
|
||||
|
||||
@ -529,6 +539,10 @@ public:
|
||||
void KilledFriend();
|
||||
void FriendlyFire();
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
void SpottedSniper(void);
|
||||
void FriendSpottedSniper(void);
|
||||
#endif
|
||||
bool SeesAtLeastOneEnemy() const { return m_seeAtLeastOneEnemy; }
|
||||
|
||||
private:
|
||||
@ -555,6 +569,9 @@ private:
|
||||
CountdownTimer m_spottedLooseBombTimer;
|
||||
CountdownTimer m_heardNoiseTimer;
|
||||
CountdownTimer m_escortingHostageTimer;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
CountdownTimer m_warnSniperTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline BotChatterInterface::VerbosityType BotChatterInterface::GetVerbosity() const
|
||||
|
@ -56,6 +56,11 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *pEntity, CBaseEntity *pOt
|
||||
DecreaseMorale();
|
||||
}
|
||||
break;
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
case EVENT_NEW_MATCH:
|
||||
m_morale = POSITIVE; // starting a new round makes everyone a little happy
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!IsAlive())
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
cvar_t cv_bot_enable = { "bot_enable", "0", 0, 0.0f, nullptr };
|
||||
cvar_t cv_bot_traceview = { "bot_traceview", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
cvar_t cv_bot_stop = { "bot_stop", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
cvar_t cv_bot_show_nav = { "bot_show_nav", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
@ -62,6 +63,9 @@ cvar_t cv_bot_deathmatch = { "bot_deathmatch", "0", FCVAR_SERVER, 0.
|
||||
cvar_t cv_bot_quota_mode = { "bot_quota_mode", "normal", FCVAR_SERVER, 0.0f, nullptr };
|
||||
cvar_t cv_bot_join_delay = { "bot_join_delay", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
cvar_t cv_bot_freeze = { "bot_freeze", "0", 0, 0.0f, nullptr };
|
||||
cvar_t cv_bot_mimic = { "bot_mimic", "0", 0, 0.0f, nullptr };
|
||||
cvar_t cv_bot_mimic_yaw_offset = { "bot_mimic_yaw_offset", "0", 0, 0.0f, nullptr };
|
||||
cvar_t cv_bot_excellent_morale = { "bot_excellent_morale", "0", 0, 0.0f, nullptr };
|
||||
#else
|
||||
// Migrated to bot_quota_mode, use "match"
|
||||
cvar_t cv_bot_quota_match = { "bot_quota_match", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
@ -131,6 +135,9 @@ void Bot_RegisterCVars()
|
||||
CVAR_REGISTER(&cv_bot_quota_mode);
|
||||
CVAR_REGISTER(&cv_bot_join_delay);
|
||||
CVAR_REGISTER(&cv_bot_freeze);
|
||||
CVAR_REGISTER(&cv_bot_mimic);
|
||||
CVAR_REGISTER(&cv_bot_mimic_yaw_offset);
|
||||
CVAR_REGISTER(&cv_bot_excellent_morale);
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -189,6 +196,11 @@ void CCSBot::ResetValues()
|
||||
m_currentArea = nullptr;
|
||||
m_lastKnownArea = nullptr;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
m_isEnemySniperVisible = false;
|
||||
m_sawEnemySniperTimer.Invalidate();
|
||||
#endif
|
||||
|
||||
m_avoidFriendTimer.Invalidate();
|
||||
m_isFriendInTheWay = false;
|
||||
m_isWaitingBehindFriend = false;
|
||||
@ -325,10 +337,10 @@ void CCSBot::ResetValues()
|
||||
// NOTE: For some reason, this can be called twice when a bot is added.
|
||||
void CCSBot::SpawnBot()
|
||||
{
|
||||
TheCSBots()->ValidateMapData();
|
||||
TheCSBots()->LoadNavigationMap();
|
||||
ResetValues();
|
||||
|
||||
Q_strcpy(m_name, STRING(pev->netname));
|
||||
Q_strlcpy(m_name, STRING(pev->netname));
|
||||
|
||||
SetState(&m_buyState);
|
||||
SetTouch(&CCSBot::BotTouch);
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
extern cvar_t cv_bot_enable;
|
||||
extern cvar_t cv_bot_traceview;
|
||||
extern cvar_t cv_bot_stop;
|
||||
extern cvar_t cv_bot_show_nav;
|
||||
@ -62,6 +63,9 @@ extern cvar_t cv_bot_deathmatch;
|
||||
extern cvar_t cv_bot_quota_mode;
|
||||
extern cvar_t cv_bot_join_delay;
|
||||
extern cvar_t cv_bot_freeze;
|
||||
extern cvar_t cv_bot_mimic;
|
||||
extern cvar_t cv_bot_mimic_yaw_offset;
|
||||
extern cvar_t cv_bot_excellent_morale;
|
||||
#else
|
||||
extern cvar_t cv_bot_quota_match;
|
||||
#endif
|
||||
|
@ -30,8 +30,7 @@
|
||||
|
||||
const float updateTimesliceDuration = 0.5f;
|
||||
|
||||
int _navAreaCount = 0;
|
||||
int _currentIndex = 0;
|
||||
unsigned int _generationIndex = 0; // used for iterating nav areas during generation process
|
||||
|
||||
inline CNavNode *LadderEndSearch(CBaseEntity *pEntity, const Vector *pos, NavDirType mountDir)
|
||||
{
|
||||
@ -385,11 +384,8 @@ void CCSBot::UpdateLearnProcess()
|
||||
|
||||
void CCSBot::StartAnalyzeAlphaProcess()
|
||||
{
|
||||
m_processMode = PROCESS_ANALYZE_ALPHA;
|
||||
m_analyzeIter = TheNavAreaList.begin();
|
||||
|
||||
_navAreaCount = TheNavAreaList.size();
|
||||
_currentIndex = 0;
|
||||
m_processMode = PROCESS_ANALYZE_ALPHA;
|
||||
_generationIndex = 0;
|
||||
|
||||
ApproachAreaAnalysisPrep();
|
||||
DestroyHidingSpots();
|
||||
@ -400,15 +396,18 @@ void CCSBot::StartAnalyzeAlphaProcess()
|
||||
|
||||
bool CCSBot::AnalyzeAlphaStep()
|
||||
{
|
||||
_currentIndex++;
|
||||
if (m_analyzeIter == TheNavAreaList.end())
|
||||
_generationIndex++;
|
||||
|
||||
if (_generationIndex < 0 || _generationIndex >= TheNavAreaList.size())
|
||||
return false;
|
||||
|
||||
CNavArea *area = (*m_analyzeIter);
|
||||
// TODO: Pretty ugly and very slow way to access element by index
|
||||
// There is no reason not to use a vector instead of a linked list
|
||||
const NavAreaList::const_iterator &iter = std::next(TheNavAreaList.begin(), _generationIndex - 1);
|
||||
|
||||
CNavArea *area = (*iter);
|
||||
area->ComputeHidingSpots();
|
||||
area->ComputeApproachAreas();
|
||||
m_analyzeIter++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -426,29 +425,30 @@ void CCSBot::UpdateAnalyzeAlphaProcess()
|
||||
}
|
||||
}
|
||||
|
||||
float progress = (double(_currentIndex) / double(_navAreaCount)) * 0.5f;
|
||||
float progress = (double(_generationIndex) / double(TheNavAreaList.size())) * 0.5f;
|
||||
drawProgressMeter(progress, "#CZero_AnalyzingHidingSpots");
|
||||
}
|
||||
|
||||
void CCSBot::StartAnalyzeBetaProcess()
|
||||
{
|
||||
m_processMode = PROCESS_ANALYZE_BETA;
|
||||
m_analyzeIter = TheNavAreaList.begin();
|
||||
|
||||
_navAreaCount = TheNavAreaList.size();
|
||||
_currentIndex = 0;
|
||||
m_processMode = PROCESS_ANALYZE_BETA;
|
||||
_generationIndex = 0;
|
||||
}
|
||||
|
||||
bool CCSBot::AnalyzeBetaStep()
|
||||
{
|
||||
_currentIndex++;
|
||||
if (m_analyzeIter == TheNavAreaList.end())
|
||||
_generationIndex++;
|
||||
|
||||
if (_generationIndex < 0 || _generationIndex >= TheNavAreaList.size())
|
||||
return false;
|
||||
|
||||
CNavArea *area = (*m_analyzeIter);
|
||||
// TODO: Pretty ugly and very slow way to access element by index
|
||||
// There is no reason not to use a vector instead of a linked list
|
||||
const NavAreaList::const_iterator &iter = std::next(TheNavAreaList.begin(), _generationIndex - 1);
|
||||
|
||||
CNavArea *area = (*iter);
|
||||
area->ComputeSpotEncounters();
|
||||
area->ComputeSniperSpots();
|
||||
m_analyzeIter++;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -466,7 +466,7 @@ void CCSBot::UpdateAnalyzeBetaProcess()
|
||||
}
|
||||
}
|
||||
|
||||
float progress = (double(_currentIndex) / double(_navAreaCount) + 1.0f) * 0.5f;
|
||||
float progress = (double(_generationIndex) / double(TheNavAreaList.size()) + 1.0f) * 0.5f;
|
||||
drawProgressMeter(progress, "#CZero_AnalyzingApproachPoints");
|
||||
}
|
||||
|
||||
@ -477,31 +477,24 @@ void CCSBot::StartSaveProcess()
|
||||
|
||||
void CCSBot::UpdateSaveProcess()
|
||||
{
|
||||
char filename[256];
|
||||
char msg[256];
|
||||
char cmd[128];
|
||||
char gd[64]{};
|
||||
GET_GAME_DIR(gd);
|
||||
|
||||
GET_GAME_DIR(filename);
|
||||
|
||||
Q_strcat(filename, "\\");
|
||||
Q_strcat(filename, TheBots->GetNavMapFilename());
|
||||
|
||||
HintMessageToAllPlayers("Saving...");
|
||||
char filename[MAX_OSPATH];
|
||||
Q_snprintf(filename, sizeof(filename), "%s\\%s", gd, TheBots->GetNavMapFilename());
|
||||
SaveNavigationMap(filename);
|
||||
|
||||
char msg[256]{};
|
||||
Q_snprintf(msg, sizeof(msg), "Navigation file '%s' saved.", filename);
|
||||
HintMessageToAllPlayers(msg);
|
||||
CONSOLE_ECHO("%s\n", msg);
|
||||
|
||||
hideProgressMeter();
|
||||
StartNormalProcess();
|
||||
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
Q_snprintf(cmd, sizeof(cmd), "map %s\n", STRING(gpGlobals->mapname));
|
||||
#else
|
||||
Q_snprintf(cmd, sizeof(cmd), "changelevel %s\n", STRING(gpGlobals->mapname));
|
||||
#endif
|
||||
|
||||
SERVER_COMMAND(cmd);
|
||||
// tell bot manager that the analysis is completed
|
||||
if (TheCSBots())
|
||||
TheCSBots()->AnalysisCompleted();
|
||||
}
|
||||
|
||||
void CCSBot::StartNormalProcess()
|
||||
|
@ -231,13 +231,12 @@ bool CCSBotManager::IsOnOffense(CBasePlayer *pPlayer) const
|
||||
// Invoked when a map has just been loaded
|
||||
void CCSBotManager::ServerActivate()
|
||||
{
|
||||
DestroyNavigationMap();
|
||||
m_isMapDataLoaded = false;
|
||||
|
||||
m_zoneCount = 0;
|
||||
m_gameScenario = SCENARIO_DEATHMATCH;
|
||||
|
||||
ValidateMapData();
|
||||
LoadNavigationMap();
|
||||
RestartRound();
|
||||
|
||||
m_isLearningMap = false;
|
||||
@ -337,6 +336,10 @@ void CCSBotManager::ClientDisconnect(CBasePlayer *pPlayer)
|
||||
pPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pevTemp);
|
||||
AddEntityHashValue(pPlayer->pev, STRING(pPlayer->pev->classname), CLASSNAME);
|
||||
pPlayer->pev->flags = FL_DORMANT;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
pPlayer->has_disconnected = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrintAllEntities()
|
||||
@ -396,22 +399,24 @@ void CCSBotManager::ServerCommand(const char *pcmd)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
const char *name = STRING(pPlayer->pev->netname);
|
||||
if (FStrEq(name, ""))
|
||||
continue;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (pPlayer->pev->deadflag != DEAD_NO)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (pPlayer->IsBot())
|
||||
{
|
||||
CCSBot *pBot = static_cast<CCSBot *>(pPlayer);
|
||||
if (killThemAll || FStrEq(name, msg))
|
||||
{
|
||||
pPlayer->Kill();
|
||||
}
|
||||
pBot->Kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -423,13 +428,17 @@ void CCSBotManager::ServerCommand(const char *pcmd)
|
||||
else
|
||||
kickThemAll = false;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
bool fillMode = FStrEq(cv_bot_quota_mode.string, "fill");
|
||||
#else
|
||||
bool fillMode = false;
|
||||
#endif
|
||||
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
const char *name = STRING(pPlayer->pev->netname);
|
||||
@ -444,7 +453,11 @@ void CCSBotManager::ServerCommand(const char *pcmd)
|
||||
// adjust bot quota so kicked bot is not immediately added back in
|
||||
int newQuota = cv_bot_quota.value - 1;
|
||||
SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", name));
|
||||
CVAR_SET_FLOAT("bot_quota", clamp(newQuota, 0, int(cv_bot_quota.value)));
|
||||
|
||||
if (kickThemAll || !fillMode)
|
||||
{
|
||||
CVAR_SET_FLOAT("bot_quota", clamp(newQuota, 0, int(cv_bot_quota.value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -564,18 +577,21 @@ void CCSBotManager::ServerCommand(const char *pcmd)
|
||||
}
|
||||
else if (FStrEq(pcmd, "bot_nav_save"))
|
||||
{
|
||||
GET_GAME_DIR(buffer);
|
||||
Q_strcat(buffer, "\\");
|
||||
Q_strcat(buffer, CBotManager::GetNavMapFilename());
|
||||
char gd[64]{};
|
||||
GET_GAME_DIR(gd);
|
||||
|
||||
if (SaveNavigationMap(buffer))
|
||||
CONSOLE_ECHO("Navigation map '%s' saved.\n", buffer);
|
||||
char filename[MAX_OSPATH];
|
||||
Q_snprintf(filename, sizeof(filename), "%s\\%s", gd, CBotManager::GetNavMapFilename());
|
||||
|
||||
if (SaveNavigationMap(filename))
|
||||
CONSOLE_ECHO("Navigation map '%s' saved.\n", filename);
|
||||
else
|
||||
CONSOLE_ECHO("ERROR: Cannot save navigation map '%s'.\n", buffer);
|
||||
CONSOLE_ECHO("ERROR: Cannot save navigation map '%s'.\n", filename);
|
||||
}
|
||||
else if (FStrEq(pcmd, "bot_nav_load"))
|
||||
{
|
||||
ValidateMapData();
|
||||
m_isMapDataLoaded = false; // force nav reload
|
||||
LoadNavigationMap();
|
||||
}
|
||||
else if (FStrEq(pcmd, "bot_nav_use_place"))
|
||||
{
|
||||
@ -630,11 +646,15 @@ void CCSBotManager::ServerCommand(const char *pcmd)
|
||||
{
|
||||
CONSOLE_ECHO("Ambiguous\n");
|
||||
}
|
||||
else
|
||||
else if (found)
|
||||
{
|
||||
CONSOLE_ECHO("Current place set to '%s'\n", found->GetName());
|
||||
SetNavPlace(found->GetID());
|
||||
}
|
||||
else
|
||||
{
|
||||
CONSOLE_ECHO("Error - place name '%s' no exists in phrases BotChatter.db\n", msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (FStrEq(pcmd, "bot_nav_toggle_place_mode"))
|
||||
@ -662,6 +682,9 @@ void CCSBotManager::ServerCommand(const char *pcmd)
|
||||
CBaseEntity *pEntity = nullptr;
|
||||
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
|
||||
{
|
||||
if (FNullEnt(pEntity->edict()))
|
||||
break;
|
||||
|
||||
if (!pEntity->IsPlayer())
|
||||
continue;
|
||||
|
||||
@ -742,6 +765,23 @@ void CCSBotManager::ServerCommand(const char *pcmd)
|
||||
|
||||
BOOL CCSBotManager::ClientCommand(CBasePlayer *pPlayer, const char *pcmd)
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (pPlayer->IsBot())
|
||||
return FALSE;
|
||||
|
||||
if (cv_bot_mimic.value == pPlayer->entindex())
|
||||
{
|
||||
// Bots mimic our client commands
|
||||
ForEachPlayer([pPlayer, pcmd](CBasePlayer *bot)
|
||||
{
|
||||
if (pPlayer != bot && bot->IsBot())
|
||||
bot->ClientCommand(pcmd, CMD_ARGV_(1));
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -784,7 +824,8 @@ bool CCSBotManager::BotAddCommand(BotProfileTeamType team, bool isFromConsole)
|
||||
// decrease the bot quota
|
||||
if (!isFromConsole)
|
||||
{
|
||||
CVAR_SET_FLOAT("bot_quota", cv_bot_quota.value - 1);
|
||||
int newQuota = cv_bot_quota.value - 1;
|
||||
CVAR_SET_FLOAT("bot_quota", clamp(newQuota, 0, (int)cv_bot_quota.value));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -818,7 +859,8 @@ bool CCSBotManager::BotAddCommand(BotProfileTeamType team, bool isFromConsole)
|
||||
if (isFromConsole)
|
||||
{
|
||||
// increase the bot quota to account for manually added bot
|
||||
CVAR_SET_FLOAT("bot_quota", cv_bot_quota.value + 1);
|
||||
int newQuota = cv_bot_quota.value + 1;
|
||||
CVAR_SET_FLOAT("bot_quota", clamp(newQuota, 0, gpGlobals->maxClients));
|
||||
}
|
||||
}
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
@ -827,7 +869,8 @@ bool CCSBotManager::BotAddCommand(BotProfileTeamType team, bool isFromConsole)
|
||||
// decrease the bot quota
|
||||
if (!isFromConsole)
|
||||
{
|
||||
CVAR_SET_FLOAT("bot_quota", cv_bot_quota.value - 1);
|
||||
int newQuota = cv_bot_quota.value - 1;
|
||||
CVAR_SET_FLOAT("bot_quota", clamp(newQuota, 0, (int)cv_bot_quota.value));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -846,21 +889,26 @@ void CCSBotManager::MaintainBotQuota()
|
||||
if (m_isLearningMap)
|
||||
return;
|
||||
|
||||
int totalHumansInGame = UTIL_HumansInGame();
|
||||
int humanPlayersInGame = UTIL_HumansInGame(IGNORE_SPECTATORS);
|
||||
int spectatorPlayersInGame = UTIL_SpectatorsInGame();
|
||||
int humanPlayersInGame = UTIL_HumansInGame();
|
||||
|
||||
// don't add bots until local player has been registered, to make sure he's player ID #1
|
||||
if (!IS_DEDICATED_SERVER() && totalHumansInGame == 0)
|
||||
if (!IS_DEDICATED_SERVER() && humanPlayersInGame == 0)
|
||||
return;
|
||||
|
||||
int desiredBotCount = int(cv_bot_quota.value);
|
||||
int occupiedBotSlots = UTIL_BotsInGame();
|
||||
|
||||
bool isRoundInDeathmatch = false;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (round_infinite.value > 0)
|
||||
isRoundInDeathmatch = true; // is no round end gameplay
|
||||
#endif
|
||||
|
||||
// isRoundInProgress is true if the round has progressed far enough that new players will join as dead.
|
||||
bool isRoundInProgress = CSGameRules()->IsGameStarted() &&
|
||||
!TheCSBots()->IsRoundOver() &&
|
||||
(CSGameRules()->GetRoundElapsedTime() >= CSGameRules()->GetRoundRespawnTime());
|
||||
(CSGameRules()->GetRoundRespawnTime() != -1 && CSGameRules()->GetRoundElapsedTime() >= CSGameRules()->GetRoundRespawnTime()) && !isRoundInDeathmatch;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (FStrEq(cv_bot_quota_mode.string, "fill"))
|
||||
@ -869,7 +917,7 @@ void CCSBotManager::MaintainBotQuota()
|
||||
// unless the round is already in progress, in which case we play with what we've been dealt
|
||||
if (!isRoundInProgress)
|
||||
{
|
||||
desiredBotCount = Q_max(0, desiredBotCount - humanPlayersInGame + spectatorPlayersInGame);
|
||||
desiredBotCount = Q_max(0, desiredBotCount - humanPlayersInGame);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -899,7 +947,7 @@ void CCSBotManager::MaintainBotQuota()
|
||||
// wait for a player to join, if necessary
|
||||
if (cv_bot_join_after_player.value > 0.0)
|
||||
{
|
||||
if (humanPlayersInGame == 0 && spectatorPlayersInGame == 0)
|
||||
if (humanPlayersInGame == 0)
|
||||
desiredBotCount = 0;
|
||||
}
|
||||
|
||||
@ -916,13 +964,15 @@ void CCSBotManager::MaintainBotQuota()
|
||||
if (cv_bot_auto_vacate.value > 0.0)
|
||||
desiredBotCount = Q_min(desiredBotCount, gpGlobals->maxClients - (humanPlayersInGame + 1));
|
||||
else
|
||||
desiredBotCount = Q_min(desiredBotCount, gpGlobals->maxClients - humanPlayersInGame + spectatorPlayersInGame);
|
||||
desiredBotCount = Q_min(desiredBotCount, gpGlobals->maxClients - humanPlayersInGame);
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
// Try to balance teams, if we are in the first specified seconds of a round and bots can join either team.
|
||||
if (occupiedBotSlots > 0 && desiredBotCount == occupiedBotSlots && CSGameRules()->IsGameStarted())
|
||||
if (occupiedBotSlots > 0 && desiredBotCount == occupiedBotSlots && (CSGameRules()->IsGameStarted() || isRoundInDeathmatch))
|
||||
{
|
||||
if (CSGameRules()->GetRoundElapsedTime() < CSGameRules()->GetRoundRespawnTime()) // new bots can still spawn during this time
|
||||
if (isRoundInDeathmatch ||
|
||||
(CSGameRules()->GetRoundRespawnTime() == -1 || // means no time limit
|
||||
CSGameRules()->GetRoundElapsedTime() < CSGameRules()->GetRoundRespawnTime())) // new bots can still spawn during this time
|
||||
{
|
||||
if (autoteambalance.value > 0.0f)
|
||||
{
|
||||
@ -1039,7 +1089,8 @@ void CCSBotManager::MaintainBotQuota()
|
||||
UTIL_KickBotFromTeam(TERRORIST);
|
||||
}
|
||||
|
||||
CVAR_SET_FLOAT("bot_quota", cv_bot_quota.value - 1.0f);
|
||||
int newQuota = cv_bot_quota.value - 1;
|
||||
CVAR_SET_FLOAT("bot_quota", clamp(newQuota, 0, (int)cv_bot_quota.value));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1093,22 +1144,232 @@ private:
|
||||
CCSBotManager::Zone *m_zone;
|
||||
};
|
||||
|
||||
// Search the map entities to determine the game scenario and define important zones.
|
||||
void CCSBotManager::ValidateMapData()
|
||||
LINK_ENTITY_TO_CLASS(info_spawn_point, CPointEntity, CCSPointEntity)
|
||||
|
||||
inline bool IsFreeSpace(Vector vecOrigin, int iHullNumber, edict_t *pSkipEnt = nullptr)
|
||||
{
|
||||
if (UTIL_PointContents(vecOrigin) != CONTENTS_EMPTY)
|
||||
return false;
|
||||
|
||||
TraceResult trace;
|
||||
UTIL_TraceHull(vecOrigin, vecOrigin, dont_ignore_monsters, iHullNumber, pSkipEnt, &trace);
|
||||
|
||||
return (!trace.fStartSolid && !trace.fAllSolid && trace.fInOpen);
|
||||
}
|
||||
|
||||
inline bool pointInRadius(Vector vecOrigin, float radius)
|
||||
{
|
||||
CBaseEntity *pEntity = nullptr;
|
||||
while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecOrigin, radius)))
|
||||
{
|
||||
if (!UTIL_IsValidEntity(pEntity->edict()))
|
||||
continue; // ignore the entity marked for deletion
|
||||
|
||||
if (FClassnameIs(pEntity->edict(), "info_spawn_point"))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// a simple algorithm that searches for the farthest point (so that the player does not look at the wall)
|
||||
inline bool GetIdealLookYawForSpawnPoint(const Vector &vecStart, float &flIdealLookYaw)
|
||||
{
|
||||
const float ANGLE_STEP = 30.0f;
|
||||
float bestDistance = 0.0f;
|
||||
|
||||
for (float angleYaw = 0.0f; angleYaw <= 360.0f; angleYaw += ANGLE_STEP)
|
||||
{
|
||||
TraceResult tr;
|
||||
UTIL_MakeVectors(Vector(0, angleYaw, 0));
|
||||
|
||||
Vector vecEnd(vecStart + gpGlobals->v_forward * 8192);
|
||||
UTIL_TraceLine(vecStart, vecEnd, ignore_monsters, nullptr, &tr);
|
||||
|
||||
float distance = (vecStart - tr.vecEndPos).Length();
|
||||
if (distance > bestDistance)
|
||||
{
|
||||
bestDistance = distance;
|
||||
flIdealLookYaw = angleYaw;
|
||||
}
|
||||
}
|
||||
|
||||
return bestDistance > 0.0f;
|
||||
}
|
||||
|
||||
// this function from leaked csgo sources 2020y
|
||||
inline bool IsValidArea(CNavArea *area)
|
||||
{
|
||||
ShortestPathCost cost;
|
||||
bool bNotOrphaned;
|
||||
|
||||
// check that we can path from the nav area to a ct spawner to confirm it isn't orphaned.
|
||||
CBaseEntity *CTSpawn = UTIL_FindEntityByClassname(nullptr, "info_player_start");
|
||||
|
||||
if (CTSpawn)
|
||||
{
|
||||
CNavArea *CTSpawnArea = TheNavAreaGrid.GetNearestNavArea(&CTSpawn->pev->origin);
|
||||
bNotOrphaned = NavAreaBuildPath(area, CTSpawnArea, nullptr, cost);
|
||||
|
||||
if (bNotOrphaned)
|
||||
return true;
|
||||
}
|
||||
|
||||
// double check that we can path from the nav area to a t spawner to confirm it isn't orphaned.
|
||||
CBaseEntity *TSpawn = UTIL_FindEntityByClassname(nullptr, "info_player_deathmatch");
|
||||
|
||||
if (TSpawn)
|
||||
{
|
||||
CNavArea *TSpawnArea = TheNavAreaGrid.GetNearestNavArea(&TSpawn->pev->origin);
|
||||
bNotOrphaned = NavAreaBuildPath(area, TSpawnArea, nullptr, cost);
|
||||
|
||||
if (bNotOrphaned)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
|
||||
// Generates spawn points (info_spawn_point entities) for players and bots based on the navigation map data
|
||||
// It uses the navigation areas to find valid spots for spawn points considering factors like area size, slope,
|
||||
// available free space, and distance from other spawn points.
|
||||
void GenerateSpawnPointsFromNavData()
|
||||
{
|
||||
// Remove any existing spawn points
|
||||
UTIL_RemoveOther("info_spawn_point");
|
||||
|
||||
const int MAX_SPAWNS_POINTS = 128; // Max allowed spawn points
|
||||
|
||||
const float MAX_SLOPE = 0.85f; // Maximum slope allowed for a spawn point
|
||||
const float MIN_AREA_SIZE = 32.0f; // Minimum area size for a valid spawn point
|
||||
const float MIN_NEARBY_SPAWNPOINT = 128.0f; // Minimum distance between spawn point
|
||||
|
||||
// Total number of spawn points generated
|
||||
int totalSpawns = 0;
|
||||
|
||||
for (CNavArea *area : TheNavAreaList)
|
||||
{
|
||||
if (totalSpawns >= MAX_SPAWNS_POINTS)
|
||||
break;
|
||||
|
||||
if (!area)
|
||||
continue;
|
||||
|
||||
// Skip areas that are too small
|
||||
if (area->GetSizeX() < MIN_AREA_SIZE || area->GetSizeY() < MIN_AREA_SIZE)
|
||||
continue;
|
||||
|
||||
// Skip areas with unwanted attributes (jump, crouch, etc.)
|
||||
if (area->GetAttributes() != 0)
|
||||
continue;
|
||||
|
||||
// Skip areas with steep slopes
|
||||
if (area->GetAreaSlope() < MAX_SLOPE)
|
||||
{
|
||||
//CONSOLE_ECHO("Skip area slope: %0.3f\n", area->GetAreaSlope());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate the spawn point position above the area center
|
||||
Vector vecOrigin = *area->GetCenter() + Vector(0, 0, HalfHumanHeight + 5);
|
||||
|
||||
// Ensure there is free space at the calculated position
|
||||
if (!IsFreeSpace(vecOrigin, human_hull))
|
||||
{
|
||||
//CONSOLE_ECHO("No free space!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pointInRadius(vecOrigin, MIN_NEARBY_SPAWNPOINT))
|
||||
continue; // spawn point is too close to others
|
||||
|
||||
if (!IsValidArea(area))
|
||||
continue;
|
||||
|
||||
// Calculate ideal spawn point yaw angle
|
||||
float flIdealSpawnPointYaw = 0.0f;
|
||||
if (GetIdealLookYawForSpawnPoint(vecOrigin, flIdealSpawnPointYaw))
|
||||
{
|
||||
CBaseEntity *pPoint = CBaseEntity::Create("info_spawn_point", vecOrigin, Vector(0, flIdealSpawnPointYaw, 0), nullptr);
|
||||
if (pPoint)
|
||||
{
|
||||
totalSpawns++;
|
||||
//CONSOLE_ECHO("Add spawn at x:%f y:%f z:%f with angle %0.1f slope %0.3f \n", vecOrigin.x, vecOrigin.y, vecOrigin.z, bestAngle.y, area->GetAreaSlope());
|
||||
|
||||
// use only for debugging
|
||||
if (randomspawn.value > 1.0f)
|
||||
{
|
||||
SET_MODEL(ENT(pPoint->pev), "models/player.mdl");
|
||||
pPoint->pev->sequence = ACT_IDLE;
|
||||
pPoint->pev->rendermode = kRenderTransAdd;
|
||||
pPoint->pev->renderamt = 150.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CONSOLE_ECHO("Total spawns points: %i\n", totalSpawns);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Load the map's navigation data
|
||||
bool CCSBotManager::LoadNavigationMap()
|
||||
{
|
||||
// check if the map data is already loaded or if bots are not allowed
|
||||
if (m_isMapDataLoaded || !AreBotsAllowed())
|
||||
return;
|
||||
return false;
|
||||
|
||||
m_isMapDataLoaded = true;
|
||||
|
||||
if (LoadNavigationMap())
|
||||
// Clear navigation map data from previous map
|
||||
DestroyNavigationMap();
|
||||
|
||||
// Try to load the map's navigation file
|
||||
NavErrorType navStatus = ::LoadNavigationMap();
|
||||
if (navStatus != NAV_OK)
|
||||
{
|
||||
CONSOLE_ECHO("Failed to load navigation map.\n");
|
||||
return;
|
||||
CONSOLE_ECHO("ERROR: Failed to load 'maps/%s.nav' file navigation map!\n", STRING(gpGlobals->mapname));
|
||||
|
||||
switch (navStatus)
|
||||
{
|
||||
case NAV_CANT_ACCESS_FILE:
|
||||
CONSOLE_ECHO("\tNavigation file not found or access denied.\n");
|
||||
break;
|
||||
case NAV_INVALID_FILE:
|
||||
CONSOLE_ECHO("\tInvalid navigation file format.\n");
|
||||
break;
|
||||
case NAV_BAD_FILE_VERSION:
|
||||
CONSOLE_ECHO("\tBad navigation file version.\n");
|
||||
break;
|
||||
case NAV_CORRUPT_DATA:
|
||||
CONSOLE_ECHO("\tCorrupted navigation data detected.\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (navStatus != NAV_CANT_ACCESS_FILE)
|
||||
CONSOLE_ECHO("\tTry regenerating it using the command: bot_nav_analyze\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CONSOLE_ECHO("Navigation map loaded.\n");
|
||||
// Determine the scenario for the current map (e.g., bomb defuse, hostage rescue etc)
|
||||
DetermineMapScenario();
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
GenerateSpawnPointsFromNavData();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Search the map entities to determine the game scenario and define important zones.
|
||||
void CCSBotManager::DetermineMapScenario()
|
||||
{
|
||||
m_zoneCount = 0;
|
||||
m_gameScenario = SCENARIO_DEATHMATCH;
|
||||
|
||||
@ -1160,6 +1421,13 @@ void CCSBotManager::ValidateMapData()
|
||||
found = true;
|
||||
isLegacy = false;
|
||||
}
|
||||
else if (FClassnameIs(pEntity->pev, "func_escapezone"))
|
||||
{
|
||||
m_gameScenario = SCENARIO_ESCAPE;
|
||||
found = true;
|
||||
isLegacy = false;
|
||||
}
|
||||
|
||||
|
||||
if (found)
|
||||
{
|
||||
@ -1241,6 +1509,59 @@ void CCSBotManager::ValidateMapData()
|
||||
}
|
||||
}
|
||||
|
||||
// Tell all bots that the given nav data no longer exists
|
||||
// This function is called when a part of the map or the nav data is destroyed
|
||||
void CCSBotManager::OnDestroyNavDataNotify(NavNotifyDestroyType navNotifyType, void *dead)
|
||||
{
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (!pPlayer->IsBot())
|
||||
continue;
|
||||
|
||||
// Notify the bot about the destroyed nav data
|
||||
CCSBot *pBot = static_cast<CCSBot *>(pPlayer);
|
||||
pBot->OnDestroyNavDataNotify(navNotifyType, dead);
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the map analysis process has completed
|
||||
// This function makes sure all bots are removed from the map analysis process
|
||||
// and are reset to normal bot behavior. It also reloads the navigation map
|
||||
// and triggers a game restart after the analysis is completed
|
||||
void CCSBotManager::AnalysisCompleted()
|
||||
{
|
||||
// Ensure that all bots are no longer involved in map analysis and start their normal process
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (!pPlayer->IsBot())
|
||||
continue;
|
||||
|
||||
CCSBot *pBot = static_cast<CCSBot *>(pPlayer);
|
||||
pBot->StartNormalProcess();
|
||||
}
|
||||
|
||||
m_isLearningMap = false;
|
||||
m_isMapDataLoaded = false;
|
||||
m_isAnalysisRequested = false;
|
||||
|
||||
// Try to reload the navigation map from the file
|
||||
if (LoadNavigationMap())
|
||||
{
|
||||
// Initiate a game restart in 3 seconds
|
||||
CVAR_SET_FLOAT("sv_restart", 3);
|
||||
}
|
||||
}
|
||||
|
||||
bool CCSBotManager::AddBot(const BotProfile *profile, BotProfileTeamType team)
|
||||
{
|
||||
if (!AreBotsAllowed())
|
||||
@ -1448,6 +1769,7 @@ void CCSBotManager::SetLooseBomb(CBaseEntity *bomb)
|
||||
if (bomb)
|
||||
{
|
||||
m_looseBombArea = TheNavAreaGrid.GetNearestNavArea(&bomb->pev->origin);
|
||||
DbgAssert(!TheNavAreaGrid.IsValid() || m_looseBombArea); // TODO: Need investigation and find out why it cannot find nearest area for a lost bomb, just catch it
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1576,7 +1898,8 @@ void CCSBotManager::OnFreeEntPrivateData(CBaseEntity *pEntity)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (!pPlayer || pPlayer->IsDormant())
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (pPlayer->IsBot())
|
||||
|
@ -56,13 +56,16 @@ public:
|
||||
virtual bool IsImportantPlayer(CBasePlayer *pPlayer) const; // return true if pPlayer is important to scenario (VIP, bomb carrier, etc)
|
||||
|
||||
public:
|
||||
void ValidateMapData();
|
||||
bool LoadNavigationMap();
|
||||
void DetermineMapScenario();
|
||||
void OnFreeEntPrivateData(CBaseEntity *pEntity);
|
||||
void OnDestroyNavDataNotify(NavNotifyDestroyType navNotifyType, void *dead);
|
||||
bool IsLearningMap() const { return m_isLearningMap; }
|
||||
void SetLearningMapFlag() { m_isLearningMap = true; }
|
||||
bool IsAnalysisRequested() const { return m_isAnalysisRequested; }
|
||||
void RequestAnalysis() { m_isAnalysisRequested = true; }
|
||||
void AckAnalysisRequest() { m_isAnalysisRequested = false; }
|
||||
void AnalysisCompleted();
|
||||
|
||||
// difficulty levels
|
||||
static BotDifficultyType GetDifficultyLevel()
|
||||
@ -85,7 +88,8 @@ public:
|
||||
SCENARIO_DEATHMATCH,
|
||||
SCENARIO_DEFUSE_BOMB,
|
||||
SCENARIO_RESCUE_HOSTAGES,
|
||||
SCENARIO_ESCORT_VIP
|
||||
SCENARIO_ESCORT_VIP,
|
||||
SCENARIO_ESCAPE
|
||||
};
|
||||
|
||||
GameScenarioType GetScenario() const
|
||||
@ -268,3 +272,4 @@ inline bool AreBotsAllowed()
|
||||
}
|
||||
|
||||
void PrintAllEntities();
|
||||
void GenerateSpawnPointsFromNavData();
|
||||
|
@ -1118,10 +1118,7 @@ bool CCSBot::IsFriendInTheWay(const Vector *goalPos) const
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (!pPlayer->IsAlive())
|
||||
@ -1294,7 +1291,7 @@ CCSBot::PathResult CCSBot::UpdatePathMovement(bool allowSpeedChange)
|
||||
if (IsOnLadder())
|
||||
Jump(MUST_JUMP);
|
||||
|
||||
assert(m_pathIndex < m_pathLength);
|
||||
Assert(m_pathIndex < m_pathLength);
|
||||
|
||||
// Check if reached the end of the path
|
||||
bool nearEndOfPath = false;
|
||||
|
@ -299,6 +299,12 @@ void CCSBot::Attack(CBasePlayer *victim)
|
||||
if (cv_bot_zombie.value != 0.0f)
|
||||
return;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// If mimicing the player, don't attack state
|
||||
if (cv_bot_mimic.value)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// cannot attack if we are reloading
|
||||
if (IsActiveWeaponReloading())
|
||||
return;
|
||||
|
@ -255,7 +255,7 @@ void CCSBot::Update()
|
||||
Vector dir = m_spotEncounter->path.to - m_spotEncounter->path.from;
|
||||
float length = dir.NormalizeInPlace();
|
||||
|
||||
for (auto &order : m_spotEncounter->spotList) {
|
||||
for (auto& order : m_spotEncounter->spotList) {
|
||||
UTIL_DrawBeamPoints(m_spotEncounter->path.from + order.t * length * dir, *order.spot->GetPosition(), 3, 0, 255, 255);
|
||||
}
|
||||
}
|
||||
@ -339,7 +339,7 @@ void CCSBot::Update()
|
||||
UpdateReactionQueue();
|
||||
|
||||
// "threat" may be the same as our current enemy
|
||||
CBasePlayer *threat = GetRecognizedEnemy();
|
||||
CBasePlayer* threat = GetRecognizedEnemy();
|
||||
if (threat)
|
||||
{
|
||||
// adjust our personal "safe" time
|
||||
@ -437,7 +437,6 @@ void CCSBot::Update()
|
||||
}
|
||||
else
|
||||
{
|
||||
const int dada = offsetof(CCSBot, m_visibleEnemyParts);
|
||||
// check LOS to current enemy (chest & head), in case he's dead (GetNearestEnemy() only returns live players)
|
||||
// note we're not checking FOV - once we've acquired an enemy (which does check FOV), assume we know roughly where he is
|
||||
if (IsVisible(m_enemy, false, &m_visibleEnemyParts))
|
||||
@ -593,6 +592,10 @@ void CCSBot::Update()
|
||||
SecondaryAttack();
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (!IsBlind())
|
||||
{
|
||||
#endif
|
||||
// check encounter spots
|
||||
UpdatePeripheralVision();
|
||||
|
||||
@ -602,11 +605,24 @@ void CCSBot::Update()
|
||||
GetChatter()->SpottedBomber(GetBomber());
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// watch for snipers
|
||||
if (CanSeeSniper() && !HasSeenSniperRecently())
|
||||
{
|
||||
GetChatter()->SpottedSniper();
|
||||
|
||||
const float sniperRecentInterval = 20.0f;
|
||||
m_sawEnemySniperTimer.Start(sniperRecentInterval);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CanSeeLooseBomb())
|
||||
{
|
||||
GetChatter()->SpottedLooseBomb(TheCSBots()->GetLooseBomb());
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
}
|
||||
#endif
|
||||
// Scenario interrupts
|
||||
switch (TheCSBots()->GetScenario())
|
||||
{
|
||||
|
@ -61,6 +61,12 @@ void CCSBot::UpdateLookAngles()
|
||||
float stiffness;
|
||||
float damping;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// If mimicing the player, don't modify the view angles
|
||||
if (cv_bot_mimic.value > 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// springs are stiffer when attacking, so we can track and move between targets better
|
||||
if (IsAttacking())
|
||||
{
|
||||
@ -253,7 +259,7 @@ bool CCSBot::IsVisible(CBasePlayer *pPlayer, bool testFOV, unsigned char *visPar
|
||||
if ((pPlayer->pev->flags & FL_NOTARGET) || (pPlayer->pev->effects & EF_NODRAW))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
|
||||
Vector spot = pPlayer->pev->origin;
|
||||
unsigned char testVisParts = NONE;
|
||||
|
||||
@ -691,6 +697,13 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
|
||||
m_closestVisibleFriend = nullptr;
|
||||
m_closestVisibleHumanFriend = nullptr;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
m_isEnemySniperVisible = false;
|
||||
CBasePlayer* sniperThreat = NULL;
|
||||
float sniperThreatRange = 99999999999.9f;
|
||||
bool sniperThreatIsFacingMe = false;
|
||||
#endif
|
||||
|
||||
float closeFriendRange = 99999999999.9f;
|
||||
float closeHumanFriendRange = 99999999999.9f;
|
||||
|
||||
@ -701,10 +714,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
// is it a player?
|
||||
@ -786,6 +796,53 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
|
||||
Vector d = pev->origin - pPlayer->pev->origin;
|
||||
float distSq = d.LengthSquared();
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
CBasePlayerWeapon *pCurrentWeapon = static_cast<CBasePlayerWeapon *>(pPlayer->m_pActiveItem);
|
||||
if (pCurrentWeapon && isSniperRifle(pCurrentWeapon))
|
||||
{
|
||||
m_isEnemySniperVisible = true;
|
||||
if (sniperThreat)
|
||||
{
|
||||
if (IsPlayerLookingAtMe(pPlayer))
|
||||
{
|
||||
if (sniperThreatIsFacingMe)
|
||||
{
|
||||
// several snipers are facing us - keep closest
|
||||
if (distSq < sniperThreatRange)
|
||||
{
|
||||
sniperThreat = pPlayer;
|
||||
sniperThreatRange = distSq;
|
||||
sniperThreatIsFacingMe = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// even if this sniper is farther away, keep it because he's aiming at us
|
||||
sniperThreat = pPlayer;
|
||||
sniperThreatRange = distSq;
|
||||
sniperThreatIsFacingMe = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this sniper is not looking at us, only consider it if we dont have a sniper facing us
|
||||
if (!sniperThreatIsFacingMe && distSq < sniperThreatRange)
|
||||
{
|
||||
sniperThreat = pPlayer;
|
||||
sniperThreatRange = distSq;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// first sniper we see
|
||||
sniperThreat = pPlayer;
|
||||
sniperThreatRange = distSq;
|
||||
sniperThreatIsFacingMe = IsPlayerLookingAtMe(pPlayer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// maintain set of visible threats, sorted by increasing distance
|
||||
if (threatCount == 0)
|
||||
{
|
||||
@ -947,6 +1004,23 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
|
||||
{
|
||||
return currentThreat;
|
||||
}
|
||||
|
||||
// if we are a sniper and we see a sniper threat, attack it unless
|
||||
// there are other close enemies facing me
|
||||
if (IsSniper() && sniperThreat)
|
||||
{
|
||||
const float closeCombatRange = 500.0f;
|
||||
|
||||
for (t = 0; t < threatCount; ++t)
|
||||
{
|
||||
if (threat[t].range < closeCombatRange && IsPlayerLookingAtMe(threat[t].enemy))
|
||||
{
|
||||
return threat[t].enemy;
|
||||
}
|
||||
}
|
||||
|
||||
return sniperThreat;
|
||||
}
|
||||
#endif
|
||||
|
||||
// otherwise, find the closest threat that without using shield
|
||||
|
@ -462,17 +462,26 @@ void BuyState::OnUpdate(CCSBot *me)
|
||||
me->ClientCommand("vesthelm");
|
||||
me->ClientCommand("vest");
|
||||
|
||||
// pistols - if we have no preferred pistol, buy at random
|
||||
if (TheCSBots()->AllowPistols() && !me->GetProfile()->HasPistolPreference())
|
||||
if (TheCSBots()->AllowPistols()
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
&& !me->GetProfile()->HasPistolPreference()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (m_buyPistol)
|
||||
{
|
||||
int which = RANDOM_LONG(0, MAX_BUY_WEAPON_SECONDARY - 1);
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
// pistols - if we have no preferred pistol, buy at random
|
||||
if (!me->GetProfile()->HasPistolPreference())
|
||||
#endif
|
||||
{
|
||||
int which = RANDOM_LONG(0, MAX_BUY_WEAPON_SECONDARY - 1);
|
||||
|
||||
if (me->m_iTeam == TERRORIST)
|
||||
me->ClientCommand(secondaryWeaponBuyInfoT[which].buyAlias);
|
||||
else
|
||||
me->ClientCommand(secondaryWeaponBuyInfoCT[which].buyAlias);
|
||||
if (me->m_iTeam == TERRORIST)
|
||||
me->ClientCommand(secondaryWeaponBuyInfoT[which].buyAlias);
|
||||
else
|
||||
me->ClientCommand(secondaryWeaponBuyInfoCT[which].buyAlias);
|
||||
}
|
||||
|
||||
// only buy one pistol
|
||||
m_buyPistol = false;
|
||||
|
@ -95,10 +95,15 @@ void HuntState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
if (!me->IsRogue() && me->CanSeeLooseBomb())
|
||||
{
|
||||
CNavArea *looseBombArea = TheCSBots()->GetLooseBombArea();
|
||||
|
||||
// if we are near the loose bomb and can see it, hide nearby and guard it
|
||||
me->SetTask(CCSBot::GUARD_LOOSE_BOMB);
|
||||
me->Hide(TheCSBots()->GetLooseBombArea());
|
||||
me->GetChatter()->AnnouncePlan("GoingToGuardLooseBomb", TheCSBots()->GetLooseBombArea()->GetPlace());
|
||||
me->Hide(looseBombArea);
|
||||
|
||||
if (looseBombArea)
|
||||
me->GetChatter()->AnnouncePlan("GoingToGuardLooseBomb", looseBombArea->GetPlace());
|
||||
|
||||
return;
|
||||
}
|
||||
else if (TheCSBots()->IsBombPlanted())
|
||||
|
@ -353,7 +353,7 @@ void IdleState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
}
|
||||
|
||||
assert((0, "A CT bot doesn't know what to do while the bomb is planted!\n"));
|
||||
DbgAssert(!"A CT bot doesn't know what to do while the bomb is planted!\n");
|
||||
}
|
||||
|
||||
// if we have a sniper rifle, we like to camp, whether rogue or not
|
||||
@ -773,6 +773,93 @@ void IdleState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CCSBotManager::SCENARIO_ESCAPE:
|
||||
{
|
||||
if (me->m_iTeam == TERRORIST)
|
||||
{
|
||||
// if early in round, pick a random zone, otherwise pick closest zone
|
||||
const float earlyTime = 20.0f;
|
||||
const CCSBotManager::Zone *zone = nullptr;
|
||||
|
||||
if (TheCSBots()->GetElapsedRoundTime() < earlyTime)
|
||||
{
|
||||
// pick random zone
|
||||
zone = TheCSBots()->GetRandomZone();
|
||||
}
|
||||
else
|
||||
{
|
||||
// pick closest zone
|
||||
zone = TheCSBots()->GetClosestZone(me->GetLastKnownArea(), PathCost(me));
|
||||
}
|
||||
|
||||
if (zone)
|
||||
{
|
||||
// pick a random spot within the escape zone
|
||||
const Vector *pos = TheCSBots()->GetRandomPositionInZone(zone);
|
||||
if (pos)
|
||||
{
|
||||
// move to escape zone
|
||||
// me->SetTask(CCSBot::VIP_ESCAPE);
|
||||
me->Run();
|
||||
me->MoveTo(pos);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// CT
|
||||
else
|
||||
{
|
||||
if (me->IsSniper())
|
||||
{
|
||||
if (RANDOM_FLOAT(0, 100) <= defenseSniperCampChance)
|
||||
{
|
||||
// snipe escape zone(s)
|
||||
const CCSBotManager::Zone *zone = TheCSBots()->GetRandomZone();
|
||||
if (zone)
|
||||
{
|
||||
CNavArea *area = TheCSBots()->GetRandomAreaInZone(zone);
|
||||
if (area)
|
||||
{
|
||||
me->SetTask(CCSBot::MOVE_TO_SNIPER_SPOT);
|
||||
me->Hide(area, -1.0, sniperHideRange);
|
||||
me->SetDisposition(CCSBot::OPPORTUNITY_FIRE);
|
||||
me->PrintIfWatched("Sniping near escape zone\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rogues just hunt, unless they want to snipe
|
||||
// if the whole team has decided to rush, hunt
|
||||
if (me->IsRogue() || TheCSBots()->IsDefenseRushing())
|
||||
break;
|
||||
|
||||
// the lower our morale gets, the more we want to camp the escape zone(s)
|
||||
float guardEscapeZoneChance = -34.0f * me->GetMorale();
|
||||
|
||||
if (RANDOM_FLOAT(0.0f, 100.0f) < guardEscapeZoneChance)
|
||||
{
|
||||
// guard escape zone(s)
|
||||
const CCSBotManager::Zone *zone = TheCSBots()->GetRandomZone();
|
||||
if (zone)
|
||||
{
|
||||
CNavArea *area = TheCSBots()->GetRandomAreaInZone(zone);
|
||||
if (area)
|
||||
{
|
||||
// guard the escape zone - stay closer if our morale is low
|
||||
//me->SetTask(CCSBot::GUARD_VIP_ESCAPE_ZONE);
|
||||
me->PrintIfWatched("I'm guarding an escape zone\n");
|
||||
|
||||
float escapeGuardRange = 750.0f + 250.0f * (me->GetMorale() + 3);
|
||||
me->Hide(area, -1.0, escapeGuardRange);
|
||||
me->SetDisposition(CCSBot::OPPORTUNITY_FIRE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// deathmatch
|
||||
default:
|
||||
{
|
||||
|
@ -1,5 +1,12 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#if !defined(DOOR_ASSERT)
|
||||
#undef DbgAssert
|
||||
#undef DbgAssertMsg
|
||||
#define DbgAssert(_exp) ((void)0)
|
||||
#define DbgAssertMsg(_exp, _msg) ((void)0)
|
||||
#endif
|
||||
|
||||
TYPEDESCRIPTION CEnvGlobal::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD(CEnvGlobal, m_globalstate, FIELD_STRING),
|
||||
@ -671,7 +678,7 @@ void CBaseButton::ButtonActivate()
|
||||
PlayLockSounds(pev, &m_ls, FALSE, TRUE);
|
||||
}
|
||||
|
||||
assert(m_toggle_state == TS_AT_BOTTOM);
|
||||
DbgAssert(m_toggle_state == TS_AT_BOTTOM);
|
||||
m_toggle_state = TS_GOING_UP;
|
||||
|
||||
SetMoveDone(&CBaseButton::TriggerAndWait);
|
||||
@ -688,7 +695,7 @@ void CBaseButton::ButtonActivate()
|
||||
// Button has reached the "in/up" position. Activate its "targets", and pause before "popping out".
|
||||
void CBaseButton::TriggerAndWait()
|
||||
{
|
||||
assert(m_toggle_state == TS_GOING_UP);
|
||||
DbgAssert(m_toggle_state == TS_GOING_UP);
|
||||
|
||||
if (!UTIL_IsMasterTriggered(m_sMaster, m_hActivator))
|
||||
return;
|
||||
@ -724,7 +731,7 @@ void CBaseButton::TriggerAndWait()
|
||||
// Starts the button moving "out/down".
|
||||
void CBaseButton::ButtonReturn()
|
||||
{
|
||||
//assert(m_toggle_state == TS_AT_TOP);
|
||||
DbgAssert(m_toggle_state == TS_AT_TOP);
|
||||
m_toggle_state = TS_GOING_DOWN;
|
||||
|
||||
SetMoveDone(&CBaseButton::ButtonBackHome);
|
||||
@ -763,7 +770,7 @@ void CBaseButton::Restart()
|
||||
// Button has returned to start state. Quiesce it.
|
||||
void CBaseButton::ButtonBackHome()
|
||||
{
|
||||
assert(m_toggle_state == TS_GOING_DOWN);
|
||||
DbgAssert(m_toggle_state == TS_GOING_DOWN);
|
||||
m_toggle_state = TS_AT_BOTTOM;
|
||||
|
||||
if (pev->spawnflags & SF_BUTTON_TOGGLE
|
||||
@ -776,7 +783,11 @@ void CBaseButton::ButtonBackHome()
|
||||
SUB_UseTargets(m_hActivator, USE_TOGGLE, 0);
|
||||
}
|
||||
|
||||
if (!FStringNull(pev->target))
|
||||
if (!FStringNull(pev->target)
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
&& m_hActivator
|
||||
#endif
|
||||
)
|
||||
{
|
||||
edict_t *pentTarget = nullptr;
|
||||
while ((pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target))))
|
||||
@ -880,7 +891,7 @@ void CRotButton::Spawn()
|
||||
m_vecAngle1 = pev->angles;
|
||||
m_vecAngle2 = pev->angles + pev->movedir * m_flMoveDistance;
|
||||
|
||||
assert(("rotating button start/end positions are equal", m_vecAngle1 != m_vecAngle2));
|
||||
DbgAssertMsg(m_vecAngle1 != m_vecAngle2, "rotating button start/end positions are equal");
|
||||
|
||||
m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE);
|
||||
m_fRotating = TRUE;
|
||||
|
@ -260,7 +260,7 @@ void CCareerTask::OnEvent(GameEventType event, CBasePlayer *pVictim, CBasePlayer
|
||||
|
||||
while ((pHostage = UTIL_FindEntityByClassname(pHostage, "hostage_entity")))
|
||||
{
|
||||
if (pHostage && pHostage->IsDead())
|
||||
if (pHostage->IsDead())
|
||||
hostagesCount++;
|
||||
}
|
||||
|
||||
@ -389,7 +389,6 @@ void CCareerTaskManager::Reset(bool deleteTasks)
|
||||
delete task;
|
||||
|
||||
m_tasks.clear();
|
||||
m_nextId = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -397,6 +396,7 @@ void CCareerTaskManager::Reset(bool deleteTasks)
|
||||
task->Reset();
|
||||
}
|
||||
|
||||
m_nextId = 0;
|
||||
m_finishedTaskTime = 0;
|
||||
m_finishedTaskRound = 0;
|
||||
m_shouldLatchRoundEndMessage = false;
|
||||
@ -545,7 +545,11 @@ void CCareerTaskManager::HandleDeath(int team, CBasePlayer *pAttacker)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (pPlayer && pPlayer->m_iTeam == enemyTeam && pPlayer->IsAlive())
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (pPlayer->m_iTeam == enemyTeam && pPlayer->IsAlive())
|
||||
numEnemies++;
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,10 @@ NEW_DLL_FUNCTIONS gNewDLLFunctions =
|
||||
nullptr
|
||||
};
|
||||
|
||||
#ifndef REGAMEDLL_API
|
||||
entvars_t *g_pevLastInflictor = nullptr;
|
||||
#endif
|
||||
|
||||
CMemoryPool hashItemMemPool(sizeof(hash_item_t), 64);
|
||||
|
||||
int CaseInsensitiveHash(const char *string, int iBounds)
|
||||
@ -697,7 +701,11 @@ BOOL CBaseEntity::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, fl
|
||||
pev->health -= flDamage;
|
||||
if (pev->health <= 0)
|
||||
{
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
KilledInflicted(pevInflictor, pevAttacker, GIB_NORMAL);
|
||||
#else
|
||||
Killed(pevAttacker, GIB_NORMAL);
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -866,6 +874,17 @@ BOOL CBaseEntity::IsInWorld()
|
||||
}
|
||||
|
||||
// speed
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
float maxvel = g_psv_maxvelocity->value;
|
||||
if (pev->velocity.x > maxvel || pev->velocity.y > maxvel || pev->velocity.z > maxvel)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (pev->velocity.x < -maxvel || pev->velocity.y < -maxvel || pev->velocity.z < -maxvel)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if (pev->velocity.x >= 2000.0 || pev->velocity.y >= 2000.0 || pev->velocity.z >= 2000.0)
|
||||
{
|
||||
return FALSE;
|
||||
@ -874,6 +893,7 @@ BOOL CBaseEntity::IsInWorld()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1242,7 +1262,7 @@ bool EXT_FUNC IsPenetrableEntity_default(Vector &vecSrc, Vector &vecEnd, entvars
|
||||
|
||||
|
||||
LINK_HOOK_CLASS_CHAIN(VectorRef, CBaseEntity, FireBullets3, (VectorRef vecSrc, VectorRef vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand), vecSrc, vecDirShooting, vecSpread, flDistance, iPenetration, iBulletType, iDamage, flRangeModifier, pevAttacker, bPistol, shared_rand)
|
||||
|
||||
|
||||
// Go to the trouble of combining multiple pellets into a single damage call.
|
||||
// This version is used by Players, uses the random seed generator to sync client and server side shots.
|
||||
VectorRef CBaseEntity::__API_HOOK(FireBullets3)(VectorRef vecSrc, VectorRef vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand)
|
||||
@ -1340,6 +1360,7 @@ VectorRef CBaseEntity::__API_HOOK(FireBullets3)(VectorRef vecSrc, VectorRef vecD
|
||||
|
||||
float flDamageModifier = 0.5;
|
||||
|
||||
int iStartPenetration = iPenetration;
|
||||
while (iPenetration != 0)
|
||||
{
|
||||
ClearMultiDamage();
|
||||
@ -1400,9 +1421,11 @@ VectorRef CBaseEntity::__API_HOOK(FireBullets3)(VectorRef vecSrc, VectorRef vecD
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (tr.flFraction != 1.0f)
|
||||
{
|
||||
CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
|
||||
int iPenetrationCur = iPenetration;
|
||||
iPenetration--;
|
||||
|
||||
flCurrentDistance = tr.flFraction * flDistance;
|
||||
@ -1426,7 +1449,11 @@ VectorRef CBaseEntity::__API_HOOK(FireBullets3)(VectorRef vecSrc, VectorRef vecD
|
||||
pEntity->pev->punchangle.x = iCurrentDamage * RANDOM_FLOAT(-0.15, 0.15);
|
||||
pEntity->pev->punchangle.z = iCurrentDamage * RANDOM_FLOAT(-0.15, 0.15);
|
||||
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
if (pEntity->pev->punchangle.x < 4)
|
||||
#else
|
||||
if (pEntity->pev->punchangle.x < -4)
|
||||
#endif
|
||||
{
|
||||
pEntity->pev->punchangle.x = -4;
|
||||
}
|
||||
@ -1459,6 +1486,7 @@ VectorRef CBaseEntity::__API_HOOK(FireBullets3)(VectorRef vecSrc, VectorRef vecD
|
||||
flDistance = (flDistance - flCurrentDistance) * flDistanceModifier;
|
||||
vecEnd = vecSrc + (vecDir * flDistance);
|
||||
|
||||
pEntity->SetDmgPenetrationLevel(iStartPenetration - iPenetrationCur);
|
||||
pEntity->TraceAttack(pevAttacker, iCurrentDamage, vecDir, &tr, (DMG_BULLET | DMG_NEVERGIB));
|
||||
iCurrentDamage *= flDamageModifier;
|
||||
}
|
||||
@ -1570,6 +1598,30 @@ void OnFreeEntPrivateData(edict_t *pEnt)
|
||||
if (!pEntity)
|
||||
return;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
// FIXED: Ensure this item will be removed from the owner player's inventory 'm_rgpPlayerItems[]'
|
||||
// to avoid dangling pointers
|
||||
CBasePlayerItem *pItem = dynamic_cast<CBasePlayerItem *>(pEntity);
|
||||
if (pItem)
|
||||
{
|
||||
CBasePlayer *pOwner = GET_PRIVATE<CBasePlayer>(pItem->pev->owner);
|
||||
if (pOwner && pOwner->IsPlayer())
|
||||
{
|
||||
if (pOwner->m_pActiveItem == pItem && pItem->IsWeapon())
|
||||
((CBasePlayerWeapon *)pItem)->RetireWeapon();
|
||||
|
||||
if (pOwner->RemovePlayerItem(pItem))
|
||||
{
|
||||
// Ammo must be dropped, otherwise grenades cannot be buy or picked up
|
||||
if (IsGrenadeWeapon(pItem->m_iId) || pItem->m_iId == WEAPON_C4)
|
||||
pOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()] = 0;
|
||||
|
||||
pOwner->pev->weapons &= ~(1 << pItem->m_iId);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REGAMEDLL_API
|
||||
pEntity->OnDestroy();
|
||||
#endif
|
||||
|
@ -242,8 +242,16 @@ public:
|
||||
void SetBlocked(void (T::*pfn)(CBaseEntity *pOther));
|
||||
void SetBlocked(std::nullptr_t);
|
||||
|
||||
void SetDmgPenetrationLevel(int iPenetrationLevel);
|
||||
void ResetDmgPenetrationLevel();
|
||||
int GetDmgPenetrationLevel() const;
|
||||
|
||||
void KilledInflicted(entvars_t *pevInflictor, entvars_t *pevAttacker, int iGib);
|
||||
entvars_t *GetLastInflictor();
|
||||
|
||||
#ifdef REGAMEDLL_API
|
||||
CCSEntity *m_pEntity;
|
||||
CCSEntity *CSEntity() const;
|
||||
#else
|
||||
// We use this variables to store each ammo count.
|
||||
// let's sacrifice this unused member, for its own needs in favor of m_pEntity
|
||||
@ -328,6 +336,26 @@ inline void CBaseEntity::SetBlocked(std::nullptr_t)
|
||||
m_pfnBlocked = nullptr;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_API
|
||||
inline CCSEntity *CBaseEntity::CSEntity() const
|
||||
{
|
||||
return m_pEntity;
|
||||
}
|
||||
#else // !REGAMEDLL_API
|
||||
|
||||
extern entvars_t *g_pevLastInflictor;
|
||||
inline void CBaseEntity::SetDmgPenetrationLevel(int iPenetrationLevel) {}
|
||||
inline void CBaseEntity::ResetDmgPenetrationLevel() {}
|
||||
inline int CBaseEntity::GetDmgPenetrationLevel() const { return 0; }
|
||||
inline entvars_t *CBaseEntity::GetLastInflictor() { return g_pevLastInflictor; }
|
||||
inline void CBaseEntity::KilledInflicted(entvars_t *pevInflictor, entvars_t *pevAttacker, int iGib)
|
||||
{
|
||||
g_pevLastInflictor = pevInflictor;
|
||||
Killed(pevAttacker, iGib);
|
||||
g_pevLastInflictor = nullptr;
|
||||
}
|
||||
#endif // !REGAMEDLL_API
|
||||
|
||||
class CPointEntity: public CBaseEntity {
|
||||
public:
|
||||
virtual void Spawn();
|
||||
@ -369,6 +397,7 @@ public:
|
||||
float SetBoneController(int iController, float flValue = 0.0f);
|
||||
void InitBoneControllers();
|
||||
|
||||
float GetSequenceDuration() const;
|
||||
float SetBlending(int iBlender, float flValue);
|
||||
void GetBonePosition(int iBone, Vector &origin, Vector &angles);
|
||||
void GetAutomovement(Vector &origin, Vector &angles, float flInterval = 0.1f);
|
||||
|
@ -74,6 +74,7 @@ const int DEFAULT_FOV = 90; // the default field of view
|
||||
#define PLAYER_PREVENT_DUCK BIT(4)
|
||||
#define PLAYER_PREVENT_CLIMB BIT(5) // The player can't climb ladder
|
||||
#define PLAYER_PREVENT_JUMP BIT(6)
|
||||
#define PLAYER_PREVENT_DDUCK BIT(7)
|
||||
|
||||
#define MENU_KEY_1 BIT(0)
|
||||
#define MENU_KEY_2 BIT(1)
|
||||
|
@ -133,6 +133,7 @@ static entity_field_alias_t custom_entity_field_alias[] =
|
||||
{ "animtime", 0 },
|
||||
};
|
||||
|
||||
edict_t *g_pEdicts = nullptr;
|
||||
bool g_bServerActive = false;
|
||||
bool g_bItemCreatedByBuying = false;
|
||||
PLAYERPVSSTATUS g_PVSStatus[MAX_CLIENTS];
|
||||
@ -249,7 +250,7 @@ void WriteSigonMessages()
|
||||
|
||||
#ifdef PLAY_GAMEDLL
|
||||
// TODO: fix test demo
|
||||
iFlags &= ~ITEM_FLAG_NOFIREUNDERWATER;
|
||||
iFlags &= ~ITEM_FLAG_CUSTOM;
|
||||
#endif
|
||||
|
||||
MESSAGE_BEGIN(MSG_INIT, gmsgWeaponList);
|
||||
@ -438,6 +439,9 @@ NOXREF int CountTeams()
|
||||
if (FNullEnt(pEntity->edict()))
|
||||
break;
|
||||
|
||||
if (pEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
CBasePlayer *pPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev);
|
||||
|
||||
if (pPlayer->m_iTeam == UNASSIGNED)
|
||||
@ -461,7 +465,7 @@ NOXREF int CountTeams()
|
||||
|
||||
void ListPlayers(CBasePlayer *current)
|
||||
{
|
||||
char message[120] = "", cNumber[12];
|
||||
char message[120]{};
|
||||
|
||||
CBaseEntity *pEntity = nullptr;
|
||||
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
|
||||
@ -475,12 +479,7 @@ void ListPlayers(CBasePlayer *current)
|
||||
CBasePlayer *pPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev);
|
||||
int iUserID = GETPLAYERUSERID(ENT(pPlayer->pev));
|
||||
|
||||
Q_sprintf(cNumber, "%d", iUserID);
|
||||
Q_strcpy(message, "\n");
|
||||
Q_strcat(message, cNumber);
|
||||
Q_strcat(message, " : ");
|
||||
Q_strcat(message, STRING(pPlayer->pev->netname));
|
||||
|
||||
Q_snprintf(message, sizeof(message), "\n%d : %s", iUserID, STRING(pPlayer->pev->netname));
|
||||
ClientPrint(current->pev, HUD_PRINTCONSOLE, message);
|
||||
}
|
||||
|
||||
@ -499,7 +498,8 @@ int CountTeamPlayers(int iTeam)
|
||||
if (pEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
if (GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev)->m_iTeam == iTeam)
|
||||
CBasePlayer *pPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev);
|
||||
if (pPlayer->m_iTeam == iTeam)
|
||||
{
|
||||
nCount++;
|
||||
}
|
||||
@ -534,6 +534,9 @@ void ProcessKickVote(CBasePlayer *pVotingPlayer, CBasePlayer *pKickPlayer)
|
||||
if (FNullEnt(pTempEntity->edict()))
|
||||
break;
|
||||
|
||||
if (pTempEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
pTempPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pTempEntity->pev);
|
||||
|
||||
if (!pTempPlayer || pTempPlayer->m_iTeam == UNASSIGNED)
|
||||
@ -571,6 +574,9 @@ void ProcessKickVote(CBasePlayer *pVotingPlayer, CBasePlayer *pKickPlayer)
|
||||
if (FNullEnt(pTempEntity->edict()))
|
||||
break;
|
||||
|
||||
if (pTempEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
pTempPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pTempEntity->pev);
|
||||
|
||||
if (!pTempPlayer || pTempPlayer->m_iTeam == UNASSIGNED)
|
||||
@ -621,6 +627,9 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
pPlayer->m_bHasDefuser = false;
|
||||
#endif
|
||||
pPlayer->m_bNotKilled = true;
|
||||
pPlayer->m_iIgnoreGlobalChat = IGNOREMSG_NONE;
|
||||
pPlayer->m_iTeamKills = 0;
|
||||
@ -670,10 +679,12 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
|
||||
CBaseEntity *pTarget = nullptr;
|
||||
pPlayer->m_pIntroCamera = UTIL_FindEntityByClassname(nullptr, "trigger_camera");
|
||||
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
if (g_pGameRules && g_pGameRules->IsMultiplayer())
|
||||
{
|
||||
CSGameRules()->m_bMapHasCameras = (pPlayer->m_pIntroCamera != nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pPlayer->m_pIntroCamera)
|
||||
{
|
||||
@ -691,7 +702,12 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
|
||||
pPlayer->pev->angles = CamAngles;
|
||||
pPlayer->pev->v_angle = pPlayer->pev->angles;
|
||||
|
||||
pPlayer->m_fIntroCamTime = gpGlobals->time + 6;
|
||||
pPlayer->m_fIntroCamTime =
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
(CSGameRules()->m_bMapHasCameras <= 1) ? 0.0 : // no need to refresh cameras if map has only one
|
||||
#endif
|
||||
gpGlobals->time + 6;
|
||||
|
||||
pPlayer->pev->view_ofs = g_vecZero;
|
||||
}
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
@ -717,8 +733,8 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
|
||||
|
||||
pPlayer->m_iJoiningState = SHOWLTEXT;
|
||||
|
||||
static char sName[128];
|
||||
Q_strcpy(sName, STRING(pPlayer->pev->netname));
|
||||
char sName[128];
|
||||
Q_strlcpy(sName, STRING(pPlayer->pev->netname));
|
||||
|
||||
for (char *pApersand = sName; pApersand && *pApersand != '\0'; pApersand++)
|
||||
{
|
||||
@ -727,7 +743,7 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_API
|
||||
pPlayer->CSPlayer()->ResetVars();
|
||||
pPlayer->CSPlayer()->OnConnect();
|
||||
#endif
|
||||
|
||||
UTIL_ClientPrintAll(HUD_PRINTNOTIFY, "#Game_connected", (sName[0] != '\0') ? sName : "<unconnected>");
|
||||
@ -776,12 +792,12 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
{
|
||||
if (CMD_ARGC_() >= 2)
|
||||
{
|
||||
Q_sprintf(szTemp, "%s %s", pcmd, CMD_ARGS());
|
||||
Q_snprintf(szTemp, sizeof(szTemp), "%s %s", pcmd, CMD_ARGS());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just a one word command, use the first word...sigh
|
||||
Q_sprintf(szTemp, "%s", pcmd);
|
||||
Q_snprintf(szTemp, sizeof(szTemp), "%s", pcmd);
|
||||
}
|
||||
|
||||
p = szTemp;
|
||||
@ -795,7 +811,9 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
if (*p == '"')
|
||||
{
|
||||
p++;
|
||||
p[Q_strlen(p) - 1] = '\0';
|
||||
size_t len = Q_strlen(p);
|
||||
if (len > 0)
|
||||
p[len - 1] = '\0';
|
||||
}
|
||||
|
||||
// Check if buffer contains an invalid unicode sequence
|
||||
@ -819,14 +837,24 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
return;
|
||||
|
||||
const char *placeName = nullptr;
|
||||
char *pszFormat = nullptr;
|
||||
const char *pszFormat = nullptr;
|
||||
char *pszConsoleFormat = nullptr;
|
||||
bool consoleUsesPlaceName = false;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// there's no team on FFA mode
|
||||
if (teamonly && CSGameRules()->IsFreeForAll() && (pPlayer->m_iTeam == CT || pPlayer->m_iTeam == TERRORIST))
|
||||
teamonly = FALSE;
|
||||
#endif
|
||||
|
||||
// team only
|
||||
if (teamonly)
|
||||
{
|
||||
if (AreRunningCZero() && (pPlayer->m_iTeam == CT || pPlayer->m_iTeam == TERRORIST))
|
||||
if ((
|
||||
#ifdef REGAMEDLL_ADD
|
||||
location_area_info.value >= 2 ||
|
||||
#endif
|
||||
AreRunningCZero()) && (pPlayer->m_iTeam == CT || pPlayer->m_iTeam == TERRORIST))
|
||||
{
|
||||
// search the place name where is located the player
|
||||
Place playerPlace = TheNavAreaGrid.GetPlace(&pPlayer->pev->origin);
|
||||
@ -840,8 +868,17 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!placeName)
|
||||
placeName = TheNavAreaGrid.IDToName(playerPlace);
|
||||
}
|
||||
|
||||
bool bUseLocFallback = false;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (chat_loc_fallback.value)
|
||||
bUseLocFallback = true;
|
||||
#endif
|
||||
|
||||
if (pPlayer->m_iTeam == CT)
|
||||
{
|
||||
if (bSenderDead)
|
||||
@ -851,7 +888,7 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
}
|
||||
else if (placeName)
|
||||
{
|
||||
pszFormat = "#Cstrike_Chat_CT_Loc";
|
||||
pszFormat = bUseLocFallback ? "\x1(Counter-Terrorist) \x3%s1\x1 @ \x4%s3\x1 : %s2" : "#Cstrike_Chat_CT_Loc";
|
||||
pszConsoleFormat = "*(Counter-Terrorist) %s @ %s : %s";
|
||||
consoleUsesPlaceName = true;
|
||||
}
|
||||
@ -870,7 +907,7 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
}
|
||||
else if (placeName)
|
||||
{
|
||||
pszFormat = "#Cstrike_Chat_T_Loc";
|
||||
pszFormat = bUseLocFallback ? "\x1(Terrorist) \x3%s1\x1 @ \x4%s3\x1 : %s2" : "#Cstrike_Chat_T_Loc";
|
||||
pszConsoleFormat = "(Terrorist) %s @ %s : %s";
|
||||
consoleUsesPlaceName = true;
|
||||
}
|
||||
@ -933,8 +970,8 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
}
|
||||
}
|
||||
|
||||
Q_strcat(text, p);
|
||||
Q_strcat(text, "\n");
|
||||
Q_strlcat(text, p);
|
||||
Q_strlcat(text, "\n");
|
||||
|
||||
// loop through all players
|
||||
// Start with the first player.
|
||||
@ -953,6 +990,9 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
if (pReceiver->edict() == pEntity)
|
||||
continue;
|
||||
|
||||
if (pReceiver->IsDormant())
|
||||
continue;
|
||||
|
||||
// Not a client ? (should never be true)
|
||||
if (!pReceiver->IsNetClient())
|
||||
continue;
|
||||
@ -961,7 +1001,13 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
if (gpGlobals->deathmatch != 0.0f && CSGameRules()->m_VoiceGameMgr.PlayerHasBlockedPlayer(pReceiver, pPlayer))
|
||||
continue;
|
||||
|
||||
if (teamonly && pReceiver->m_iTeam != pPlayer->m_iTeam)
|
||||
if (teamonly
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
&& CSGameRules()->PlayerRelationship(pPlayer, pReceiver) != GR_TEAMMATE
|
||||
#else
|
||||
&& pReceiver->m_iTeam != pPlayer->m_iTeam
|
||||
#endif
|
||||
)
|
||||
continue;
|
||||
|
||||
if (
|
||||
@ -974,7 +1020,13 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((pReceiver->m_iIgnoreGlobalChat == IGNOREMSG_ENEMY && pReceiver->m_iTeam == pPlayer->m_iTeam)
|
||||
if ((pReceiver->m_iIgnoreGlobalChat == IGNOREMSG_ENEMY
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
&& CSGameRules()->PlayerRelationship(pPlayer, pReceiver) == GR_TEAMMATE
|
||||
#else
|
||||
&& pReceiver->m_iTeam == pPlayer->m_iTeam
|
||||
#endif
|
||||
)
|
||||
|| pReceiver->m_iIgnoreGlobalChat == IGNOREMSG_NONE)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgSayText, nullptr, pReceiver->pev);
|
||||
@ -1194,7 +1246,9 @@ void BuyMachineGun(CBasePlayer *pPlayer, int iSlot)
|
||||
BuyWeaponByWeaponID(pPlayer, WEAPON_M249);
|
||||
}
|
||||
|
||||
void BuyItem(CBasePlayer *pPlayer, int iSlot)
|
||||
LINK_HOOK_VOID_CHAIN(BuyItem, (CBasePlayer *pPlayer, int iSlot), pPlayer, iSlot)
|
||||
|
||||
void EXT_FUNC __API_HOOK(BuyItem)(CBasePlayer *pPlayer, int iSlot)
|
||||
{
|
||||
int iItemPrice = 0;
|
||||
const char *pszItem = nullptr;
|
||||
@ -1435,28 +1489,13 @@ void BuyItem(CBasePlayer *pPlayer, int iSlot)
|
||||
if (pPlayer->m_iAccount >= DEFUSEKIT_PRICE)
|
||||
{
|
||||
bEnoughMoney = true;
|
||||
pPlayer->m_bHasDefuser = true;
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pPlayer->pev);
|
||||
WRITE_BYTE(STATUSICON_SHOW);
|
||||
WRITE_STRING("defuser");
|
||||
WRITE_BYTE(0);
|
||||
WRITE_BYTE(160);
|
||||
WRITE_BYTE(0);
|
||||
MESSAGE_END();
|
||||
|
||||
pPlayer->pev->body = 1;
|
||||
pPlayer->GiveDefuser();
|
||||
pPlayer->AddAccount(-DEFUSEKIT_PRICE, RT_PLAYER_BOUGHT_SOMETHING);
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
EMIT_SOUND(ENT(pPlayer->pev), CHAN_VOICE, "items/kevlar.wav", VOL_NORM, ATTN_NORM);
|
||||
#else
|
||||
EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/kevlar.wav", VOL_NORM, ATTN_NORM);
|
||||
#endif
|
||||
pPlayer->SendItemStatus();
|
||||
|
||||
#ifdef BUILD_LATEST
|
||||
pPlayer->SetScoreboardAttributes();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@ -1474,7 +1513,6 @@ void BuyItem(CBasePlayer *pPlayer, int iSlot)
|
||||
if (pPlayer->m_iAccount >= SHIELDGUN_PRICE)
|
||||
{
|
||||
bEnoughMoney = true;
|
||||
|
||||
pPlayer->DropPrimary();
|
||||
pPlayer->GiveShield();
|
||||
pPlayer->AddAccount(-SHIELDGUN_PRICE, RT_PLAYER_BOUGHT_SOMETHING);
|
||||
@ -1911,7 +1949,7 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *pPlayer, int slot)
|
||||
MESSAGE_END();
|
||||
#endif
|
||||
// do we have fadetoblack on? (need to fade their screen back in)
|
||||
if (fadetoblack.value)
|
||||
if (fadetoblack.value == FADETOBLACK_STAY)
|
||||
{
|
||||
UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 0.001, 0, 0, FFADE_IN);
|
||||
}
|
||||
@ -2262,7 +2300,7 @@ bool EXT_FUNC __API_HOOK(BuyGunAmmo)(CBasePlayer *pPlayer, CBasePlayerItem *weap
|
||||
if (pPlayer->m_iAccount >= info->clipCost)
|
||||
{
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (pPlayer->GiveAmmo(info->buyClipSize, info->ammoName2, weapon->iMaxAmmo1()) == -1)
|
||||
if (pPlayer->GiveAmmo(info->buyClipSize, weapon->pszAmmo1(), weapon->iMaxAmmo1()) == -1)
|
||||
return false;
|
||||
|
||||
EMIT_SOUND(ENT(weapon->pev), CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM);
|
||||
@ -2334,6 +2372,9 @@ CBaseEntity *EntityFromUserID(int userID)
|
||||
if (FNullEnt(pTempEntity->edict()))
|
||||
break;
|
||||
|
||||
if (pTempEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
CBasePlayer *pTempPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pTempEntity->pev);
|
||||
|
||||
if (pTempPlayer->m_iTeam != UNASSIGNED && userID == GETPLAYERUSERID(pTempEntity->edict()))
|
||||
@ -2354,6 +2395,9 @@ NOXREF int CountPlayersInServer()
|
||||
if (FNullEnt(pTempEntity->edict()))
|
||||
break;
|
||||
|
||||
if (pTempEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
CBasePlayer *pTempPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pTempEntity->pev);
|
||||
|
||||
if (pTempPlayer->m_iTeam != UNASSIGNED)
|
||||
@ -2599,6 +2643,15 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
static const int flagKick = UTIL_ReadFlags("k");
|
||||
if ((flagKick & UTIL_ReadFlags(vote_flags.string)) == 0)
|
||||
{
|
||||
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Command_Not_Available");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
pPlayer->m_flNextVoteTime = gpGlobals->time + 3;
|
||||
|
||||
if (pPlayer->m_iTeam != UNASSIGNED)
|
||||
@ -2680,11 +2733,20 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
static const int flagMap = UTIL_ReadFlags("m");
|
||||
if ((flagMap & UTIL_ReadFlags(vote_flags.string)) == 0)
|
||||
{
|
||||
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Command_Not_Available");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
pPlayer->m_flNextVoteTime = gpGlobals->time + 3;
|
||||
|
||||
if (pPlayer->m_iTeam != UNASSIGNED)
|
||||
{
|
||||
if (gpGlobals->time < 180)
|
||||
if (gpGlobals->time < CGameRules::GetVotemapMinElapsedTime())
|
||||
{
|
||||
ClientPrint(pPlayer->pev, HUD_PRINTCONSOLE, "#Cannot_Vote_Map");
|
||||
return;
|
||||
@ -3253,6 +3315,26 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// Request from client for the given version of player movement control, if any
|
||||
else if (FStrEq(pcmd, "cl_pmove_version"))
|
||||
{
|
||||
// cl_pmove_version <num>
|
||||
if (CMD_ARGC_() < 2)
|
||||
return; // invalid
|
||||
|
||||
PlayerMovementVersion &playerMovementVersion = pPlayer->CSPlayer()->m_MovementVersion;
|
||||
playerMovementVersion.Set(parg1);
|
||||
|
||||
// If the client's requested movement version is newer, enforce it to the available one
|
||||
if (playerMovementVersion.IsGreaterThan(PM_VERSION))
|
||||
{
|
||||
playerMovementVersion.Set(PM_VERSION); // reset to available version
|
||||
CLIENT_COMMAND(pEntity, "cl_pmove_version %s\n", playerMovementVersion.ToString());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
if (g_pGameRules->ClientCommand_DeadOrAlive(GetClassPtr<CCSPlayer>((CBasePlayer *)pev), pcmd))
|
||||
@ -3334,7 +3416,11 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pObserver = UTIL_PlayerByIndex(i);
|
||||
if (pObserver && pObserver->IsObservingPlayer(pPlayer))
|
||||
|
||||
if (!UTIL_IsValidPlayer(pObserver))
|
||||
continue;
|
||||
|
||||
if (pObserver->IsObservingPlayer(pPlayer))
|
||||
{
|
||||
EMIT_SOUND(ENT(pObserver->pev), CHAN_ITEM, "items/nvg_off.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
|
||||
|
||||
@ -3359,7 +3445,11 @@ void EXT_FUNC InternalCommand(edict_t *pEntity, const char *pcmd, const char *pa
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pObserver = UTIL_PlayerByIndex(i);
|
||||
if (pObserver && pObserver->IsObservingPlayer(pPlayer))
|
||||
|
||||
if (!UTIL_IsValidPlayer(pObserver))
|
||||
continue;
|
||||
|
||||
if (pObserver->IsObservingPlayer(pPlayer))
|
||||
{
|
||||
EMIT_SOUND(ENT(pObserver->pev), CHAN_ITEM, "items/nvg_on.wav", RANDOM_FLOAT(0.92, 1), ATTN_NORM);
|
||||
|
||||
@ -3673,6 +3763,22 @@ void EXT_FUNC ServerDeactivate()
|
||||
|
||||
void EXT_FUNC ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
|
||||
{
|
||||
g_pEdicts = pEdictList;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
//
|
||||
// Tells clients which version of player movement (pmove) the server is using
|
||||
//
|
||||
// In GoldSrc, both the server and clients handle player movement using shared code.
|
||||
// If the server changes how movement works, due to improvements or bugfixes, it can mess up
|
||||
// the client's movement prediction, causing desync. To avoid this, the server can tell clients what
|
||||
// version of the movement code it's using. Clients that don't recognize or respond to this version
|
||||
// will be treated as using the previous behavior, and the server will handle them accordingly.
|
||||
// Clients that do recognize it will let the server know, so everything stays in sync.
|
||||
//
|
||||
SET_KEY_VALUE(GET_INFO_BUFFER(pEdictList), "pmove", PM_ServerVersion());
|
||||
#endif
|
||||
|
||||
int i;
|
||||
CBaseEntity *pClass;
|
||||
|
||||
@ -4207,7 +4313,7 @@ void ClientPrecache()
|
||||
PRECACHE_GENERIC("sprites/scope_arc_ne.tga");
|
||||
PRECACHE_GENERIC("sprites/scope_arc_sw.tga");
|
||||
|
||||
m_usResetDecals = g_engfuncs.pfnPrecacheEvent(1, "events/decal_reset.sc");
|
||||
m_usResetDecals = PRECACHE_EVENT(1, "events/decal_reset.sc");
|
||||
}
|
||||
|
||||
const char *EXT_FUNC GetGameDescription()
|
||||
@ -4483,7 +4589,7 @@ BOOL EXT_FUNC AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, e
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// don't send unhandled custom bits to client
|
||||
state->effects &= ~(EF_FORCEVISIBILITY | EF_OWNER_VISIBILITY | EF_OWNER_NO_VISIBILITY);
|
||||
state->effects &= ~EF_CUSTOM_BITS;
|
||||
|
||||
if (ent->v.skin == CONTENTS_LADDER &&
|
||||
(host->v.iuser3 & PLAYER_PREVENT_CLIMB) == PLAYER_PREVENT_CLIMB) {
|
||||
@ -4491,7 +4597,13 @@ BOOL EXT_FUNC AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, e
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!player && ent->v.animtime && !ent->v.velocity.x && !ent->v.velocity.y && !ent->v.velocity.z)
|
||||
// add studio interpolation if non-player entity is moving (why?)
|
||||
if (!player &&
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// adds slerp (studio interpolation) if not set
|
||||
!(ent->v.effects & EF_NOSLERP) &&
|
||||
#endif
|
||||
ent->v.animtime && !ent->v.velocity.x && !ent->v.velocity.y && !ent->v.velocity.z)
|
||||
state->eflags |= EFLAG_SLERP;
|
||||
|
||||
state->scale = ent->v.scale;
|
||||
@ -4517,8 +4629,22 @@ BOOL EXT_FUNC AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, e
|
||||
|
||||
state->aiment = 0;
|
||||
|
||||
// following something
|
||||
if (ent->v.aiment)
|
||||
state->aiment = ENTINDEX(ent->v.aiment);
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// if set, it will still follow the player with a bit of "delay", still looks fine (experimental)
|
||||
if (ent->v.effects & EF_FOLLOWKEEPRENDER)
|
||||
{
|
||||
// will keep the current render entity values if it's set
|
||||
state->movetype = MOVETYPE_NONE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
state->aiment = ENTINDEX(ent->v.aiment);
|
||||
}
|
||||
}
|
||||
|
||||
state->owner = 0;
|
||||
if (ent->v.owner)
|
||||
@ -4817,6 +4943,16 @@ int EXT_FUNC GetWeaponData(edict_t *pEdict, struct weapon_data_s *info)
|
||||
item->fuser2 = weapon->m_flStartThrow;
|
||||
item->fuser3 = weapon->m_flReleaseThrow;
|
||||
item->iuser1 = weapon->m_iSwing;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (pPlayerItem == pPlayer->m_pActiveItem && !weapon->m_fInReload && weapon->m_iClip == II.iMaxClip)
|
||||
{
|
||||
const WeaponInfoStruct *wpnInfo = GetDefaultWeaponInfo(II.iId);
|
||||
|
||||
if (wpnInfo && wpnInfo->gunClipSize != II.iMaxClip)
|
||||
item->m_iClip = wpnInfo->gunClipSize;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -4849,7 +4985,12 @@ void EXT_FUNC UpdateClientData(const edict_t *ent, int sendweapons, struct clien
|
||||
}
|
||||
|
||||
cd->flags = pev->flags;
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
cd->health = max(pev->health, 0.0f);
|
||||
#else
|
||||
cd->health = pev->health;
|
||||
#endif
|
||||
|
||||
cd->viewmodel = MODEL_INDEX(STRING(pev->viewmodel));
|
||||
cd->waterlevel = pev->waterlevel;
|
||||
cd->watertype = pev->watertype;
|
||||
@ -4864,7 +5005,7 @@ void EXT_FUNC UpdateClientData(const edict_t *ent, int sendweapons, struct clien
|
||||
cd->flSwimTime = pev->flSwimTime;
|
||||
cd->waterjumptime = int(pev->teleport_time);
|
||||
|
||||
Q_strcpy(cd->physinfo, ENGINE_GETPHYSINFO(ent));
|
||||
Q_strlcpy(cd->physinfo, ENGINE_GETPHYSINFO(ent));
|
||||
|
||||
cd->maxspeed = pev->maxspeed;
|
||||
cd->fov = pev->fov;
|
||||
@ -5075,8 +5216,10 @@ int EXT_FUNC InconsistentFile(const edict_t *pEdict, const char *filename, char
|
||||
if (!CVAR_GET_FLOAT("mp_consistency"))
|
||||
return 0;
|
||||
|
||||
const int BufferLen = 256;
|
||||
|
||||
// Default behavior is to kick the player
|
||||
Q_sprintf(disconnect_message, "Server is enforcing file consistency for %s\n", filename);
|
||||
Q_snprintf(disconnect_message, BufferLen, "Server is enforcing file consistency for %s\n", filename);
|
||||
|
||||
// Kick now with specified disconnect message.
|
||||
return 1;
|
||||
|
@ -112,6 +112,7 @@ extern unsigned short g_iShadowSprite;
|
||||
void HandleMenu_ChooseAppearance_OrigFunc(CBasePlayer *pPlayer, int slot);
|
||||
BOOL HandleMenu_ChooseTeam_OrigFunc(CBasePlayer *pPlayer, int slot);
|
||||
bool BuyGunAmmo_OrigFunc(CBasePlayer *pPlayer, CBasePlayerItem *weapon, bool bBlinkMoney);
|
||||
void BuyItem_OrigFunc(CBasePlayer *pPlayer, int iSlot);
|
||||
CBaseEntity *BuyWeaponByWeaponID_OrigFunc(CBasePlayer *pPlayer, WeaponIdType weaponID);
|
||||
void ShowMenu_OrigFunc(CBasePlayer *pPlayer, int bitsValidSlots, int nDisplayTime, BOOL fNeedMore, char *pszText);
|
||||
void ShowVGUIMenu_OrigFunc(CBasePlayer *pPlayer, int MenuType, int BitMask, char *szOldMenu);
|
||||
|
@ -37,7 +37,10 @@ void SV_Continue_f()
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (pPlayer && !pPlayer->IsBot())
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (!pPlayer->IsBot())
|
||||
{
|
||||
// at the end of the round is showed window with the proposal surrender or continue
|
||||
// now of this time HUD is completely hidden
|
||||
@ -96,7 +99,7 @@ void SV_Career_EndRound_f()
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer || FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (pPlayer->IsBot() && pPlayer->m_iTeam == pLocalPlayer->m_iTeam)
|
||||
|
@ -4,24 +4,39 @@ void PlayerBlind(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAt
|
||||
{
|
||||
UTIL_ScreenFade(pPlayer, color, fadeTime, fadeHold, alpha, 0);
|
||||
|
||||
if (!fadetoblack.value)
|
||||
if (fadetoblack.value != FADETOBLACK_STAY)
|
||||
{
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pObserver = UTIL_PlayerByIndex(i);
|
||||
if (pObserver && pObserver->IsObservingPlayer(pPlayer))
|
||||
|
||||
if (!UTIL_IsValidPlayer(pObserver))
|
||||
continue;
|
||||
|
||||
if (pObserver->IsObservingPlayer(pPlayer))
|
||||
{
|
||||
UTIL_ScreenFade(pObserver, color, fadeTime, fadeHold, alpha, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pPlayer->Blind(fadeTime * 0.33, fadeHold, fadeTime, alpha);
|
||||
float flDurationTime = fadeTime * 0.33;
|
||||
pPlayer->Blind(flDurationTime, fadeHold, fadeTime, alpha);
|
||||
|
||||
if (TheBots)
|
||||
{
|
||||
TheBots->OnEvent(EVENT_PLAYER_BLINDED_BY_FLASHBANG, pPlayer);
|
||||
}
|
||||
|
||||
#if defined(REGAMEDLL_API) && defined(REGAMEDLL_ADD)
|
||||
float flAdjustedDamage;
|
||||
if (alpha > 200)
|
||||
flAdjustedDamage = fadeTime / 3;
|
||||
else
|
||||
flAdjustedDamage = fadeTime / 1.75;
|
||||
|
||||
pPlayer->CSPlayer()->RecordDamage(CBasePlayer::Instance(pevAttacker), flAdjustedDamage * 16.0f, flDurationTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RadiusFlash_TraceLine_hook(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, Vector &vecSrc, Vector &vecSpot, TraceResult *tr)
|
||||
@ -90,6 +105,19 @@ void RadiusFlash(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker,
|
||||
|
||||
if (tr2.flFraction >= 1.0)
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
switch ((int)teamflash.value)
|
||||
{
|
||||
case 0:
|
||||
if (pPlayer->pev != pevAttacker && g_pGameRules->PlayerRelationship(pPlayer, CBaseEntity::Instance(pevAttacker)) == GR_TEAMMATE)
|
||||
continue;
|
||||
break;
|
||||
case -1:
|
||||
if (pPlayer->pev == pevAttacker || g_pGameRules->PlayerRelationship(pPlayer, CBaseEntity::Instance(pevAttacker)) == GR_TEAMMATE)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (tr.fStartSolid)
|
||||
{
|
||||
tr.vecEndPos = vecSrc;
|
||||
@ -97,7 +125,6 @@ void RadiusFlash(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker,
|
||||
}
|
||||
|
||||
flAdjustedDamage = flDamage - (vecSrc - tr.vecEndPos).Length() * falloff;
|
||||
|
||||
if (flAdjustedDamage < 0)
|
||||
flAdjustedDamage = 0;
|
||||
|
||||
@ -258,8 +285,6 @@ void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker
|
||||
damageRatio = GetAmountOfPlayerVisible(vecSrc, pEntity);
|
||||
}
|
||||
|
||||
damageRatio = GetAmountOfPlayerVisible(vecSrc, pEntity);
|
||||
|
||||
float length;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// allow to damage breakable objects
|
||||
@ -290,6 +315,8 @@ void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker
|
||||
|
||||
if (tr.flFraction != 1.0f)
|
||||
flAdjustedDamage = 0.0f;
|
||||
else
|
||||
pEntity->SetDmgPenetrationLevel(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ NOXREF void UTIL_DPrintf(DebugOutputType outputType, char *pszMsg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, pszMsg);
|
||||
vsprintf(theDebugBuffer, pszMsg, argptr);
|
||||
Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SERVER_PRINT(theDebugBuffer);
|
||||
@ -41,7 +41,7 @@ void UTIL_DPrintf(char *pszMsg, ...)
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, pszMsg);
|
||||
vsprintf(theDebugBuffer, pszMsg, argptr);
|
||||
Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SERVER_PRINT(theDebugBuffer);
|
||||
@ -130,7 +130,7 @@ NOXREF void UTIL_BotDPrintf(char *pszMsg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, pszMsg);
|
||||
vsprintf(theDebugBuffer, pszMsg, argptr);
|
||||
Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SERVER_PRINT(theDebugBuffer);
|
||||
@ -146,7 +146,7 @@ void UTIL_CareerDPrintf(char *pszMsg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, pszMsg);
|
||||
vsprintf(theDebugBuffer, pszMsg, argptr);
|
||||
Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SERVER_PRINT(theDebugBuffer);
|
||||
@ -162,7 +162,7 @@ NOXREF void UTIL_TutorDPrintf(char *pszMsg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, pszMsg);
|
||||
vsprintf(theDebugBuffer, pszMsg, argptr);
|
||||
Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SERVER_PRINT(theDebugBuffer);
|
||||
@ -178,7 +178,7 @@ NOXREF void UTIL_StatsDPrintf(char *pszMsg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, pszMsg);
|
||||
vsprintf(theDebugBuffer, pszMsg, argptr);
|
||||
Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SERVER_PRINT(theDebugBuffer);
|
||||
@ -194,7 +194,7 @@ NOXREF void UTIL_HostageDPrintf(char *pszMsg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start(argptr, pszMsg);
|
||||
vsprintf(theDebugBuffer, pszMsg, argptr);
|
||||
Q_vsnprintf(theDebugBuffer, sizeof(theDebugBuffer), pszMsg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
SERVER_PRINT(theDebugBuffer);
|
||||
|
@ -1,5 +1,12 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#if !defined(DOOR_ASSERT)
|
||||
#undef DbgAssert
|
||||
#undef DbgAssertMsg
|
||||
#define DbgAssert(_exp) ((void)0)
|
||||
#define DbgAssertMsg(_exp, _msg) ((void)0)
|
||||
#endif
|
||||
|
||||
TYPEDESCRIPTION CBaseDoor::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD(CBaseDoor, m_bHealthValue, FIELD_CHARACTER),
|
||||
@ -215,7 +222,7 @@ void CBaseDoor::Spawn()
|
||||
// Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big
|
||||
m_vecPosition2 = m_vecPosition1 + (pev->movedir * (Q_fabs(real_t(pev->movedir.x * (pev->size.x - 2))) + Q_fabs(real_t(pev->movedir.y * (pev->size.y - 2))) + Q_fabs(real_t(pev->movedir.z * (pev->size.z - 2))) - m_flLip));
|
||||
|
||||
assert(("door start/end positions are equal", m_vecPosition1 != m_vecPosition2));
|
||||
DbgAssertMsg(m_vecPosition1 != m_vecPosition2, "door start/end positions are equal");
|
||||
|
||||
if (pev->spawnflags & SF_DOOR_START_OPEN)
|
||||
{
|
||||
@ -494,7 +501,7 @@ void CBaseDoor::DoorGoUp()
|
||||
bool isReversing = (m_toggle_state == TS_GOING_DOWN);
|
||||
|
||||
// It could be going-down, if blocked.
|
||||
assert(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN);
|
||||
DbgAssert(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN);
|
||||
|
||||
// emit door moving and stop sounds on CHAN_STATIC so that the multicast doesn't
|
||||
// filter them out and leave a client stuck with looping door sounds!
|
||||
@ -634,7 +641,7 @@ void CBaseDoor::DoorHitTop()
|
||||
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseArrived), VOL_NORM, ATTN_NORM);
|
||||
}
|
||||
|
||||
assert(m_toggle_state == TS_GOING_UP);
|
||||
DbgAssert(m_toggle_state == TS_GOING_UP);
|
||||
m_toggle_state = TS_AT_TOP;
|
||||
|
||||
// toggle-doors don't come down automatically, they wait for refire.
|
||||
@ -695,10 +702,7 @@ void CBaseDoor::DoorGoDown()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DOOR_ASSERT
|
||||
assert(m_toggle_state == TS_AT_TOP);
|
||||
#endif
|
||||
|
||||
DbgAssert(m_toggle_state == TS_AT_TOP);
|
||||
m_toggle_state = TS_GOING_DOWN;
|
||||
|
||||
SetMoveDone(&CBaseDoor::DoorHitBottom);
|
||||
@ -724,7 +728,7 @@ void CBaseDoor::DoorHitBottom()
|
||||
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseArrived), VOL_NORM, ATTN_NORM);
|
||||
}
|
||||
|
||||
assert(m_toggle_state == TS_GOING_DOWN);
|
||||
DbgAssert(m_toggle_state == TS_GOING_DOWN);
|
||||
m_toggle_state = TS_AT_BOTTOM;
|
||||
|
||||
// Re-instate touch method, cycle is complete
|
||||
@ -927,7 +931,7 @@ void CRotDoor::Spawn()
|
||||
m_vecAngle1 = pev->angles;
|
||||
m_vecAngle2 = pev->angles + pev->movedir * m_flMoveDistance;
|
||||
|
||||
assert(("rotating door start/end positions are equal", m_vecAngle1 != m_vecAngle2));
|
||||
DbgAssertMsg(m_vecAngle1 != m_vecAngle2, "rotating door start/end positions are equal");
|
||||
|
||||
if (pev->spawnflags & SF_DOOR_PASSABLE)
|
||||
pev->solid = SOLID_NOT;
|
||||
@ -1011,7 +1015,7 @@ void CMomentaryDoor::Spawn()
|
||||
|
||||
// Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big
|
||||
m_vecPosition2 = m_vecPosition1 + (pev->movedir * (Q_fabs(real_t(pev->movedir.x * (pev->size.x - 2))) + Q_fabs(real_t(pev->movedir.y * (pev->size.y - 2))) + Q_fabs(real_t(pev->movedir.z * (pev->size.z - 2))) - m_flLip));
|
||||
assert(("door start/end positions are equal", m_vecPosition1 != m_vecPosition2));
|
||||
DbgAssertMsg(m_vecPosition1 != m_vecPosition2, "door start/end positions are equal");
|
||||
|
||||
if (pev->spawnflags & SF_DOOR_START_OPEN)
|
||||
{
|
||||
|
@ -130,6 +130,10 @@ inline edict_t *EntityHandle<T>::Set(edict_t *pEdict)
|
||||
{
|
||||
m_serialnumber = pEdict->serialnumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_serialnumber = 0;
|
||||
}
|
||||
|
||||
return pEdict;
|
||||
}
|
||||
@ -176,7 +180,7 @@ inline int EntityHandle<T>::GetSerialNumber() const
|
||||
template <typename T>
|
||||
inline bool EntityHandle<T>::operator==(T *pEntity) const
|
||||
{
|
||||
assert(("EntityHandle<T>::operator==: got a nullptr pointer!", pEntity != nullptr));
|
||||
DbgAssertMsg(pEntity != nullptr, "EntityHandle<T>::operator==: got a nullptr pointer!");
|
||||
|
||||
if (m_serialnumber != pEntity->edict()->serialnumber)
|
||||
{
|
||||
@ -221,10 +225,10 @@ template <typename T>
|
||||
inline T *EntityHandle<T>::operator->()
|
||||
{
|
||||
edict_t *pEdict = Get();
|
||||
assert(("EntityHandle<T>::operator->: pointer is nullptr!", pEdict != nullptr));
|
||||
DbgAssertMsg(pEdict != nullptr, "EntityHandle<T>::operator->: pointer is nullptr!");
|
||||
|
||||
T *pEntity = GET_PRIVATE<T>(pEdict);
|
||||
assert(("EntityHandle<T>::operator->: pvPrivateData is nullptr!", pEntity != nullptr));
|
||||
DbgAssertMsg(pEntity != nullptr, "EntityHandle<T>::operator->: pvPrivateData is nullptr!");
|
||||
return pEntity;
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ void ExplosionCreate(const Vector ¢er, Vector &angles, edict_t *pOwner, int
|
||||
|
||||
CBaseEntity *pExplosion = CBaseEntity::Create("env_explosion", center, angles, pOwner);
|
||||
|
||||
Q_sprintf(buf, "%3d", magnitude);
|
||||
Q_snprintf(buf, sizeof(buf), "%3d", magnitude);
|
||||
|
||||
kvd.szKeyName = "iMagnitude";
|
||||
kvd.szValue = buf;
|
||||
|
@ -297,12 +297,12 @@ void CFuncTank::StopControl()
|
||||
|
||||
void CFuncTank::ControllerPostFrame()
|
||||
{
|
||||
assert(m_pController != nullptr);
|
||||
|
||||
if (gpGlobals->time < m_flNextAttack)
|
||||
return;
|
||||
|
||||
if (m_pController->pev->button & IN_ATTACK)
|
||||
Assert(m_pController != nullptr);
|
||||
|
||||
if (m_pController && m_pController->pev->button & IN_ATTACK)
|
||||
{
|
||||
Vector vecForward;
|
||||
UTIL_MakeVectorsPrivate(pev->angles, vecForward, nullptr, nullptr);
|
||||
@ -879,7 +879,7 @@ void CFuncTankControls::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T
|
||||
}
|
||||
|
||||
// if this fails, most likely means save/restore hasn't worked properly
|
||||
assert(m_pTank != nullptr);
|
||||
DbgAssert(m_pTank != nullptr);
|
||||
}
|
||||
|
||||
void CFuncTankControls::Think()
|
||||
|
@ -9,6 +9,7 @@ cvar_t *g_psv_friction = nullptr;
|
||||
cvar_t *g_psv_stopspeed = nullptr;
|
||||
cvar_t *g_psv_stepsize = nullptr;
|
||||
cvar_t *g_psv_clienttrace = nullptr;
|
||||
cvar_t *g_psv_maxvelocity = nullptr;
|
||||
|
||||
cvar_t displaysoundlist = { "displaysoundlist", "0", 0, 0.0f, nullptr };
|
||||
cvar_t timelimit = { "mp_timelimit", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
@ -159,16 +160,46 @@ cvar_t t_default_grenades = { "mp_t_default_grenades", "", 0, 0.0
|
||||
cvar_t t_give_player_knife = { "mp_t_give_player_knife", "1", 0, 1.0f, nullptr };
|
||||
cvar_t t_default_weapons_secondary = { "mp_t_default_weapons_secondary", "glock18", 0, 0.0f, nullptr };
|
||||
cvar_t t_default_weapons_primary = { "mp_t_default_weapons_primary", "", 0, 0.0f, nullptr };
|
||||
cvar_t default_weapons_random = { "mp_default_weapons_random", "", 0, 0.0f, nullptr };
|
||||
cvar_t free_armor = { "mp_free_armor", "0", 0, 0.0f, nullptr };
|
||||
cvar_t teamflash = { "mp_team_flash", "1", 0, 1.0f, nullptr };
|
||||
cvar_t allchat = { "sv_allchat", "0", 0, 0.0f, nullptr };
|
||||
cvar_t sv_autobunnyhopping = { "sv_autobunnyhopping", "0", 0, 0.0f, nullptr };
|
||||
cvar_t sv_enablebunnyhopping = { "sv_enablebunnyhopping", "0", 0, 0.0f, nullptr };
|
||||
cvar_t plant_c4_anywhere = { "mp_plant_c4_anywhere", "0", 0, 0.0f, nullptr };
|
||||
cvar_t give_c4_frags = { "mp_give_c4_frags", "3", 0, 3.0f, nullptr };
|
||||
cvar_t deathmsg_flags = { "mp_deathmsg_flags", "abc", 0, 0.0f, nullptr };
|
||||
cvar_t assist_damage_threshold = { "mp_assist_damage_threshold", "40", 0, 40.0f, nullptr };
|
||||
cvar_t freezetime_duck = { "mp_freezetime_duck", "1", 0, 1.0f, nullptr };
|
||||
cvar_t freezetime_jump = { "mp_freezetime_jump", "1", 0, 1.0f, nullptr };
|
||||
cvar_t jump_height = { "mp_jump_height", "45", FCVAR_SERVER, 45.0f, nullptr };
|
||||
|
||||
cvar_t hostages_rescued_ratio = { "mp_hostages_rescued_ratio", "1.0", 0, 1.0f, nullptr };
|
||||
cvar_t hostages_rescued_ratio = { "mp_hostages_rescued_ratio", "1.0", 0, 1.0f, nullptr };
|
||||
|
||||
cvar_t legacy_vehicle_block = { "mp_legacy_vehicle_block", "1", 0, 0.0f, nullptr };
|
||||
cvar_t legacy_vehicle_block = { "mp_legacy_vehicle_block", "1", 0, 0.0f, nullptr };
|
||||
|
||||
cvar_t dying_time = { "mp_dying_time", "3.0", 0, 3.0f, nullptr };
|
||||
cvar_t defuser_allocation = { "mp_defuser_allocation", "0", 0, 0.0f, nullptr };
|
||||
cvar_t location_area_info = { "mp_location_area_info", "0", 0, 0.0f, nullptr };
|
||||
cvar_t chat_loc_fallback = { "mp_chat_loc_fallback", "1", 0, 1.0f, nullptr };
|
||||
|
||||
cvar_t item_respawn_time = { "mp_item_respawn_time", "30", FCVAR_SERVER, 30.0f, nullptr };
|
||||
cvar_t weapon_respawn_time = { "mp_weapon_respawn_time", "20", FCVAR_SERVER, 20.0f, nullptr };
|
||||
cvar_t ammo_respawn_time = { "mp_ammo_respawn_time", "20", FCVAR_SERVER, 20.0f, nullptr };
|
||||
|
||||
cvar_t vote_flags = { "mp_vote_flags", "km", 0, 0.0f, nullptr };
|
||||
cvar_t votemap_min_time = { "mp_votemap_min_time", "180", 0, 180.0f, nullptr };
|
||||
|
||||
cvar_t flymove_method = { "mp_flymove_method", "0", 0, 0.0f, nullptr };
|
||||
cvar_t stamina_restore_rate = { "mp_stamina_restore_rate", "0", 0, 0.f, nullptr };
|
||||
|
||||
cvar_t logkills = { "mp_logkills", "1", FCVAR_SERVER, 0.0f, nullptr };
|
||||
cvar_t randomspawn = { "mp_randomspawn", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
|
||||
cvar_t playerid_showhealth = { "mp_playerid_showhealth", "1", 0, 1.0f, nullptr };
|
||||
cvar_t playerid_field = { "mp_playerid_field", "3", 0, 3.0f, nullptr };
|
||||
|
||||
cvar_t knockback = { "mp_knockback", "170", 0, 170.0f, nullptr };
|
||||
|
||||
void GameDLL_Version_f()
|
||||
{
|
||||
@ -220,8 +251,13 @@ void GameDLL_SwapTeams_f()
|
||||
|
||||
#endif // REGAMEDLL_ADD
|
||||
|
||||
SpewRetval_t GameDLL_SpewHandler(SpewType_t spewType, int level, const char *pMsg);
|
||||
|
||||
void EXT_FUNC GameDLLInit()
|
||||
{
|
||||
// By default, direct dbg reporting...
|
||||
SpewOutputFunc(GameDLL_SpewHandler);
|
||||
|
||||
g_pskill = CVAR_GET_POINTER("skill");
|
||||
g_psv_gravity = CVAR_GET_POINTER("sv_gravity");
|
||||
g_psv_aim = CVAR_GET_POINTER("sv_aim");
|
||||
@ -231,6 +267,7 @@ void EXT_FUNC GameDLLInit()
|
||||
g_psv_stopspeed = CVAR_GET_POINTER("sv_stopspeed");
|
||||
g_psv_stepsize = CVAR_GET_POINTER("sv_stepsize");
|
||||
g_psv_clienttrace = CVAR_GET_POINTER("sv_clienttrace");
|
||||
g_psv_maxvelocity = CVAR_GET_POINTER("sv_maxvelocity");
|
||||
|
||||
CVAR_REGISTER(&displaysoundlist);
|
||||
CVAR_REGISTER(&timelimit);
|
||||
@ -407,7 +444,9 @@ void EXT_FUNC GameDLLInit()
|
||||
CVAR_REGISTER(&t_give_player_knife);
|
||||
CVAR_REGISTER(&t_default_weapons_secondary);
|
||||
CVAR_REGISTER(&t_default_weapons_primary);
|
||||
CVAR_REGISTER(&default_weapons_random);
|
||||
CVAR_REGISTER(&free_armor);
|
||||
CVAR_REGISTER(&teamflash);
|
||||
CVAR_REGISTER(&allchat);
|
||||
CVAR_REGISTER(&sv_autobunnyhopping);
|
||||
CVAR_REGISTER(&sv_enablebunnyhopping);
|
||||
@ -418,11 +457,49 @@ void EXT_FUNC GameDLLInit()
|
||||
|
||||
CVAR_REGISTER(&legacy_vehicle_block);
|
||||
|
||||
CVAR_REGISTER(&dying_time);
|
||||
CVAR_REGISTER(&deathmsg_flags);
|
||||
CVAR_REGISTER(&assist_damage_threshold);
|
||||
|
||||
CVAR_REGISTER(&freezetime_duck);
|
||||
CVAR_REGISTER(&freezetime_jump);
|
||||
CVAR_REGISTER(&jump_height);
|
||||
CVAR_REGISTER(&defuser_allocation);
|
||||
CVAR_REGISTER(&location_area_info);
|
||||
CVAR_REGISTER(&chat_loc_fallback);
|
||||
|
||||
CVAR_REGISTER(&item_respawn_time);
|
||||
CVAR_REGISTER(&weapon_respawn_time);
|
||||
CVAR_REGISTER(&ammo_respawn_time);
|
||||
|
||||
CVAR_REGISTER(&vote_flags);
|
||||
CVAR_REGISTER(&votemap_min_time);
|
||||
CVAR_REGISTER(&randomspawn);
|
||||
|
||||
CVAR_REGISTER(&cv_bot_enable);
|
||||
CVAR_REGISTER(&cv_hostage_ai_enable);
|
||||
CVAR_REGISTER(&logkills);
|
||||
|
||||
CVAR_REGISTER(&playerid_showhealth);
|
||||
CVAR_REGISTER(&playerid_field);
|
||||
|
||||
CVAR_REGISTER(&stamina_restore_rate);
|
||||
|
||||
CVAR_REGISTER(&flymove_method);
|
||||
|
||||
CVAR_REGISTER(&knockback);
|
||||
|
||||
// print version
|
||||
CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n");
|
||||
|
||||
// execute initial pre-configurations
|
||||
SERVER_COMMAND("exec game_init.cfg\n");
|
||||
SERVER_EXECUTE();
|
||||
|
||||
#endif // REGAMEDLL_ADD
|
||||
|
||||
Regamedll_Game_Init();
|
||||
|
||||
Bot_RegisterCVars();
|
||||
Tutor_RegisterCVars();
|
||||
Hostage_RegisterCVars();
|
||||
@ -431,10 +508,29 @@ void EXT_FUNC GameDLLInit()
|
||||
VoiceGameMgr_RegisterCVars();
|
||||
#endif
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// execute initial pre-configurations
|
||||
SERVER_COMMAND("exec game_init.cfg\n");
|
||||
SERVER_EXECUTE();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
SpewRetval_t GameDLL_SpewHandler(SpewType_t spewType, int level, const char *pMsg)
|
||||
{
|
||||
bool bSpewPrint = (CVAR_GET_FLOAT("developer") >= level);
|
||||
switch (spewType)
|
||||
{
|
||||
case SPEW_LOG:
|
||||
case SPEW_MESSAGE:
|
||||
if (bSpewPrint) UTIL_ServerPrint("%s", pMsg);
|
||||
break;
|
||||
case SPEW_WARNING:
|
||||
if (bSpewPrint) UTIL_ServerPrint("Warning: %s", pMsg);
|
||||
break;
|
||||
case SPEW_ERROR:
|
||||
Sys_Error("%s", pMsg);
|
||||
return SPEW_ABORT; // fatal error, terminate it!
|
||||
case SPEW_ASSERT:
|
||||
UTIL_ServerPrint("Assert: %s", pMsg);
|
||||
return SPEW_DEBUGGER; // assert always tries to debugger break
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return SPEW_CONTINUE; // spew handled, continue on
|
||||
}
|
||||
|
@ -43,12 +43,13 @@
|
||||
extern cvar_t *g_pskill;
|
||||
extern cvar_t *g_psv_gravity;
|
||||
extern cvar_t *g_psv_aim;
|
||||
extern cvar_t *g_footsteps;
|
||||
extern cvar_t *g_psv_accelerate;
|
||||
extern cvar_t *g_psv_friction;
|
||||
extern cvar_t *g_psv_stopspeed;
|
||||
extern cvar_t *g_psv_stepsize;
|
||||
extern cvar_t *g_psv_clienttrace;
|
||||
extern cvar_t *g_footsteps;
|
||||
extern cvar_t *g_psv_maxvelocity;
|
||||
|
||||
extern cvar_t displaysoundlist;
|
||||
extern cvar_t timelimit;
|
||||
@ -185,19 +186,44 @@ extern cvar_t t_default_grenades;
|
||||
extern cvar_t t_give_player_knife;
|
||||
extern cvar_t t_default_weapons_secondary;
|
||||
extern cvar_t t_default_weapons_primary;
|
||||
extern cvar_t default_weapons_random;
|
||||
extern cvar_t free_armor;
|
||||
extern cvar_t teamflash;
|
||||
extern cvar_t allchat;
|
||||
extern cvar_t sv_autobunnyhopping;
|
||||
extern cvar_t sv_enablebunnyhopping;
|
||||
extern cvar_t plant_c4_anywhere;
|
||||
extern cvar_t give_c4_frags;
|
||||
extern cvar_t hostages_rescued_ratio;
|
||||
|
||||
extern cvar_t legacy_vehicle_block;
|
||||
extern cvar_t dying_time;
|
||||
extern cvar_t deathmsg_flags;
|
||||
extern cvar_t assist_damage_threshold;
|
||||
extern cvar_t freezetime_duck;
|
||||
extern cvar_t freezetime_jump;
|
||||
extern cvar_t jump_height;
|
||||
extern cvar_t defuser_allocation;
|
||||
extern cvar_t location_area_info;
|
||||
extern cvar_t chat_loc_fallback;
|
||||
extern cvar_t item_respawn_time;
|
||||
extern cvar_t weapon_respawn_time;
|
||||
extern cvar_t ammo_respawn_time;
|
||||
extern cvar_t vote_flags;
|
||||
extern cvar_t votemap_min_time;
|
||||
extern cvar_t flymove_method;
|
||||
extern cvar_t stamina_restore_rate;
|
||||
extern cvar_t logkills;
|
||||
extern cvar_t randomspawn;
|
||||
extern cvar_t playerid_showhealth;
|
||||
extern cvar_t playerid_field;
|
||||
extern cvar_t knockback;
|
||||
|
||||
#endif
|
||||
|
||||
extern cvar_t scoreboard_showmoney;
|
||||
extern cvar_t scoreboard_showhealth;
|
||||
extern cvar_t scoreboard_showdefkit;
|
||||
|
||||
|
||||
|
||||
void GameDLLInit();
|
||||
|
@ -8,8 +8,8 @@ CGameRules::CGameRules()
|
||||
m_bBombDropped = FALSE;
|
||||
m_bGameOver = false;
|
||||
|
||||
m_GameDesc = new char[sizeof("Counter-Strike")];
|
||||
Q_strcpy(m_GameDesc, AreRunningCZero() ? "Condition Zero" : "Counter-Strike");
|
||||
const char *pszGameDesc = AreRunningCZero() ? "Condition Zero" : "Counter-Strike";
|
||||
m_GameDesc = CloneString(pszGameDesc);
|
||||
}
|
||||
|
||||
CGameRules::~CGameRules()
|
||||
|
@ -31,27 +31,29 @@
|
||||
#include "game_shared/voice_gamemgr.h"
|
||||
#include "cmdhandler.h"
|
||||
|
||||
const int MAX_RULE_BUFFER = 1024;
|
||||
const int MAX_VOTE_MAPS = 100;
|
||||
const int MAX_VIP_QUEUES = 5;
|
||||
const int MAX_MONEY_THRESHOLD = 999999; // allowable money limit in the game that can be drawn on the HUD
|
||||
const int MAX_RULE_BUFFER = 1024;
|
||||
const int MAX_VOTE_MAPS = 100;
|
||||
const int MAX_VIP_QUEUES = 5;
|
||||
const int MAX_MONEY_THRESHOLD = 999999; // allowable money limit in the game that can be drawn on the HUD
|
||||
|
||||
const int MAX_MOTD_CHUNK = 60;
|
||||
const int MAX_MOTD_LENGTH = 1536; // (MAX_MOTD_CHUNK * 4)
|
||||
const int MAX_MOTD_CHUNK = 60;
|
||||
const int MAX_MOTD_LENGTH = 1536; // (MAX_MOTD_CHUNK * 4)
|
||||
|
||||
const float ITEM_RESPAWN_TIME = 30.0f;
|
||||
const float WEAPON_RESPAWN_TIME = 20.0f;
|
||||
const float AMMO_RESPAWN_TIME = 20.0f;
|
||||
const float ROUND_RESPAWN_TIME = 20.0f;
|
||||
const float ROUND_BEGIN_DELAY = 5.0f; // delay before beginning new round
|
||||
const float ITEM_KILL_DELAY = 300.0f;
|
||||
const float RADIO_TIMEOUT = 1.5f;
|
||||
const float ITEM_RESPAWN_TIME = 30.0f;
|
||||
const float WEAPON_RESPAWN_TIME = 20.0f;
|
||||
const float AMMO_RESPAWN_TIME = 20.0f;
|
||||
const float ROUND_RESPAWN_TIME = 20.0f;
|
||||
const float ROUND_BEGIN_DELAY = 5.0f; // delay before beginning new round
|
||||
const float ITEM_KILL_DELAY = 300.0f;
|
||||
const float RADIO_TIMEOUT = 1.5f;
|
||||
const float DEATH_ANIMATION_TIME = 3.0f;
|
||||
const float VOTEMAP_MIN_TIME = 180.0f;
|
||||
|
||||
const int MAX_INTERMISSION_TIME = 120; // longest the intermission can last, in seconds
|
||||
const int MAX_INTERMISSION_TIME = 120; // longest the intermission can last, in seconds
|
||||
|
||||
// when we are within this close to running out of entities, items
|
||||
// marked with the ITEM_FLAG_LIMITINWORLD will delay their respawn
|
||||
const int ENTITY_INTOLERANCE = 100;
|
||||
const int ENTITY_INTOLERANCE = 100;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -206,7 +208,7 @@ enum
|
||||
SCENARIO_BLOCK_PRISON_ESCAPE_TIME = BIT(8), // flag "i"
|
||||
SCENARIO_BLOCK_BOMB_TIME = BIT(9), // flag "j"
|
||||
SCENARIO_BLOCK_HOSTAGE_RESCUE_TIME = BIT(10), // flag "k"
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Player relationship return codes
|
||||
@ -219,6 +221,49 @@ enum
|
||||
GR_NEUTRAL,
|
||||
};
|
||||
|
||||
// The number of times you must kill a given player to be dominating them
|
||||
// Should always be more than 1
|
||||
const int CS_KILLS_FOR_DOMINATION = 4;
|
||||
|
||||
// Flags for specifying extra info about player death
|
||||
enum DeathMessageFlags
|
||||
{
|
||||
// float[3]
|
||||
// Position where the victim was killed by the enemy
|
||||
PLAYERDEATH_POSITION = 0x001,
|
||||
|
||||
// byte
|
||||
// Index of the assistant who helped the attacker kill the victim
|
||||
PLAYERDEATH_ASSISTANT = 0x002,
|
||||
|
||||
// short
|
||||
// Bitsum classification for the rarity of the kill
|
||||
// See enum KillRarity for details
|
||||
PLAYERDEATH_KILLRARITY = 0x004
|
||||
};
|
||||
|
||||
// Classifying various player kill methods in the game
|
||||
enum KillRarity
|
||||
{
|
||||
KILLRARITY_HEADSHOT = 0x001, // Headshot
|
||||
KILLRARITY_KILLER_BLIND = 0x002, // Killer was blind
|
||||
KILLRARITY_NOSCOPE = 0x004, // No-scope sniper rifle kill
|
||||
KILLRARITY_PENETRATED = 0x008, // Penetrated kill (through walls)
|
||||
KILLRARITY_THRUSMOKE = 0x010, // Smoke grenade penetration kill (bullets went through smoke)
|
||||
KILLRARITY_ASSISTEDFLASH = 0x020, // Assister helped with a flash
|
||||
KILLRARITY_DOMINATION_BEGAN = 0x040, // Killer player began dominating the victim (NOTE: this flag is set once)
|
||||
KILLRARITY_DOMINATION = 0x080, // Continues domination by the killer
|
||||
KILLRARITY_REVENGE = 0x100, // Revenge by the killer
|
||||
KILLRARITY_INAIR = 0x200 // Killer was in the air (skill to deal with high inaccuracy)
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DEFUSERALLOCATION_NONE = 0,
|
||||
DEFUSERALLOCATION_RANDOM = 1,
|
||||
DEFUSERALLOCATION_ALL = 2,
|
||||
};
|
||||
|
||||
class CItem;
|
||||
|
||||
class CGameRules
|
||||
@ -336,6 +381,8 @@ public:
|
||||
inline void SetGameOver() { m_bGameOver = true; }
|
||||
static float GetItemKillDelay();
|
||||
static float GetRadioTimeout();
|
||||
static float GetDyingTime();
|
||||
static float GetVotemapMinElapsedTime();
|
||||
|
||||
public:
|
||||
BOOL m_bFreezePeriod; // TRUE at beginning of round, set to FALSE when the period expires
|
||||
@ -541,7 +588,7 @@ public:
|
||||
// check if the scenario has been won/lost
|
||||
virtual void CheckWinConditions();
|
||||
virtual void RemoveGuns();
|
||||
virtual void GiveC4();
|
||||
virtual CBasePlayer *GiveC4();
|
||||
virtual void ChangeLevel();
|
||||
virtual void GoToIntermission();
|
||||
|
||||
@ -564,10 +611,15 @@ public:
|
||||
void RestartRound_OrigFunc();
|
||||
void CheckWinConditions_OrigFunc();
|
||||
void RemoveGuns_OrigFunc();
|
||||
void GiveC4_OrigFunc();
|
||||
CBasePlayer *GiveC4_OrigFunc();
|
||||
void ChangeLevel_OrigFunc();
|
||||
void GoToIntermission_OrigFunc();
|
||||
void BalanceTeams_OrigFunc();
|
||||
void Think_OrigFunc();
|
||||
BOOL TeamFull_OrigFunc(int team_id);
|
||||
BOOL TeamStacked_OrigFunc(int newTeam_id, int curTeam_id);
|
||||
void PlayerGotWeapon_OrigFunc(CBasePlayer *pPlayer, CBasePlayerItem *pWeapon);
|
||||
void SendDeathMessage_OrigFunc(CBaseEntity *pKiller, CBasePlayer *pVictim, CBasePlayer *pAssister, entvars_t *pevInflictor, const char *killerWeaponName, int iDeathMessageFlags, int iRarityOfKill);
|
||||
#endif
|
||||
|
||||
public:
|
||||
@ -692,6 +744,12 @@ public:
|
||||
VFUNC bool HasRoundTimeExpired();
|
||||
VFUNC bool IsBombPlanted();
|
||||
|
||||
VFUNC void SendDeathMessage(CBaseEntity *pKiller, CBasePlayer *pVictim, CBasePlayer *pAssister, entvars_t *pevInflictor, const char *killerWeaponName, int iDeathMessageFlags, int iRarityOfKill);
|
||||
int GetRarityOfKill(CBaseEntity *pKiller, CBasePlayer *pVictim, CBasePlayer *pAssister, const char *killerWeaponName, bool bFlashAssist);
|
||||
CBasePlayer *CheckAssistsToKill(CBaseEntity *pKiller, CBasePlayer *pVictim, bool &bFlashAssist);
|
||||
|
||||
void GiveDefuserToRandomPlayer();
|
||||
|
||||
private:
|
||||
void MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(int iTeam);
|
||||
|
||||
@ -733,7 +791,7 @@ public:
|
||||
bool m_bMapHasEscapeZone;
|
||||
|
||||
BOOL m_bMapHasVIPSafetyZone; // TRUE = has VIP safety zone, FALSE = does not have VIP safetyzone
|
||||
BOOL m_bMapHasCameras;
|
||||
int m_bMapHasCameras;
|
||||
int m_iC4Timer;
|
||||
int m_iC4Guy; // The current Terrorist who has the C4.
|
||||
int m_iLoserBonus; // the amount of money the losing team gets. This scales up as they lose more rounds in a row
|
||||
@ -921,6 +979,24 @@ inline float CGameRules::GetRadioTimeout()
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float CGameRules::GetDyingTime()
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
return dying_time.value;
|
||||
#else
|
||||
return DEATH_ANIMATION_TIME;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float CGameRules::GetVotemapMinElapsedTime()
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
return votemap_min_time.value;
|
||||
#else
|
||||
return VOTEMAP_MIN_TIME;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsBotSpeaking();
|
||||
void SV_Continue_f();
|
||||
void SV_Tutor_Toggle_f();
|
||||
@ -933,5 +1009,4 @@ char *GetTeam(int team);
|
||||
void DestroyMapCycle(mapcycle_t *cycle);
|
||||
int ReloadMapCycleFile(char *filename, mapcycle_t *cycle);
|
||||
int CountPlayers();
|
||||
void ExtractCommandString(char *s, char *szCommand);
|
||||
int GetMapCount();
|
||||
|
@ -600,9 +600,15 @@ void CGrenade::__API_HOOK(SG_Detonate)()
|
||||
}
|
||||
|
||||
m_bDetonated = true;
|
||||
PLAYBACK_EVENT_FULL(0, nullptr, m_usEvent, 0, pev->origin, (float *)&g_vecZero, 0, 0, 0, 1, m_bLightSmoke, FALSE);
|
||||
m_vSmokeDetonate = pev->origin;
|
||||
|
||||
int flags = 0;
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
flags = FEV_RELIABLE;
|
||||
#endif
|
||||
|
||||
PLAYBACK_EVENT_FULL(flags, nullptr, m_usEvent, 0, m_vSmokeDetonate, (float *)&g_vecZero, 0, 0, 0, 1, m_bLightSmoke, FALSE);
|
||||
|
||||
pev->velocity.x = RANDOM_FLOAT(-175, 175);
|
||||
pev->velocity.y = RANDOM_FLOAT(-175, 175);
|
||||
pev->velocity.z = RANDOM_FLOAT(250, 350);
|
||||
@ -766,6 +772,13 @@ void CGrenade::BounceSound()
|
||||
|
||||
void CGrenade::TumbleThink()
|
||||
{
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (pev->velocity.IsLengthGreaterThan(g_psv_maxvelocity->value))
|
||||
{
|
||||
pev->velocity = pev->velocity.Normalize() * g_psv_maxvelocity->value;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!IsInWorld())
|
||||
{
|
||||
UTIL_Remove(this);
|
||||
@ -803,6 +816,13 @@ void CGrenade::TumbleThink()
|
||||
|
||||
void CGrenade::SG_TumbleThink()
|
||||
{
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (pev->velocity.IsLengthGreaterThan(g_psv_maxvelocity->value))
|
||||
{
|
||||
pev->velocity = pev->velocity.Normalize() * g_psv_maxvelocity->value;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!IsInWorld())
|
||||
{
|
||||
UTIL_Remove(this);
|
||||
@ -1150,6 +1170,12 @@ void CGrenade::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTy
|
||||
if (!m_bIsC4)
|
||||
return;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
// block the start of defuse if the bomb timer has expired
|
||||
if (m_flC4Blow > 0 && gpGlobals->time >= m_flC4Blow)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// TODO: We must be sure that the activator is a player.
|
||||
CBasePlayer *pPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pActivator->pev);
|
||||
|
||||
@ -1316,6 +1342,13 @@ void AnnounceFlashInterval(float interval, float offset)
|
||||
|
||||
void CGrenade::C4Think()
|
||||
{
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (pev->velocity.IsLengthGreaterThan(g_psv_maxvelocity->value))
|
||||
{
|
||||
pev->velocity = pev->velocity.Normalize() * g_psv_maxvelocity->value;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!IsInWorld())
|
||||
{
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
@ -1476,6 +1509,13 @@ void CGrenade::C4Think()
|
||||
{
|
||||
DefuseBombEnd(pPlayer, false);
|
||||
}
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
// if the bomb timer has expired and defuse is still ongoing, stop the defuse
|
||||
else if (gpGlobals->time >= m_flC4Blow)
|
||||
{
|
||||
DefuseBombEnd(pPlayer, false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4,14 +4,14 @@ LINK_ENTITY_TO_CLASS(gib, CGib, CCSGib)
|
||||
|
||||
void CGib::LimitVelocity()
|
||||
{
|
||||
float length = pev->velocity.Length();
|
||||
float topspeed = g_psv_maxvelocity->value * 0.75f;
|
||||
|
||||
// ceiling at 1500. The gib velocity equation is not bounded properly. Rather than tune it
|
||||
// ceiling at topspeed. The gib velocity equation is not bounded properly. Rather than tune it
|
||||
// in 3 separate places again, I'll just limit it here.
|
||||
if (length > 1500.0)
|
||||
if (pev->velocity.IsLengthGreaterThan(topspeed))
|
||||
{
|
||||
// This should really be sv_maxvelocity * 0.75 or something
|
||||
pev->velocity = pev->velocity.Normalize() * 1500;
|
||||
// DONE: This should really be sv_maxvelocity * 0.75 or something
|
||||
pev->velocity = pev->velocity.Normalize() * topspeed;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,4 +11,3 @@ BOOL gDisplayTitle;
|
||||
bool g_bIsBeta = false;
|
||||
bool g_bIsCzeroGame = false;
|
||||
bool g_bAllowedCSBot = false;
|
||||
bool g_bHostageImprov = false;
|
||||
|
@ -38,4 +38,3 @@ extern BOOL gDisplayTitle;
|
||||
extern bool g_bIsBeta;
|
||||
extern bool g_bIsCzeroGame;
|
||||
extern bool g_bAllowedCSBot;
|
||||
extern bool g_bHostageImprov;
|
||||
|
@ -13,25 +13,9 @@ C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t *pEnginefuncsTable, global
|
||||
gpGlobals = pGlobals;
|
||||
|
||||
FileSystem_Init();
|
||||
Regamedll_Game_Init();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// DLL entry point
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
}
|
||||
else if (fdwReason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else // _WIN32
|
||||
#if defined(_LINUX)
|
||||
|
||||
void __attribute__((constructor)) DllMainLoad()
|
||||
{
|
||||
@ -41,4 +25,4 @@ void __attribute__((destructor)) DllMainUnload()
|
||||
{
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // _LINUX
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
cvar_t cv_hostage_ai_enable = { "hostage_ai_enable", "0", 0, 0.0f, nullptr };
|
||||
cvar_t cv_hostage_debug = { "hostage_debug", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
cvar_t cv_hostage_stop = { "hostage_stop", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
|
||||
@ -268,39 +269,48 @@ void CHostage::Spawn()
|
||||
|
||||
void CHostage::Precache()
|
||||
{
|
||||
if (AreImprovAllowed())
|
||||
if (cv_hostage_ai_enable.value)
|
||||
{
|
||||
string_t model = iStringNull;
|
||||
|
||||
static int which = 0;
|
||||
switch (which)
|
||||
{
|
||||
default:
|
||||
case REGULAR_GUY:
|
||||
pev->model = MAKE_STRING("models/hostageA.mdl");
|
||||
model = MAKE_STRING("models/hostageA.mdl");
|
||||
break;
|
||||
case OLD_GUY:
|
||||
pev->model = MAKE_STRING("models/hostageB.mdl");
|
||||
model = MAKE_STRING("models/hostageB.mdl");
|
||||
break;
|
||||
case BLACK_GUY:
|
||||
pev->model = MAKE_STRING("models/hostageC.mdl");
|
||||
model = MAKE_STRING("models/hostageC.mdl");
|
||||
break;
|
||||
case GOOFY_GUY:
|
||||
pev->model = MAKE_STRING("models/hostageD.mdl");
|
||||
break;
|
||||
default:
|
||||
model = MAKE_STRING("models/hostageD.mdl");
|
||||
break;
|
||||
}
|
||||
|
||||
m_whichModel = static_cast<ModelType>(which);
|
||||
|
||||
if (++which > 3)
|
||||
which = 0;
|
||||
if (++which > GOOFY_GUY)
|
||||
which = REGULAR_GUY;
|
||||
|
||||
if (g_pFileSystem->FileExists(model))
|
||||
{
|
||||
pev->model = model;
|
||||
}
|
||||
else
|
||||
{
|
||||
// It seems that the model is missing, so use classic hostages
|
||||
CVAR_SET_FLOAT("hostage_ai_enable", 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (pev->model.IsNull())
|
||||
{
|
||||
m_whichModel = REGULAR_GUY;
|
||||
if (pev->model.IsNull())
|
||||
{
|
||||
pev->model = MAKE_STRING("models/scientist.mdl");
|
||||
}
|
||||
pev->model = MAKE_STRING("models/scientist.mdl");
|
||||
}
|
||||
|
||||
PRECACHE_MODEL(pev->model);
|
||||
@ -342,7 +352,7 @@ void CHostage::IdleThink()
|
||||
const float giveUpTime = (1 / 30.0f);
|
||||
float const updateRate = 0.1f;
|
||||
|
||||
if (AreImprovAllowed() && !TheNavAreaList.empty())
|
||||
if (cv_hostage_ai_enable.value && !TheNavAreaList.empty())
|
||||
{
|
||||
if (!m_improv)
|
||||
{
|
||||
@ -619,7 +629,7 @@ void CHostage::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir
|
||||
BOOL CHostage::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (!CanTakeDamage(pevAttacker))
|
||||
if (pevAttacker && !CanTakeDamage(pevAttacker))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
@ -771,7 +781,7 @@ void CHostage::SetDeathActivity()
|
||||
return;
|
||||
}
|
||||
|
||||
if (AreImprovAllowed())
|
||||
if (cv_hostage_ai_enable.value)
|
||||
{
|
||||
switch (m_LastHitGroup)
|
||||
{
|
||||
@ -1242,7 +1252,7 @@ void CHostage::SendHostagePositionMsg()
|
||||
if (!pEntity->IsPlayer())
|
||||
continue;
|
||||
|
||||
if (pEntity->pev->flags == FL_DORMANT)
|
||||
if (pEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
CBasePlayer *pTempPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev);
|
||||
@ -1271,7 +1281,7 @@ void CHostage::SendHostageEventMsg()
|
||||
if (!pEntity->IsPlayer())
|
||||
continue;
|
||||
|
||||
if (pEntity->pev->flags == FL_DORMANT)
|
||||
if (pEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
CBasePlayer *pTempPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev);
|
||||
@ -1397,7 +1407,7 @@ void Hostage_RegisterCVars()
|
||||
{
|
||||
// These cvars are only used in czero
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (!AreImprovAllowed())
|
||||
if (!cv_hostage_ai_enable.value)
|
||||
return;
|
||||
#endif
|
||||
|
||||
@ -1432,7 +1442,7 @@ void CHostageManager::ServerActivate()
|
||||
AddHostage(pHostage);
|
||||
}
|
||||
|
||||
if (AreImprovAllowed())
|
||||
if (cv_hostage_ai_enable.value)
|
||||
{
|
||||
for (auto& snd : hostageSoundStruct) {
|
||||
m_chatter.AddSound(snd.type, snd.fileName);
|
||||
@ -1568,6 +1578,9 @@ void SimpleChatter::AddSound(HostageChatterType type, char *filename)
|
||||
|
||||
Q_snprintf(actualFilename, sizeof(actualFilename), "sound\\%s", filename);
|
||||
|
||||
if (!g_pFileSystem->FileExists(actualFilename))
|
||||
return;
|
||||
|
||||
chatter->file[chatter->count].filename = CloneString(filename);
|
||||
chatter->file[chatter->count].duration = (double)GET_APPROX_WAVE_PLAY_LEN(actualFilename) / 1000.0;
|
||||
|
||||
@ -1605,6 +1618,9 @@ void SimpleChatter::Shuffle(ChatterSet *chatter)
|
||||
char *SimpleChatter::GetSound(HostageChatterType type, float *duration)
|
||||
{
|
||||
ChatterSet *chatter = &m_chatter[type];
|
||||
if (chatter->count == 0)
|
||||
return nullptr;
|
||||
|
||||
char *sound;
|
||||
|
||||
Shuffle(chatter);
|
||||
|
@ -77,6 +77,7 @@ enum HostageChatterType
|
||||
extern CHostageManager *g_pHostages;
|
||||
extern int g_iHostageNumber;
|
||||
|
||||
extern cvar_t cv_hostage_ai_enable;
|
||||
extern cvar_t cv_hostage_debug;
|
||||
extern cvar_t cv_hostage_stop;
|
||||
|
||||
@ -284,11 +285,5 @@ private:
|
||||
SimpleChatter m_chatter;
|
||||
};
|
||||
|
||||
// Determine whether hostage improv can be used or not
|
||||
inline bool AreImprovAllowed()
|
||||
{
|
||||
return g_bHostageImprov;
|
||||
}
|
||||
|
||||
void Hostage_RegisterCVars();
|
||||
void InstallHostageManager();
|
||||
|
@ -358,10 +358,7 @@ bool CHostageImprov::IsFriendInTheWay(const Vector &goalPos) const
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (!pPlayer->IsAlive() || pPlayer->m_iTeam == TERRORIST)
|
||||
@ -675,10 +672,7 @@ void CHostageImprov::UpdateVision()
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (FStrEq(STRING(pPlayer->pev->netname), ""))
|
||||
@ -1611,9 +1605,9 @@ void CHostageImprov::Afraid()
|
||||
|
||||
int which = RANDOM_LONG(0, 100) % 3 + 1;
|
||||
|
||||
Q_sprintf(animInto, "cower_into_%d", which);
|
||||
Q_sprintf(animLoop, "cower_loop_%d", which);
|
||||
Q_sprintf(animExit, "cower_exit_%d", which);
|
||||
Q_snprintf(animInto, sizeof(animInto), "cower_into_%d", which);
|
||||
Q_snprintf(animLoop, sizeof(animLoop), "cower_loop_%d", which);
|
||||
Q_snprintf(animExit, sizeof(animExit), "cower_exit_%d", which);
|
||||
|
||||
m_animateState.AddSequence(this, animInto);
|
||||
m_animateState.AddSequence(this, animLoop, RANDOM_FLOAT(3, 10));
|
||||
|
@ -78,7 +78,7 @@ void HostageIdleState::OnUpdate(CHostageImprov *improv)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_moveState && improv->IsAtMoveGoal())
|
||||
if (m_moveState != NotMoving && improv->IsAtMoveGoal())
|
||||
{
|
||||
m_moveState = NotMoving;
|
||||
|
||||
|
@ -237,7 +237,7 @@ BOOL CItemBattery::MyTouch(CBasePlayer *pPlayer)
|
||||
pct--;
|
||||
|
||||
char szcharge[64];
|
||||
Q_sprintf(szcharge, "!HEV_%1dP", pct);
|
||||
Q_snprintf(szcharge, sizeof(szcharge), "!HEV_%1dP", pct);
|
||||
pPlayer->SetSuitUpdate(szcharge, SUIT_SENTENCE, SUIT_NEXT_IN_30SEC);
|
||||
|
||||
return TRUE;
|
||||
@ -481,22 +481,9 @@ BOOL CItemThighPack::MyTouch(CBasePlayer *pPlayer)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
pPlayer->m_bHasDefuser = true;
|
||||
pPlayer->pev->body = 1;
|
||||
|
||||
pPlayer->GiveDefuser();
|
||||
ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Got_defuser");
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pPlayer->pev);
|
||||
WRITE_BYTE(STATUSICON_SHOW);
|
||||
WRITE_STRING("defuser");
|
||||
WRITE_BYTE(0);
|
||||
WRITE_BYTE(160);
|
||||
WRITE_BYTE(0);
|
||||
MESSAGE_END();
|
||||
|
||||
pPlayer->SendItemStatus();
|
||||
pPlayer->SetScoreboardAttributes();
|
||||
|
||||
EMIT_SOUND(pPlayer->edict(), CHAN_VOICE, "items/kevlar.wav", VOL_NORM, ATTN_NORM);
|
||||
|
||||
if (TheTutor)
|
||||
|
@ -129,11 +129,11 @@ void CEnvLight::KeyValue(KeyValueData *pkvd)
|
||||
pkvd->fHandled = TRUE;
|
||||
|
||||
char szColor[64];
|
||||
Q_sprintf(szColor, "%d", r);
|
||||
Q_snprintf(szColor, sizeof(szColor), "%d", r);
|
||||
CVAR_SET_STRING("sv_skycolor_r", szColor);
|
||||
Q_sprintf(szColor, "%d", g);
|
||||
Q_snprintf(szColor, sizeof(szColor), "%d", g);
|
||||
CVAR_SET_STRING("sv_skycolor_g", szColor);
|
||||
Q_sprintf(szColor, "%d", b);
|
||||
Q_snprintf(szColor, sizeof(szColor), "%d", b);
|
||||
CVAR_SET_STRING("sv_skycolor_b", szColor);
|
||||
}
|
||||
else
|
||||
@ -147,13 +147,13 @@ void CEnvLight::Spawn()
|
||||
char szVector[64];
|
||||
UTIL_MakeAimVectors(pev->angles);
|
||||
|
||||
Q_sprintf(szVector, "%f", gpGlobals->v_forward.x);
|
||||
Q_snprintf(szVector, sizeof(szVector), "%f", gpGlobals->v_forward.x);
|
||||
CVAR_SET_STRING("sv_skyvec_x", szVector);
|
||||
|
||||
Q_sprintf(szVector, "%f", gpGlobals->v_forward.y);
|
||||
Q_snprintf(szVector, sizeof(szVector), "%f", gpGlobals->v_forward.y);
|
||||
CVAR_SET_STRING("sv_skyvec_y", szVector);
|
||||
|
||||
Q_sprintf(szVector, "%f", gpGlobals->v_forward.z);
|
||||
Q_snprintf(szVector, sizeof(szVector), "%f", gpGlobals->v_forward.z);
|
||||
CVAR_SET_STRING("sv_skyvec_z", szVector);
|
||||
|
||||
CLight::Spawn();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@ int __API_HOOK(GetForceCamera)(CBasePlayer *pObserver)
|
||||
{
|
||||
int retVal;
|
||||
|
||||
if (!fadetoblack.value)
|
||||
if (fadetoblack.value != FADETOBLACK_STAY)
|
||||
{
|
||||
retVal = int(CVAR_GET_FLOAT("mp_forcechasecam"));
|
||||
|
||||
@ -51,7 +51,7 @@ void UpdateClientEffects(CBasePlayer *pObserver, int oldMode)
|
||||
{
|
||||
bool clearProgress = false;
|
||||
bool clearBlindness = false;
|
||||
bool blindnessOk = (fadetoblack.value == 0);
|
||||
bool blindnessOk = (fadetoblack.value != FADETOBLACK_STAY);
|
||||
bool clearNightvision = false;
|
||||
|
||||
if (pObserver->GetObserverMode() == OBS_IN_EYE)
|
||||
@ -478,10 +478,19 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Observer_SetMode)(int iMode)
|
||||
// verify observer target again
|
||||
if (m_hObserverTarget)
|
||||
{
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
m_hObserverTarget = Observer_IsValidTarget( ENTINDEX(m_hObserverTarget->edict()), forcecamera != CAMERA_MODE_SPEC_ANYONE );
|
||||
#else
|
||||
CBasePlayer *pTarget = m_hObserverTarget;
|
||||
|
||||
if (pTarget == this || !pTarget || pTarget->has_disconnected || pTarget->GetObserverMode() != OBS_NONE || (pTarget->pev->effects & EF_NODRAW) || (forcecamera != CAMERA_MODE_SPEC_ANYONE && pTarget->m_iTeam != m_iTeam))
|
||||
if (pTarget == this
|
||||
|| !pTarget
|
||||
|| pTarget->has_disconnected
|
||||
|| pTarget->GetObserverMode() != OBS_NONE
|
||||
|| (pTarget->pev->effects & EF_NODRAW)
|
||||
|| (forcecamera != CAMERA_MODE_SPEC_ANYONE && pTarget->m_iTeam != m_iTeam))
|
||||
m_hObserverTarget = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// set spectator mode
|
||||
@ -525,14 +534,16 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Observer_SetMode)(int iMode)
|
||||
// print spepctaor mode on client screen
|
||||
|
||||
char modemsg[16];
|
||||
Q_sprintf(modemsg, "#Spec_Mode%i", pev->iuser1);
|
||||
Q_snprintf(modemsg, sizeof(modemsg), "#Spec_Mode%i", pev->iuser1);
|
||||
ClientPrint(pev, HUD_PRINTCENTER, modemsg);
|
||||
|
||||
m_iObserverLastMode = iMode;
|
||||
m_bWasFollowing = false;
|
||||
}
|
||||
|
||||
void CBasePlayer::Observer_Think()
|
||||
LINK_HOOK_CLASS_VOID_CHAIN2(CBasePlayer, Observer_Think)
|
||||
|
||||
void EXT_FUNC CBasePlayer::__API_HOOK(Observer_Think)()
|
||||
{
|
||||
Observer_HandleButtons();
|
||||
Observer_CheckTarget();
|
||||
|
@ -32,6 +32,12 @@
|
||||
#define CAMERA_MODE_SPEC_ONLY_TEAM 1
|
||||
#define CAMERA_MODE_SPEC_ONLY_FIRST_PERSON 2
|
||||
|
||||
enum FadeToBlack {
|
||||
FADETOBLACK_OFF,
|
||||
FADETOBLACK_STAY,
|
||||
FADETOBLACK_AT_DYING,
|
||||
};
|
||||
|
||||
int GetForceCamera(CBasePlayer *pObserver);
|
||||
void UpdateClientEffects(CBasePlayer *pObserver, int oldMode);
|
||||
|
||||
|
@ -23,7 +23,7 @@ void CPathCorner::KeyValue(KeyValueData *pkvd)
|
||||
|
||||
void CPathCorner::Spawn()
|
||||
{
|
||||
assert(("path_corner without a targetname", !pev->targetname.IsNull()));
|
||||
DbgAssertMsg(!pev->targetname.IsNull(), "path_corner without a targetname");
|
||||
}
|
||||
|
||||
TYPEDESCRIPTION CPathTrack::m_SaveData[] =
|
||||
|
@ -382,7 +382,7 @@ void CFuncPlat::GoDown()
|
||||
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMovement), m_volume, ATTN_NORM);
|
||||
}
|
||||
|
||||
assert(m_toggle_state == TS_AT_TOP || m_toggle_state == TS_GOING_UP);
|
||||
DbgAssert(m_toggle_state == TS_AT_TOP || m_toggle_state == TS_GOING_UP);
|
||||
m_toggle_state = TS_GOING_DOWN;
|
||||
SetMoveDone(&CFuncPlat::CallHitBottom);
|
||||
LinearMove(m_vecPosition2, pev->speed);
|
||||
@ -401,7 +401,7 @@ void CFuncPlat::HitBottom()
|
||||
EMIT_SOUND(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM);
|
||||
}
|
||||
|
||||
assert(m_toggle_state == TS_GOING_DOWN);
|
||||
DbgAssert(m_toggle_state == TS_GOING_DOWN);
|
||||
m_toggle_state = TS_AT_BOTTOM;
|
||||
}
|
||||
|
||||
@ -413,7 +413,7 @@ void CFuncPlat::GoUp()
|
||||
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMovement), m_volume, ATTN_NORM);
|
||||
}
|
||||
|
||||
assert(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN);
|
||||
DbgAssert(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN);
|
||||
m_toggle_state = TS_GOING_UP;
|
||||
SetMoveDone(&CFuncPlat::CallHitTop);
|
||||
LinearMove(m_vecPosition1, pev->speed);
|
||||
@ -432,7 +432,7 @@ void CFuncPlat::HitTop()
|
||||
EMIT_SOUND(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM);
|
||||
}
|
||||
|
||||
assert(m_toggle_state == TS_GOING_UP);
|
||||
DbgAssert(m_toggle_state == TS_GOING_UP);
|
||||
m_toggle_state = TS_AT_TOP;
|
||||
|
||||
if (!IsTogglePlat())
|
||||
@ -456,7 +456,7 @@ void CFuncPlat::Blocked(CBaseEntity *pOther)
|
||||
}
|
||||
|
||||
// Send the platform back where it came from
|
||||
assert(m_toggle_state == TS_GOING_UP || m_toggle_state == TS_GOING_DOWN);
|
||||
DbgAssert(m_toggle_state == TS_GOING_UP || m_toggle_state == TS_GOING_DOWN);
|
||||
|
||||
if (m_toggle_state == TS_GOING_UP)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -58,9 +58,10 @@ const int MAX_BUFFER_MENU_BRIEFING = 50;
|
||||
const float SUIT_UPDATE_TIME = 3.5f;
|
||||
const float SUIT_FIRST_UPDATE_TIME = 0.1f;
|
||||
|
||||
const float MAX_PLAYER_FATAL_FALL_SPEED = 1100.0f;
|
||||
const float MAX_PLAYER_SAFE_FALL_SPEED = 500.0f;
|
||||
const float MAX_PLAYER_USE_RADIUS = 64.0f;
|
||||
const float MAX_PLAYER_FATAL_FALL_SPEED = 1100.0f;
|
||||
const float MAX_PLAYER_SAFE_FALL_SPEED = 500.0f;
|
||||
const float MAX_PLAYER_USE_RADIUS = 64.0f;
|
||||
const float MAX_PLAYER_RUN_MODIFIER_SPEED = 10.0f; // x10 speed run when IN_RUN button is pressed
|
||||
|
||||
const float ARMOR_RATIO = 0.5f; // Armor Takes 50% of the damage
|
||||
const float ARMOR_BONUS = 0.5f; // Each Point of Armor is work 1/x points of health
|
||||
@ -444,6 +445,13 @@ public:
|
||||
void Pain_OrigFunc(int iLastHitGroup, bool bHasArmour);
|
||||
void DeathSound_OrigFunc();
|
||||
void JoiningThink_OrigFunc();
|
||||
void CheckTimeBasedDamage_OrigFunc();
|
||||
edict_t *EntSelectSpawnPoint_OrigFunc();
|
||||
void PlayerDeathThink_OrigFunc();
|
||||
void Observer_Think_OrigFunc();
|
||||
void RemoveAllItems_OrigFunc(BOOL removeSuit);
|
||||
void UpdateStatusBar_OrigFunc();
|
||||
void TakeDamageImpulse_OrigFunc(CBasePlayer *pAttacker, float flKnockbackForce, float flVelModifier);
|
||||
|
||||
CCSPlayer *CSPlayer() const;
|
||||
#endif // REGAMEDLL_API
|
||||
@ -453,6 +461,7 @@ public:
|
||||
static CBasePlayer *Instance(entvars_t *pev) { return Instance(ENT(pev)); }
|
||||
static CBasePlayer *Instance(int offset) { return Instance(ENT(offset)); }
|
||||
|
||||
float GetDyingAnimationDuration() const;
|
||||
void SpawnClientSideCorpse();
|
||||
void Observer_FindNextPlayer(bool bReverse, const char *name = nullptr);
|
||||
CBasePlayer *Observer_IsValidTarget(int iPlayerIndex, bool bSameTeam);
|
||||
@ -494,6 +503,7 @@ public:
|
||||
void SetClientUserInfoModel(char *infobuffer, char *szNewModel);
|
||||
void SetClientUserInfoModel_api(char *infobuffer, char *szNewModel);
|
||||
void SetNewPlayerModel(const char *modelName);
|
||||
const usercmd_t *GetLastUserCommand() const;
|
||||
BOOL SwitchWeapon(CBasePlayerItem *pWeapon);
|
||||
void CheckPowerups();
|
||||
bool CanAffordPrimary();
|
||||
@ -514,7 +524,9 @@ public:
|
||||
void UpdatePlayerSound();
|
||||
void DeathSound();
|
||||
void SetAnimation(PLAYER_ANIM playerAnim);
|
||||
void SetWeaponAnimType(const char *szExtention) { Q_strcpy(m_szAnimExtention, szExtention); }
|
||||
enum AnimationType { ANIM_NORMAL, ANIM_CROUCH };
|
||||
int GetAnimDesired(const char *szAnim, AnimationType type);
|
||||
void SetWeaponAnimType(const char *szExtention) { Q_strlcpy(m_szAnimExtention, szExtention); }
|
||||
void CheatImpulseCommands(int iImpulse);
|
||||
void StartDeathCam();
|
||||
void StartObserver(Vector &vecPosition, Vector &vecViewAngle);
|
||||
@ -531,6 +543,7 @@ public:
|
||||
void ItemPostFrame();
|
||||
CBaseEntity *GiveNamedItem(const char *pszName);
|
||||
CBaseEntity *GiveNamedItemEx(const char *pszName);
|
||||
CBaseEntity *GiveCopyItem(CBaseEntity *pEntityBase);
|
||||
void EnableControl(BOOL fControl);
|
||||
bool HintMessage(const char *pMessage, BOOL bDisplayIfPlayerDead = FALSE, BOOL bOverride = FALSE);
|
||||
bool HintMessageEx(const char *pMessage, float duration = 6.0f, bool bDisplayIfPlayerDead = false, bool bOverride = false);
|
||||
@ -585,6 +598,7 @@ public:
|
||||
bool IsReloading() const;
|
||||
bool HasTimePassedSinceDeath(float duration) const;
|
||||
bool IsBlind() const { return (m_blindUntilTime > gpGlobals->time); }
|
||||
bool IsFullyBlind(const float flPeekTime = 0.6f) const { return m_blindAlpha >= 255 && m_blindFadeTime > (flPeekTime * 2.0f) && (m_blindStartTime + m_blindHoldTime + flPeekTime) > gpGlobals->time; }
|
||||
bool IsAutoFollowAllowed() const { return (gpGlobals->time > m_allowAutoFollowTime); }
|
||||
void InhibitAutoFollow(float duration) { m_allowAutoFollowTime = gpGlobals->time + duration; }
|
||||
void AllowAutoFollow() { m_allowAutoFollowTime = 0; }
|
||||
@ -592,7 +606,7 @@ public:
|
||||
void AddAutoBuyData(const char *str);
|
||||
void AutoBuy();
|
||||
void ClientCommand(const char *cmd, const char *arg1 = nullptr, const char *arg2 = nullptr, const char *arg3 = nullptr);
|
||||
void PrioritizeAutoBuyString(char *autobuyString, const char *priorityString);
|
||||
void PrioritizeAutoBuyString(char (&autobuyString)[MAX_AUTOBUY_LENGTH], const char *priorityString);
|
||||
const char *PickPrimaryCareerTaskWeapon();
|
||||
const char *PickSecondaryCareerTaskWeapon();
|
||||
const char *PickFlashKillWeaponString();
|
||||
@ -628,12 +642,15 @@ public:
|
||||
void DropPrimary();
|
||||
void OnSpawnEquip(bool addDefault = true, bool equipGame = true);
|
||||
void RemoveBomb();
|
||||
void GiveDefuser();
|
||||
void RemoveDefuser();
|
||||
void HideTimer();
|
||||
bool MakeBomber();
|
||||
bool GetIntoGame();
|
||||
bool ShouldToShowAccount(CBasePlayer *pReceiver) const;
|
||||
bool ShouldToShowHealthInfo(CBasePlayer *pReceiver) const;
|
||||
const char *GetKillerWeaponName(entvars_t *pevInflictor, entvars_t *pevKiller) const;
|
||||
bool ShouldGibPlayer(int iGib);
|
||||
|
||||
CBasePlayerItem *GetItemByName(const char *itemName);
|
||||
CBasePlayerItem *GetItemById(WeaponIdType weaponID);
|
||||
@ -643,6 +660,7 @@ public:
|
||||
void UseEmpty();
|
||||
void DropIdlePlayer(const char *reason);
|
||||
bool Kill();
|
||||
void TakeDamageImpulse(CBasePlayer *pAttacker, float flKnockbackForce, float flVelModifier);
|
||||
|
||||
// templates
|
||||
template<typename T = CBasePlayerItem, typename Functor>
|
||||
@ -907,6 +925,7 @@ public:
|
||||
|
||||
CWeaponBox *CreateWeaponBox(CBasePlayerItem *pItem, CBasePlayer *pPlayerOwner, const char *modelName, Vector &origin, Vector &angles, Vector &velocity, float lifeTime, bool packAmmo);
|
||||
CWeaponBox *CreateWeaponBox_OrigFunc(CBasePlayerItem *pItem, CBasePlayer *pPlayerOwner, const char *modelName, Vector &origin, Vector &angles, Vector &velocity, float lifeTime, bool packAmmo);
|
||||
CItemThighPack *SpawnDefuser(const Vector &vecOrigin, edict_t *pentOwner);
|
||||
|
||||
class CWShield: public CBaseEntity
|
||||
{
|
||||
@ -946,7 +965,24 @@ inline bool CBasePlayer::HasTimePassedSinceDeath(float duration) const
|
||||
inline CCSPlayer *CBasePlayer::CSPlayer() const {
|
||||
return reinterpret_cast<CCSPlayer *>(this->m_pEntity);
|
||||
}
|
||||
#endif
|
||||
#else // !REGAMEDLL_API
|
||||
|
||||
// Determine whether player can be gibbed or not
|
||||
inline bool CBasePlayer::ShouldGibPlayer(int iGib)
|
||||
{
|
||||
// Always gib the player regardless of incoming damage
|
||||
if (iGib == GIB_ALWAYS)
|
||||
return true;
|
||||
|
||||
// Gib the player if health is below the gib damage threshold
|
||||
if (pev->health < GIB_PLAYER_THRESHOLD && iGib != GIB_NEVER)
|
||||
return true;
|
||||
|
||||
// do not gib the player
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // !REGAMEDLL_API
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
|
||||
@ -957,6 +993,19 @@ inline CBasePlayer *UTIL_PlayerByIndex(int playerIndex)
|
||||
return GET_PRIVATE<CBasePlayer>(INDEXENT(playerIndex));
|
||||
}
|
||||
|
||||
// return true if the given player is valid
|
||||
inline bool UTIL_IsValidPlayer(CBaseEntity *pPlayer)
|
||||
{
|
||||
return pPlayer && !FNullEnt(pPlayer->pev) && !pPlayer->IsDormant();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline bool UTIL_IsValidPlayer(CBaseEntity *pPlayer)
|
||||
{
|
||||
return pPlayer && !FNullEnt(pPlayer->pev);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
inline CBasePlayer *UTIL_PlayerByIndexSafe(int playerIndex)
|
||||
@ -968,7 +1017,6 @@ inline CBasePlayer *UTIL_PlayerByIndexSafe(int playerIndex)
|
||||
return pPlayer;
|
||||
}
|
||||
|
||||
extern entvars_t *g_pevLastInflictor;
|
||||
extern CBaseEntity *g_pLastSpawn;
|
||||
extern CBaseEntity *g_pLastCTSpawn;
|
||||
extern CBaseEntity *g_pLastTerroristSpawn;
|
||||
@ -996,11 +1044,10 @@ void SendItemStatus(CBasePlayer *pPlayer);
|
||||
const char *GetCSModelName(int item_id);
|
||||
Vector VecVelocityForDamage(float flDamage);
|
||||
int TrainSpeed(int iSpeed, int iMax);
|
||||
const char *GetWeaponName(entvars_t *pevInflictor, entvars_t *pKiller);
|
||||
void LogAttack(CBasePlayer *pAttacker, CBasePlayer *pVictim, int teamAttack, int healthHit, int armorHit, int newHealth, int newArmor, const char *killer_weapon_name);
|
||||
bool CanSeeUseable(CBasePlayer *me, CBaseEntity *pEntity);
|
||||
void FixPlayerCrouchStuck(edict_t *pPlayer);
|
||||
BOOL IsSpawnPointValid(CBaseEntity *pPlayer, CBaseEntity *pSpot);
|
||||
BOOL IsSpawnPointValid(CBaseEntity *pPlayer, CBaseEntity *pSpot, float fRadius);
|
||||
CBaseEntity *FindEntityForward(CBaseEntity *pMe);
|
||||
real_t GetPlayerPitch(const edict_t *pEdict);
|
||||
real_t GetPlayerYaw(const edict_t *pEdict);
|
||||
|
@ -30,16 +30,18 @@
|
||||
|
||||
#define QSTRING_DEFINE
|
||||
|
||||
constexpr unsigned int iStringNull = {0};
|
||||
|
||||
// Quake string (helper class)
|
||||
class QString final
|
||||
{
|
||||
public:
|
||||
#if XASH_64BIT
|
||||
using qstring_t = int;
|
||||
#else
|
||||
using qstring_t = unsigned int;
|
||||
#endif
|
||||
|
||||
QString(): m_string(iStringNull) {};
|
||||
QString(qstring_t string): m_string(string) {};
|
||||
QString();
|
||||
QString(qstring_t string);
|
||||
|
||||
bool IsNull() const;
|
||||
bool IsNullOrEmpty() const;
|
||||
@ -52,13 +54,15 @@ public:
|
||||
bool operator==(const char *pszString) const;
|
||||
|
||||
operator const char *() const;
|
||||
operator unsigned int() const;
|
||||
operator qstring_t() const;
|
||||
const char *str() const;
|
||||
|
||||
private:
|
||||
qstring_t m_string;
|
||||
};
|
||||
|
||||
constexpr QString::qstring_t iStringNull = {0};
|
||||
|
||||
#ifdef USE_QSTRING
|
||||
#define string_t QString
|
||||
#endif
|
||||
@ -70,10 +74,25 @@ private:
|
||||
|
||||
extern globalvars_t *gpGlobals;
|
||||
|
||||
#define STRING(offset) ((const char *)(gpGlobals->pStringBase + (unsigned int)(offset)))
|
||||
#define MAKE_STRING(str) ((unsigned int)(str) - (unsigned int)(STRING(0)))
|
||||
#define STRING(offset) ((const char *)(gpGlobals->pStringBase + (QString::qstring_t)(offset)))
|
||||
#if XASH_64BIT
|
||||
// Xash3D FWGS in 64-bit mode has internal string pool which allows mods to continue use 32-bit string_t
|
||||
inline int MAKE_STRING(const char *str)
|
||||
{
|
||||
ptrdiff_t diff = str - STRING(0);
|
||||
if (diff >= INT_MIN && diff <= INT_MAX)
|
||||
return (int)diff;
|
||||
|
||||
return ALLOC_STRING(str);
|
||||
}
|
||||
#else
|
||||
#define MAKE_STRING(str) ((QString::qstring_t)(str) - (QString::qstring_t)(STRING(0)))
|
||||
#endif
|
||||
|
||||
// Inlines
|
||||
inline QString::QString(): m_string(iStringNull) {}
|
||||
inline QString::QString(qstring_t string): m_string(string) {}
|
||||
|
||||
inline bool QString::IsNull() const
|
||||
{
|
||||
return m_string == iStringNull;
|
||||
@ -115,7 +134,7 @@ inline QString::operator const char *() const
|
||||
return str();
|
||||
}
|
||||
|
||||
inline QString::operator unsigned int() const
|
||||
inline QString::operator qstring_t() const
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
|
@ -250,10 +250,10 @@ edict_t *CSaveRestoreBuffer::EntityFromIndex(int entityIndex)
|
||||
|
||||
int CSaveRestoreBuffer::EntityFlagsSet(int entityIndex, int flags)
|
||||
{
|
||||
if (!m_pData || entityIndex < 0)
|
||||
if (!m_pData)
|
||||
return 0;
|
||||
|
||||
if (!m_pData || entityIndex < 0 || entityIndex > m_pData->tableCount)
|
||||
if (entityIndex < 0 || entityIndex > m_pData->tableCount)
|
||||
return 0;
|
||||
|
||||
m_pData->pTable[entityIndex].flags |= flags;
|
||||
@ -955,15 +955,15 @@ void CGlobalState::DumpGlobals()
|
||||
|
||||
void CGlobalState::EntityAdd(string_t globalname, string_t mapName, GLOBALESTATE state)
|
||||
{
|
||||
assert(!Find(globalname));
|
||||
DbgAssert(!Find(globalname));
|
||||
|
||||
globalentity_t *pNewEntity = (globalentity_t *)calloc(sizeof(globalentity_t), 1);
|
||||
assert(pNewEntity != nullptr);
|
||||
DbgAssert(pNewEntity != nullptr);
|
||||
|
||||
pNewEntity->pNext = m_pList;
|
||||
m_pList = pNewEntity;
|
||||
Q_strcpy(pNewEntity->name, STRING(globalname));
|
||||
Q_strcpy(pNewEntity->levelName, STRING(mapName));
|
||||
Q_strlcpy(pNewEntity->name, STRING(globalname));
|
||||
Q_strlcpy(pNewEntity->levelName, STRING(mapName));
|
||||
pNewEntity->state = state;
|
||||
|
||||
m_listCount++;
|
||||
@ -1068,7 +1068,7 @@ void CGlobalState::EntityUpdate(string_t globalname, string_t mapname)
|
||||
globalentity_t *pEnt = Find(globalname);
|
||||
if (pEnt)
|
||||
{
|
||||
Q_strcpy(pEnt->levelName, STRING(mapname));
|
||||
Q_strlcpy(pEnt->levelName, STRING(mapname));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ NOXREF float GetSkillCvar(char *pName)
|
||||
float flValue;
|
||||
char szBuffer[64];
|
||||
|
||||
iCount = Q_sprintf(szBuffer, "%s%d", pName, gSkillData.iSkillLevel);
|
||||
iCount = Q_snprintf(szBuffer, sizeof(szBuffer), "%s%d", pName, gSkillData.iSkillLevel);
|
||||
flValue = CVAR_GET_FLOAT(szBuffer);
|
||||
|
||||
if (flValue <= 0.0f)
|
||||
|
@ -1040,11 +1040,10 @@ void USENTENCEG_InitLRU(unsigned char *plru, int count)
|
||||
// ipick is passed in as the requested sentence ordinal.
|
||||
// ipick 'next' is returned.
|
||||
// return of -1 indicates an error.
|
||||
int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int freset)
|
||||
int USENTENCEG_PickSequential(int isentenceg, char (&szfound)[64], int ipick, int freset)
|
||||
{
|
||||
char *szgroupname;
|
||||
unsigned char count;
|
||||
char sznum[12];
|
||||
|
||||
if (!fSentencesInit)
|
||||
return -1;
|
||||
@ -1061,10 +1060,7 @@ int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int fres
|
||||
if (ipick >= count)
|
||||
ipick = count - 1;
|
||||
|
||||
Q_strcpy(szfound, "!");
|
||||
Q_strcat(szfound, szgroupname);
|
||||
Q_snprintf(sznum, sizeof(sznum), "%d", ipick);
|
||||
Q_strcat(szfound, sznum);
|
||||
Q_snprintf(szfound, sizeof(szfound), "!%s%d", szgroupname, ipick);
|
||||
|
||||
if (ipick >= count)
|
||||
{
|
||||
@ -1084,13 +1080,12 @@ int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int fres
|
||||
// rest of the lru filled with -1. The first integer in the lru is
|
||||
// actually the size of the list. Returns ipick, the ordinal
|
||||
// of the picked sentence within the group.
|
||||
int USENTENCEG_Pick(int isentenceg, char *szfound)
|
||||
int USENTENCEG_Pick(int isentenceg, char (&szfound)[64])
|
||||
{
|
||||
char *szgroupname;
|
||||
unsigned char *plru;
|
||||
unsigned char i;
|
||||
unsigned char count;
|
||||
char sznum[12];
|
||||
unsigned char ipick = 0xFF;
|
||||
BOOL ffound = FALSE;
|
||||
|
||||
@ -1119,11 +1114,7 @@ int USENTENCEG_Pick(int isentenceg, char *szfound)
|
||||
|
||||
if (ffound)
|
||||
{
|
||||
Q_strcpy(szfound, "!");
|
||||
Q_strcat(szfound, szgroupname);
|
||||
Q_snprintf(sznum, sizeof(sznum), "%d", ipick);
|
||||
Q_strcat(szfound, sznum);
|
||||
|
||||
Q_snprintf(szfound, sizeof(szfound), "!%s%d", szgroupname, ipick);
|
||||
return ipick;
|
||||
}
|
||||
else
|
||||
@ -1168,8 +1159,6 @@ int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, float volume, float atte
|
||||
if (!fSentencesInit)
|
||||
return -1;
|
||||
|
||||
name[0] = '\0';
|
||||
|
||||
ipick = USENTENCEG_Pick(isentenceg, name);
|
||||
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
@ -1194,8 +1183,6 @@ int SENTENCEG_PlayRndSz(edict_t *entity, const char *szgroupname, float volume,
|
||||
if (!fSentencesInit)
|
||||
return -1;
|
||||
|
||||
name[0] = '\0';
|
||||
|
||||
isentenceg = SENTENCEG_GetIndex(szgroupname);
|
||||
if (isentenceg < 0)
|
||||
{
|
||||
@ -1223,8 +1210,6 @@ int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szgroupname, float v
|
||||
if (!fSentencesInit)
|
||||
return -1;
|
||||
|
||||
name[0] = '\0';
|
||||
|
||||
isentenceg = SENTENCEG_GetIndex(szgroupname);
|
||||
if (isentenceg < 0)
|
||||
return -1;
|
||||
@ -1323,7 +1308,7 @@ void SENTENCEG_Init()
|
||||
ALERT(at_warning, "Sentence %s longer than %d letters\n", pString, MAX_SENTENCE_NAME - 1);
|
||||
}
|
||||
|
||||
Q_strcpy(gszallsentencenames[gcallsentences++], pString);
|
||||
Q_strlcpy(gszallsentencenames[gcallsentences++], pString);
|
||||
|
||||
if (--j <= i)
|
||||
continue;
|
||||
@ -1354,10 +1339,10 @@ void SENTENCEG_Init()
|
||||
break;
|
||||
}
|
||||
|
||||
Q_strcpy(rgsentenceg[isentencegs].szgroupname, &(buffer[i]));
|
||||
Q_strlcpy(rgsentenceg[isentencegs].szgroupname, &(buffer[i]));
|
||||
rgsentenceg[isentencegs].count = 1;
|
||||
|
||||
Q_strcpy(szgroup, &(buffer[i]));
|
||||
Q_strlcpy(szgroup, &(buffer[i]));
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -1377,7 +1362,7 @@ void SENTENCEG_Init()
|
||||
|
||||
i = 0;
|
||||
|
||||
while (rgsentenceg[i].count && i < MAX_SENTENCE_GROUPS)
|
||||
while (i < MAX_SENTENCE_GROUPS && rgsentenceg[i].count)
|
||||
{
|
||||
USENTENCEG_InitLRU(&(rgsentenceg[i].rgblru[0]), rgsentenceg[i].count);
|
||||
i++;
|
||||
@ -1385,9 +1370,8 @@ void SENTENCEG_Init()
|
||||
}
|
||||
|
||||
// convert sentence (sample) name to !sentencenum, return !sentencenum
|
||||
int SENTENCEG_Lookup(const char *sample, char *sentencenum)
|
||||
int SENTENCEG_Lookup(const char *sample, char (&sentencenum)[32])
|
||||
{
|
||||
char sznum[12];
|
||||
int i;
|
||||
|
||||
// this is a sentence name; lookup sentence number
|
||||
@ -1396,13 +1380,7 @@ int SENTENCEG_Lookup(const char *sample, char *sentencenum)
|
||||
{
|
||||
if (!Q_stricmp(gszallsentencenames[i], sample + 1))
|
||||
{
|
||||
if (sentencenum)
|
||||
{
|
||||
Q_strcpy(sentencenum, "!");
|
||||
Q_snprintf(sznum, sizeof(sznum), "%d", i);
|
||||
Q_strcat(sentencenum, sznum);
|
||||
}
|
||||
|
||||
Q_snprintf(sentencenum, sizeof(sentencenum), "!%d", i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -1580,7 +1558,7 @@ void TEXTURETYPE_Init()
|
||||
j = Q_min(j, MAX_TEXTURENAME_LENGHT - 1 + i);
|
||||
buffer[j] = '\0';
|
||||
|
||||
Q_strcpy(&(grgszTextureName[gcTextures++][0]), &(buffer[i]));
|
||||
Q_strlcpy(grgszTextureName[gcTextures++], &(buffer[i]));
|
||||
}
|
||||
|
||||
FREE_FILE(pMemFile);
|
||||
@ -1616,7 +1594,7 @@ float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int
|
||||
char chTextureType;
|
||||
float fvol;
|
||||
float fvolbar;
|
||||
char szBuffer[64];
|
||||
char szBuffer[MAX_TEXTURENAME_LENGHT];
|
||||
const char *pTextureName;
|
||||
float rgfl1[3];
|
||||
float rgfl2[3];
|
||||
@ -1666,8 +1644,7 @@ float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int
|
||||
pTextureName++;
|
||||
|
||||
// '}}'
|
||||
Q_strcpy(szBuffer, pTextureName);
|
||||
szBuffer[MAX_TEXTURENAME_LENGHT - 1] = '\0';
|
||||
Q_strlcpy(szBuffer, pTextureName);
|
||||
|
||||
// get texture type
|
||||
chTextureType = TEXTURETYPE_Find(szBuffer);
|
||||
|
@ -170,15 +170,13 @@ public:
|
||||
|
||||
BOOL FEnvSoundInRange(entvars_t *pev, entvars_t *pevTarget, float *pflRange);
|
||||
void USENTENCEG_InitLRU(unsigned char *plru, int count);
|
||||
int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int freset);
|
||||
int USENTENCEG_Pick(int isentenceg, char *szfound);
|
||||
int SENTENCEG_GetIndex(const char *szgroupname);
|
||||
int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, float volume, float attenuation, int flags, int pitch);
|
||||
int SENTENCEG_PlayRndSz(edict_t *entity, const char *szgroupname, float volume, float attenuation, int flags, int pitch);
|
||||
int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szgroupname, float volume, float attenuation, int flags, int pitch, int ipick, int freset);
|
||||
void SENTENCEG_Stop(edict_t *entity, int isentenceg, int ipick);
|
||||
void SENTENCEG_Init();
|
||||
int SENTENCEG_Lookup(const char *sample, char *sentencenum);
|
||||
int SENTENCEG_Lookup(const char *sample, char (&sentencenum)[32]);
|
||||
void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int flags, int pitch);
|
||||
void EMIT_SOUND_SUIT(edict_t *entity, const char *sample);
|
||||
void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg);
|
||||
|
@ -330,8 +330,8 @@ void CBaseToggle::KeyValue(KeyValueData *pkvd)
|
||||
// pev->origin traveling at flSpeed
|
||||
void CBaseToggle::LinearMove(Vector vecDest, float flSpeed)
|
||||
{
|
||||
assert(("LinearMove: no speed is defined!", flSpeed != 0));
|
||||
//assert(("LinearMove: no post-move function defined", m_pfnCallWhenMoveDone != nullptr));
|
||||
DbgAssertMsg(flSpeed != 0, "LinearMove: no speed is defined!");
|
||||
//DbgAssertMsg(m_pfnCallWhenMoveDone != nullptr, "LinearMove: no post-move function defined");
|
||||
|
||||
m_vecFinalDest = vecDest;
|
||||
|
||||
@ -382,8 +382,8 @@ NOXREF BOOL CBaseToggle::IsLockedByMaster()
|
||||
// Just like LinearMove, but rotational.
|
||||
void CBaseToggle::AngularMove(Vector vecDestAngle, float flSpeed)
|
||||
{
|
||||
assert(("AngularMove: no speed is defined!", flSpeed != 0));
|
||||
//assert(("AngularMove: no post-move function defined", m_pfnCallWhenMoveDone != nullptr));
|
||||
DbgAssertMsg(flSpeed != 0, "AngularMove: no speed is defined!");
|
||||
//DbgAssertMsg(m_pfnCallWhenMoveDone != nullptr, "AngularMove: no post-move function defined");
|
||||
|
||||
m_vecFinalAngle = vecDestAngle;
|
||||
|
||||
|
@ -468,7 +468,10 @@ void CBaseTrigger::InitTrigger()
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
|
||||
// set size and link into world
|
||||
SET_MODEL(ENT(pev), STRING(pev->model));
|
||||
if (FStringNull(pev->model))
|
||||
UTIL_SetOrigin(pev, pev->origin); // link into the list
|
||||
else
|
||||
SET_MODEL(ENT(pev), STRING(pev->model));
|
||||
|
||||
if (CVAR_GET_FLOAT("showtriggers") == 0)
|
||||
{
|
||||
@ -582,7 +585,6 @@ void CTriggerCDAudio::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP
|
||||
PlayTrack(pCaller->edict());
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
const char *g_szMP3trackFileMap[] =
|
||||
{
|
||||
"", "",
|
||||
@ -614,7 +616,6 @@ const char *g_szMP3trackFileMap[] =
|
||||
"media/Suspense05.mp3",
|
||||
"media/Suspense07.mp3"
|
||||
};
|
||||
#endif
|
||||
|
||||
void PlayCDTrack(edict_t *pClient, int iTrack)
|
||||
{
|
||||
@ -622,7 +623,7 @@ void PlayCDTrack(edict_t *pClient, int iTrack)
|
||||
if (!pClient)
|
||||
return;
|
||||
|
||||
if (iTrack < -1 || iTrack > 30)
|
||||
if (iTrack < -1 || iTrack >= (int)ARRAYSIZE(g_szMP3trackFileMap))
|
||||
{
|
||||
ALERT(at_console, "TriggerCDAudio - Track %d out of range\n", iTrack);
|
||||
return;
|
||||
@ -642,7 +643,7 @@ void PlayCDTrack(edict_t *pClient, int iTrack)
|
||||
CLIENT_COMMAND(pClient, UTIL_VarArgs("mp3 play %s\n", g_szMP3trackFileMap[iTrack]));
|
||||
#else
|
||||
char string[64];
|
||||
Q_sprintf(string, "cd play %3d\n", iTrack);
|
||||
Q_snprintf(string, sizeof(string), "cd play %3d\n", iTrack);
|
||||
CLIENT_COMMAND(pClient, string);
|
||||
#endif
|
||||
}
|
||||
@ -968,7 +969,7 @@ void CTriggerMultiple::Spawn()
|
||||
|
||||
InitTrigger();
|
||||
|
||||
assert(("trigger_multiple with health", pev->health == 0));
|
||||
DbgAssertMsg(pev->health == 0, "trigger_multiple with health");
|
||||
|
||||
//UTIL_SetOrigin(pev, pev->origin);
|
||||
//SET_MODEL(ENT(pev), STRING(pev->model));
|
||||
@ -993,6 +994,14 @@ void CTriggerMultiple::Spawn()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
void CTriggerMultiple::Restart()
|
||||
{
|
||||
pev->nextthink = -1;
|
||||
Spawn();
|
||||
}
|
||||
#endif
|
||||
|
||||
LINK_ENTITY_TO_CLASS(trigger_once, CTriggerOnce, CCSTriggerOnce)
|
||||
|
||||
void CTriggerOnce::Spawn()
|
||||
@ -1203,7 +1212,7 @@ void CChangeLevel::KeyValue(KeyValueData *pkvd)
|
||||
ALERT(at_error, "Map name '%s' too long (32 chars)\n", pkvd->szValue);
|
||||
}
|
||||
|
||||
Q_strcpy(m_szMapName, pkvd->szValue);
|
||||
Q_strlcpy(m_szMapName, pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "landmark"))
|
||||
@ -1213,7 +1222,7 @@ void CChangeLevel::KeyValue(KeyValueData *pkvd)
|
||||
ALERT(at_error, "Landmark name '%s' too long (32 chars)\n", pkvd->szValue);
|
||||
}
|
||||
|
||||
Q_strcpy(m_szLandmarkName, pkvd->szValue);
|
||||
Q_strlcpy(m_szLandmarkName, pkvd->szValue);
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else if (FStrEq(pkvd->szKeyName, "changetarget"))
|
||||
@ -1345,7 +1354,7 @@ void CChangeLevel::ChangeLevelNow(CBaseEntity *pActivator)
|
||||
}
|
||||
|
||||
// This object will get removed in the call to CHANGE_LEVEL, copy the params into "safe" memory
|
||||
Q_strcpy(st_szNextMap, m_szMapName);
|
||||
Q_strlcpy(st_szNextMap, m_szMapName);
|
||||
|
||||
m_hActivator = pActivator;
|
||||
SUB_UseTargets(pActivator, USE_TOGGLE, 0);
|
||||
@ -1358,7 +1367,7 @@ void CChangeLevel::ChangeLevelNow(CBaseEntity *pActivator)
|
||||
|
||||
if (!FNullEnt(pentLandmark))
|
||||
{
|
||||
Q_strcpy(st_szNextSpot, m_szLandmarkName);
|
||||
Q_strlcpy(st_szNextSpot, m_szLandmarkName);
|
||||
gpGlobals->vecLandmarkOffset = VARS(pentLandmark)->origin;
|
||||
}
|
||||
|
||||
@ -1404,8 +1413,8 @@ int CChangeLevel::AddTransitionToList(LEVELLIST *pLevelList, int listCount, cons
|
||||
}
|
||||
}
|
||||
|
||||
Q_strcpy(pLevelList[listCount].mapName, pMapName);
|
||||
Q_strcpy(pLevelList[listCount].landmarkName, pLandmarkName);
|
||||
Q_strlcpy(pLevelList[listCount].mapName, pMapName);
|
||||
Q_strlcpy(pLevelList[listCount].landmarkName, pLandmarkName);
|
||||
|
||||
pLevelList[listCount].pentLandmark = pentLandmark;
|
||||
pLevelList[listCount].vecLandmarkOrigin = VARS(pentLandmark)->origin;
|
||||
@ -1580,12 +1589,12 @@ NOXREF void NextLevel()
|
||||
{
|
||||
gpGlobals->mapname = ALLOC_STRING("start");
|
||||
pChange = GetClassPtr<CCSChangeLevel>((CChangeLevel *)nullptr);
|
||||
Q_strcpy(pChange->m_szMapName, "start");
|
||||
Q_strlcpy(pChange->m_szMapName, "start");
|
||||
}
|
||||
else
|
||||
pChange = GetClassPtr<CCSChangeLevel>((CChangeLevel *)VARS(pent));
|
||||
|
||||
Q_strcpy(st_szNextMap, pChange->m_szMapName);
|
||||
Q_strlcpy(st_szNextMap, pChange->m_szMapName);
|
||||
g_pGameRules->SetGameOver();
|
||||
|
||||
if (pChange->pev->nextthink < gpGlobals->time)
|
||||
@ -1760,8 +1769,30 @@ void CBaseTrigger::TeleportTouch(CBaseEntity *pOther)
|
||||
|
||||
if (pOther->IsPlayer())
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// If a landmark was specified, offset the player relative to the landmark
|
||||
if (m_iszLandmarkName)
|
||||
{
|
||||
edict_t *pentLandmark = FIND_ENTITY_BY_TARGETNAME(nullptr, STRING(m_iszLandmarkName));
|
||||
|
||||
if (!FNullEnt(pentLandmark))
|
||||
{
|
||||
Vector diff = pevToucher->origin - VARS(pentLandmark)->origin;
|
||||
tmp += diff;
|
||||
tmp.z--; // offset by +1 because -1 will run out of this scope.
|
||||
}
|
||||
else
|
||||
{
|
||||
// fallback, shouldn't happen but anyway.
|
||||
tmp.z -= pOther->pev->mins.z;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// make origin adjustments in case the teleportee is a player. (origin in center, not at feet)
|
||||
tmp.z -= pOther->pev->mins.z;
|
||||
{
|
||||
tmp.z -= pOther->pev->mins.z;
|
||||
}
|
||||
}
|
||||
|
||||
tmp.z++;
|
||||
@ -1814,6 +1845,26 @@ void CTriggerTeleport::Spawn()
|
||||
SetTouch(&CTriggerTeleport::TeleportTouch);
|
||||
}
|
||||
|
||||
void CTriggerTeleport::KeyValue(KeyValueData *pkvd)
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (FStrEq(pkvd->szKeyName, "landmark"))
|
||||
{
|
||||
if (Q_strlen(pkvd->szValue) > 0)
|
||||
{
|
||||
m_iszLandmarkName = ALLOC_STRING(pkvd->szValue);
|
||||
}
|
||||
|
||||
// If empty, handle it in the teleport touch instead
|
||||
pkvd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
CBaseTrigger::KeyValue(pkvd);
|
||||
}
|
||||
}
|
||||
|
||||
LINK_ENTITY_TO_CLASS(info_teleport_destination, CPointEntity, CCSPointEntity)
|
||||
LINK_ENTITY_TO_CLASS(func_buyzone, CBuyZone, CCSBuyZone)
|
||||
|
||||
@ -1976,7 +2027,7 @@ void CEscapeZone::EscapeTouch(CBaseEntity *pOther)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer || FNullEnt(pPlayer->pev))
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (pPlayer->m_iTeam == pEscapee->m_iTeam)
|
||||
|
@ -204,6 +204,11 @@ public:
|
||||
void EXPORT CounterUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void EXPORT ToggleUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
void InitTrigger();
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
// For trigger_teleport TriggerTouch
|
||||
int m_iszLandmarkName = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define SF_TRIGGER_HURT_TARGETONCE BIT(0) // Only fire hurt target once
|
||||
@ -278,6 +283,10 @@ class CTriggerMultiple: public CBaseTrigger
|
||||
{
|
||||
public:
|
||||
virtual void Spawn();
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
virtual void Restart();
|
||||
#endif
|
||||
};
|
||||
|
||||
// Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching
|
||||
@ -393,6 +402,7 @@ class CTriggerTeleport: public CBaseTrigger
|
||||
{
|
||||
public:
|
||||
virtual void Spawn();
|
||||
virtual void KeyValue(KeyValueData *pkvd);
|
||||
};
|
||||
|
||||
class CBuyZone: public CBaseTrigger
|
||||
|
@ -75,7 +75,10 @@ void MonitorTutorStatus()
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (pPlayer && !pPlayer->IsBot())
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (!pPlayer->IsBot())
|
||||
numHumans++;
|
||||
}
|
||||
|
||||
|
@ -68,12 +68,10 @@ void TutorMessageEvent::AddParameter(char *str)
|
||||
TutorMessageEventParam *param = new TutorMessageEventParam;
|
||||
|
||||
param->m_next = nullptr;
|
||||
param->m_data = new char[Q_strlen(str) + 1];
|
||||
param->m_data = CloneString(str);
|
||||
|
||||
if (param->m_data)
|
||||
{
|
||||
Q_strcpy(param->m_data, str);
|
||||
param->m_data[Q_strlen(str)] = '\0';
|
||||
m_numParameters++;
|
||||
|
||||
if (m_paramList)
|
||||
@ -101,11 +99,7 @@ char *TutorMessageEvent::GetNextParameter(char *buf, int buflen)
|
||||
m_numParameters--;
|
||||
m_paramList = param->m_next;
|
||||
|
||||
Q_strncpy(buf, param->m_data, buflen);
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
buf[buflen] = '\0';
|
||||
#endif
|
||||
Q_strlcpy(buf, param->m_data, buflen);
|
||||
|
||||
delete param;
|
||||
return buf;
|
||||
|
@ -213,7 +213,7 @@ void ParseMessageParameters(char *&messageData, TutorMessage *ret)
|
||||
if (!Q_stricmp(token, "String"))
|
||||
{
|
||||
messageData = SharedParse((char *)messageData);
|
||||
ret->m_text = Q_strdup(SharedGetToken());
|
||||
ret->m_text = CloneString(SharedGetToken());
|
||||
}
|
||||
else if (!Q_stricmp(token, "Duration"))
|
||||
{
|
||||
@ -832,7 +832,7 @@ TutorMessageEvent *CCSTutor::CreateTutorMessageEvent(TutorMessageID mid, CBaseEn
|
||||
{
|
||||
numtasks = TheCareerTasks->GetNumRemainingTasks();
|
||||
}
|
||||
Q_sprintf(numLeftStr, "%d", numtasks);
|
||||
Q_snprintf(numLeftStr, sizeof(numLeftStr), "%d", numtasks);
|
||||
event->AddParameter(numLeftStr);
|
||||
break;
|
||||
}
|
||||
@ -2040,7 +2040,11 @@ void CCSTutor::GetNumPlayersAliveOnTeams(int &numT, int &numCT)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (!pPlayer || !pPlayer->IsAlive())
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (!pPlayer->IsAlive())
|
||||
continue;
|
||||
|
||||
switch (pPlayer->m_iTeam)
|
||||
@ -2132,7 +2136,11 @@ void CCSTutor::CheckForBombViewable()
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (pPlayer && pPlayer->m_bHasC4)
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (pPlayer->m_bHasC4)
|
||||
{
|
||||
pBombCarrier = pPlayer;
|
||||
break;
|
||||
@ -2812,14 +2820,13 @@ void CCSTutor::ConstructRecentDeathsList(TeamName team, char *buf, int buflen, T
|
||||
if (!buf || !buflen)
|
||||
return;
|
||||
|
||||
char scratch[32];
|
||||
buf[0] = '\0';
|
||||
int len = 0;
|
||||
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer)
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
// ignore alive players
|
||||
@ -2829,10 +2836,7 @@ void CCSTutor::ConstructRecentDeathsList(TeamName team, char *buf, int buflen, T
|
||||
if (pPlayer->m_iTeam != team)
|
||||
continue;
|
||||
|
||||
Q_strcat(buf, " %n");
|
||||
Q_sprintf(scratch, "%d\n", i);
|
||||
Q_strcat(buf, scratch);
|
||||
|
||||
len += Q_snprintf(&buf[len], buflen - len, " %%n%d\n", i);
|
||||
m_playerDeathInfo[i].m_event = event;
|
||||
}
|
||||
}
|
||||
|
@ -506,7 +506,11 @@ void UTIL_ScreenShake(const Vector ¢er, float amplitude, float frequency, fl
|
||||
for (i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBaseEntity *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (!pPlayer || !(pPlayer->pev->flags & FL_ONGROUND))
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (!(pPlayer->pev->flags & FL_ONGROUND))
|
||||
continue;
|
||||
|
||||
localAmplitude = 0;
|
||||
@ -552,7 +556,10 @@ void UTIL_ScreenFadeBuild(ScreenFade &fade, const Vector &color, float fadeTime,
|
||||
|
||||
void UTIL_ScreenFadeWrite(const ScreenFade &fade, CBaseEntity *pEntity)
|
||||
{
|
||||
if (!pEntity || !pEntity->IsNetClient())
|
||||
if (!UTIL_IsValidPlayer(pEntity))
|
||||
return;
|
||||
|
||||
if (!pEntity->IsNetClient())
|
||||
return;
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgFade, nullptr, pEntity->edict());
|
||||
@ -634,10 +641,11 @@ void UTIL_HudMessageAll(const hudtextparms_t &textparms, const char *pMessage)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBaseEntity *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (pPlayer)
|
||||
{
|
||||
UTIL_HudMessage(pPlayer, textparms, pMessage);
|
||||
}
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
UTIL_HudMessage(pPlayer, textparms, pMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -682,10 +690,7 @@ void UTIL_Log(const char *fmt, ...)
|
||||
Q_vsnprintf(string, sizeof(string), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (Q_strlen(string) < sizeof(string) - 2)
|
||||
Q_strcat(string, "\n");
|
||||
else
|
||||
string[Q_strlen(string) - 1] = '\n';
|
||||
Q_strlcat(string, "\n");
|
||||
|
||||
FILE *fp = fopen("regamedll.log", "at");
|
||||
if (fp)
|
||||
@ -709,10 +714,7 @@ void UTIL_ServerPrint(const char *fmt, ...)
|
||||
Q_vsnprintf(string, sizeof(string), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (Q_strlen(string) < sizeof(string) - 2)
|
||||
Q_strcat(string, "\n");
|
||||
else
|
||||
string[Q_strlen(string) - 1] = '\n';
|
||||
Q_strlcat(string, "\n");
|
||||
|
||||
SERVER_PRINT(string);
|
||||
}
|
||||
@ -730,10 +732,7 @@ void UTIL_PrintConsole(edict_t *pEdict, const char *fmt, ...)
|
||||
Q_vsnprintf(string, sizeof(string), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (Q_strlen(string) < sizeof(string) - 2)
|
||||
Q_strcat(string, "\n");
|
||||
else
|
||||
string[Q_strlen(string) - 1] = '\n';
|
||||
Q_strlcat(string, "\n");
|
||||
|
||||
ClientPrint(pEntity->pev, HUD_PRINTCONSOLE, string);
|
||||
}
|
||||
@ -751,10 +750,7 @@ void UTIL_SayText(edict_t *pEdict, const char *fmt, ...)
|
||||
Q_vsnprintf(string, sizeof(string), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (Q_strlen(string) < sizeof(string) - 2)
|
||||
Q_strcat(string, "\n");
|
||||
else
|
||||
string[Q_strlen(string) - 1] = '\n';
|
||||
Q_strlcat(string, "\n");
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgSayText, nullptr, pEntity->edict());
|
||||
WRITE_BYTE(pEntity->entindex());
|
||||
@ -773,28 +769,28 @@ void UTIL_SayTextAll(const char *pText, CBaseEntity *pEntity)
|
||||
char *UTIL_dtos1(int d)
|
||||
{
|
||||
static char buf[12];
|
||||
Q_sprintf(buf, "%d", d);
|
||||
Q_snprintf(buf, sizeof(buf), "%d", d);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *UTIL_dtos2(int d)
|
||||
{
|
||||
static char buf[12];
|
||||
Q_sprintf(buf, "%d", d);
|
||||
Q_snprintf(buf, sizeof(buf), "%d", d);
|
||||
return buf;
|
||||
}
|
||||
|
||||
NOXREF char *UTIL_dtos3(int d)
|
||||
{
|
||||
static char buf[12];
|
||||
Q_sprintf(buf, "%d", d);
|
||||
Q_snprintf(buf, sizeof(buf), "%d", d);
|
||||
return buf;
|
||||
}
|
||||
|
||||
NOXREF char *UTIL_dtos4(int d)
|
||||
{
|
||||
static char buf[12];
|
||||
Q_sprintf(buf, "%d", d);
|
||||
Q_snprintf(buf, sizeof(buf), "%d", d);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -843,8 +839,11 @@ void UTIL_ShowMessageAll(const char *pString, bool isHint)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBaseEntity *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (pPlayer)
|
||||
UTIL_ShowMessage(pString, pPlayer, isHint);
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
UTIL_ShowMessage(pString, pPlayer, isHint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -980,7 +979,7 @@ char *UTIL_VarArgs(char *format, ...)
|
||||
static char string[1024];
|
||||
|
||||
va_start(argptr, format);
|
||||
vsprintf(string, format, argptr);
|
||||
Q_vsnprintf(string, sizeof(string), format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
return string;
|
||||
@ -1465,7 +1464,7 @@ void UTIL_Remove(CBaseEntity *pEntity)
|
||||
pEntity->pev->targetname = 0;
|
||||
}
|
||||
|
||||
NOXREF BOOL UTIL_IsValidEntity(edict_t *pent)
|
||||
BOOL UTIL_IsValidEntity(edict_t *pent)
|
||||
{
|
||||
if (!pent || pent->free || (pent->v.flags & FL_KILLME))
|
||||
return FALSE;
|
||||
@ -1497,7 +1496,7 @@ void UTIL_RestartOther(const char *szClassname)
|
||||
while ((pEntity = UTIL_FindEntityByClassname(pEntity, szClassname)))
|
||||
{
|
||||
pEntity->Restart();
|
||||
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
FireTargets("game_entity_restart", pEntity, nullptr, USE_TOGGLE, 0.0);
|
||||
#endif
|
||||
@ -1550,7 +1549,7 @@ void UTIL_LogPrintf(const char *fmt, ...)
|
||||
static char string[1024];
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(string, fmt, argptr);
|
||||
Q_vsnprintf(string, sizeof(string), fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
ALERT(at_logged, "%s", string);
|
||||
@ -1569,7 +1568,7 @@ char UTIL_TextureHit(TraceResult *ptr, Vector vecSrc, Vector vecEnd)
|
||||
float rgfl1[3];
|
||||
float rgfl2[3];
|
||||
const char *pTextureName;
|
||||
char szbuffer[64];
|
||||
char szbuffer[MAX_TEXTURENAME_LENGHT];
|
||||
CBaseEntity *pEntity = CBaseEntity::Instance(ptr->pHit);
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
@ -1595,8 +1594,8 @@ char UTIL_TextureHit(TraceResult *ptr, Vector vecSrc, Vector vecEnd)
|
||||
if (*pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ')
|
||||
pTextureName++;
|
||||
|
||||
Q_strcpy(szbuffer, pTextureName);
|
||||
szbuffer[16] = '\0';
|
||||
Q_strlcpy(szbuffer, pTextureName);
|
||||
|
||||
chTextureType = TEXTURETYPE_Find(szbuffer);
|
||||
}
|
||||
else
|
||||
@ -1661,14 +1660,12 @@ int UTIL_ReadFlags(const char *c)
|
||||
// Determine whether bots can be used or not
|
||||
bool UTIL_AreBotsAllowed()
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (g_engfuncs.pfnEngCheckParm == nullptr)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (AreRunningCZero())
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (g_engfuncs.pfnEngCheckParm == nullptr)
|
||||
return false;
|
||||
|
||||
// If they pass in -nobots, don't allow bots. This is for people who host servers, to
|
||||
// allow them to disallow bots to enforce CPU limits.
|
||||
int nobots = ENG_CHECK_PARM("-nobots", nullptr);
|
||||
@ -1688,15 +1685,10 @@ bool UTIL_AreBotsAllowed()
|
||||
return true;
|
||||
}
|
||||
|
||||
// allow the using of bots for CS 1.6
|
||||
int bots = ENG_CHECK_PARM("-bots", nullptr);
|
||||
if (bots)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return cv_bot_enable.value > 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool UTIL_IsBeta()
|
||||
@ -1729,18 +1721,10 @@ bool UTIL_AreHostagesImprov()
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (g_engfuncs.pfnEngCheckParm == nullptr)
|
||||
return false;
|
||||
|
||||
// someday in CS 1.6
|
||||
int improv = ENG_CHECK_PARM("-host-improv", nullptr);
|
||||
if (improv)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return cv_hostage_ai_enable.value > 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int UTIL_GetNumPlayers()
|
||||
@ -1749,15 +1733,27 @@ int UTIL_GetNumPlayers()
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
if (pPlayer)
|
||||
{
|
||||
nNumPlayers++;
|
||||
}
|
||||
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
nNumPlayers++;
|
||||
}
|
||||
|
||||
return nNumPlayers;
|
||||
}
|
||||
|
||||
int UTIL_CountEntities(const char *szName)
|
||||
{
|
||||
int count = 0;
|
||||
CBaseEntity *pEnt = nullptr;
|
||||
|
||||
while ((pEnt = UTIL_FindEntityByClassname(pEnt, szName)))
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool UTIL_IsSpawnPointOccupied(CBaseEntity *pSpot)
|
||||
{
|
||||
if (!pSpot)
|
||||
@ -1808,10 +1804,11 @@ void NORETURN Sys_Error(const char *error, ...)
|
||||
|
||||
CONSOLE_ECHO("FATAL ERROR (shutting down): %s\n", text);
|
||||
|
||||
//TerminateProcess(GetCurrentProcess(), 1);
|
||||
int *null = 0;
|
||||
*null = 0;
|
||||
exit(-1);
|
||||
#if defined(_WIN32)
|
||||
MessageBoxA(NULL, text, "Fatal error", MB_ICONERROR | MB_OK);
|
||||
#endif
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int UTIL_CountPlayersInBrushVolume(bool bOnlyAlive, CBaseEntity *pBrushEntity, int &playersInCount, int &playersOutCount, CPlayerInVolumeAdapter *pAdapter)
|
||||
@ -1825,7 +1822,10 @@ int UTIL_CountPlayersInBrushVolume(bool bOnlyAlive, CBaseEntity *pBrushEntity, i
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (!pPlayer || !pPlayer->IsInWorld())
|
||||
if (!UTIL_IsValidPlayer(pPlayer))
|
||||
continue;
|
||||
|
||||
if (!pPlayer->IsInWorld())
|
||||
continue;
|
||||
|
||||
if (bOnlyAlive && !pPlayer->IsAlive())
|
||||
|
@ -297,6 +297,7 @@ bool UTIL_AreBotsAllowed();
|
||||
bool UTIL_IsBeta();
|
||||
bool UTIL_AreHostagesImprov();
|
||||
int UTIL_GetNumPlayers();
|
||||
int UTIL_CountEntities(const char *szName);
|
||||
bool UTIL_IsSpawnPointOccupied(CBaseEntity *pSpot);
|
||||
void MAKE_STRING_CLASS(const char *str, entvars_t *pev);
|
||||
void NORETURN Sys_Error(const char *error, ...);
|
||||
|
@ -126,7 +126,7 @@ void CFuncVehicle::Blocked(CBaseEntity *pOther)
|
||||
|
||||
float minz = pev->origin.z;
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
float maxz = pev->origin.z + (2 * Q_abs(pev->mins.z - pev->maxs.z));
|
||||
float maxz = pev->origin.z + (2 * Q_abs(pev->mins.z - pev->maxs.z));
|
||||
#else
|
||||
float maxz = pev->origin.z + (2 * Q_abs(int(pev->mins.z - pev->maxs.z)));
|
||||
#endif
|
||||
@ -343,15 +343,20 @@ void CFuncVehicle::CheckTurning()
|
||||
if (pev->speed > 0)
|
||||
{
|
||||
UTIL_TraceLine(m_vFrontRight, m_vFrontRight - (gpGlobals->v_right * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr);
|
||||
|
||||
if (tr.flFraction != 1.0f)
|
||||
{
|
||||
m_iTurnAngle = 1;
|
||||
}
|
||||
}
|
||||
else if (pev->speed < 0)
|
||||
{
|
||||
UTIL_TraceLine(m_vBackLeft, m_vBackLeft + (gpGlobals->v_right * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr);
|
||||
}
|
||||
|
||||
if (tr.flFraction != 1.0f)
|
||||
{
|
||||
m_iTurnAngle = 1;
|
||||
if (tr.flFraction != 1.0f)
|
||||
{
|
||||
m_iTurnAngle = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_iTurnAngle > 0)
|
||||
@ -359,15 +364,20 @@ void CFuncVehicle::CheckTurning()
|
||||
if (pev->speed > 0)
|
||||
{
|
||||
UTIL_TraceLine(m_vFrontLeft, m_vFrontLeft + (gpGlobals->v_right * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr);
|
||||
|
||||
if (tr.flFraction != 1.0f)
|
||||
{
|
||||
m_iTurnAngle = -1;
|
||||
}
|
||||
}
|
||||
else if (pev->speed < 0)
|
||||
{
|
||||
UTIL_TraceLine(m_vBackRight, m_vBackRight - (gpGlobals->v_right * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr);
|
||||
}
|
||||
|
||||
if (tr.flFraction != 1.0f)
|
||||
{
|
||||
m_iTurnAngle = -1;
|
||||
if (tr.flFraction != 1.0f)
|
||||
{
|
||||
m_iTurnAngle = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,36 +74,52 @@ float GetBaseAccuracy(WeaponIdType id)
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
LINK_HOOK_VOID_CHAIN2(ClearMultiDamage)
|
||||
|
||||
// Resets the global multi damage accumulator
|
||||
void ClearMultiDamage()
|
||||
void EXT_FUNC __API_HOOK(ClearMultiDamage)()
|
||||
{
|
||||
gMultiDamage.pEntity = nullptr;
|
||||
gMultiDamage.hEntity = nullptr;
|
||||
gMultiDamage.amount = 0;
|
||||
gMultiDamage.type = 0;
|
||||
}
|
||||
|
||||
LINK_HOOK_VOID_CHAIN(ApplyMultiDamage, (entvars_t *pevInflictor, entvars_t *pevAttacker), pevInflictor, pevAttacker)
|
||||
|
||||
// Inflicts contents of global multi damage register on gMultiDamage.pEntity
|
||||
void ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker)
|
||||
void EXT_FUNC __API_HOOK(ApplyMultiDamage)(entvars_t *pevInflictor, entvars_t *pevAttacker)
|
||||
{
|
||||
if (!gMultiDamage.pEntity)
|
||||
EntityHandle<CBaseEntity> hEnt = gMultiDamage.hEntity;
|
||||
if (!hEnt)
|
||||
return;
|
||||
|
||||
gMultiDamage.pEntity->TakeDamage(pevInflictor, pevAttacker, gMultiDamage.amount, gMultiDamage.type);
|
||||
hEnt->TakeDamage(pevInflictor, pevAttacker, gMultiDamage.amount, gMultiDamage.type);
|
||||
|
||||
// check again, the entity may be removed after taking damage
|
||||
if (hEnt)
|
||||
hEnt->ResetDmgPenetrationLevel();
|
||||
}
|
||||
|
||||
void AddMultiDamage(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType)
|
||||
LINK_HOOK_VOID_CHAIN(AddMultiDamage, (entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType), pevInflictor, pEntity, flDamage, bitsDamageType)
|
||||
|
||||
void EXT_FUNC __API_HOOK(AddMultiDamage)(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType)
|
||||
{
|
||||
if (!pEntity)
|
||||
return;
|
||||
|
||||
gMultiDamage.type |= bitsDamageType;
|
||||
|
||||
if (pEntity != gMultiDamage.pEntity)
|
||||
if (pEntity != gMultiDamage.hEntity)
|
||||
{
|
||||
// UNDONE: wrong attacker!
|
||||
ApplyMultiDamage(pevInflictor, pevInflictor);
|
||||
gMultiDamage.pEntity = pEntity;
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (gMultiDamage.hEntity) // avoid api calls with null default pEntity
|
||||
#endif
|
||||
{
|
||||
// UNDONE: wrong attacker!
|
||||
ApplyMultiDamage(pevInflictor, pevInflictor);
|
||||
}
|
||||
|
||||
gMultiDamage.hEntity = pEntity;
|
||||
gMultiDamage.amount = 0;
|
||||
}
|
||||
|
||||
@ -208,10 +224,16 @@ struct {
|
||||
#endif
|
||||
|
||||
// Precaches the ammo and queues the ammo info for sending to clients
|
||||
void AddAmmoNameToAmmoRegistry(const char *szAmmoname)
|
||||
int AddAmmoNameToAmmoRegistry(const char *szAmmoname)
|
||||
{
|
||||
// string validation
|
||||
if (!szAmmoname || !szAmmoname[0])
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// make sure it's not already in the registry
|
||||
for (int i = 0; i < MAX_AMMO_SLOTS; i++)
|
||||
for (int i = 1; i < MAX_AMMO_SLOTS; i++)
|
||||
{
|
||||
if (!CBasePlayerItem::m_AmmoInfoArray[i].pszName)
|
||||
continue;
|
||||
@ -219,15 +241,15 @@ void AddAmmoNameToAmmoRegistry(const char *szAmmoname)
|
||||
if (!Q_stricmp(CBasePlayerItem::m_AmmoInfoArray[i].pszName, szAmmoname))
|
||||
{
|
||||
// ammo already in registry, just quite
|
||||
return;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
giAmmoIndex++;
|
||||
assert(giAmmoIndex < MAX_AMMO_SLOTS);
|
||||
DbgAssert(giAmmoIndex < MAX_AMMO_SLOTS);
|
||||
|
||||
if (giAmmoIndex >= MAX_AMMO_SLOTS)
|
||||
giAmmoIndex = 0;
|
||||
giAmmoIndex = 1;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
for (auto& ammo : ammoIndex)
|
||||
@ -246,6 +268,8 @@ void AddAmmoNameToAmmoRegistry(const char *szAmmoname)
|
||||
|
||||
// Yes, this info is redundant
|
||||
CBasePlayerItem::m_AmmoInfoArray[giAmmoIndex].iId = giAmmoIndex;
|
||||
|
||||
return giAmmoIndex;
|
||||
}
|
||||
|
||||
// Precaches the weapon and queues the weapon info for sending to clients
|
||||
@ -269,15 +293,8 @@ void UTIL_PrecacheOtherWeapon(const char *szClassname)
|
||||
{
|
||||
CBasePlayerItem::m_ItemInfoArray[info.iId] = info;
|
||||
|
||||
if (info.pszAmmo1 && info.pszAmmo1[0] != '\0')
|
||||
{
|
||||
AddAmmoNameToAmmoRegistry(info.pszAmmo1);
|
||||
}
|
||||
|
||||
if (info.pszAmmo2 && info.pszAmmo2[0] != '\0')
|
||||
{
|
||||
AddAmmoNameToAmmoRegistry(info.pszAmmo2);
|
||||
}
|
||||
AddAmmoNameToAmmoRegistry(info.pszAmmo1);
|
||||
AddAmmoNameToAmmoRegistry(info.pszAmmo2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,7 +518,11 @@ void CBasePlayerItem::Materialize()
|
||||
UTIL_SetOrigin(pev, pev->origin);
|
||||
SetTouch(&CBasePlayerItem::DefaultTouch);
|
||||
|
||||
if (g_pGameRules->IsMultiplayer())
|
||||
if (g_pGameRules->IsMultiplayer()
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
&& g_pGameRules->WeaponShouldRespawn(this) == GR_WEAPON_RESPAWN_NO
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (!CanDrop())
|
||||
{
|
||||
@ -538,8 +559,12 @@ void CBasePlayerItem::CheckRespawn()
|
||||
{
|
||||
switch (g_pGameRules->WeaponShouldRespawn(this))
|
||||
{
|
||||
case GR_WEAPON_RESPAWN_YES:
|
||||
case GR_WEAPON_RESPAWN_YES: {
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
Respawn();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
case GR_WEAPON_RESPAWN_NO:
|
||||
return;
|
||||
}
|
||||
@ -558,6 +583,10 @@ CBaseEntity *CBasePlayerItem::Respawn()
|
||||
// invisible for now
|
||||
pNewWeapon->pev->effects |= EF_NODRAW;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
pNewWeapon->pev->spawnflags &= ~SF_NORESPAWN;
|
||||
#endif
|
||||
|
||||
// no touch
|
||||
pNewWeapon->SetTouch(nullptr);
|
||||
pNewWeapon->SetThink(&CBasePlayerItem::AttemptToMaterialize);
|
||||
@ -589,11 +618,17 @@ void CBasePlayerItem::DefaultTouch(CBaseEntity *pOther)
|
||||
CBasePlayer *pPlayer = static_cast<CBasePlayer *>(pOther);
|
||||
|
||||
if (pPlayer->m_bIsVIP
|
||||
&& m_iId != WEAPON_USP
|
||||
&&
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
m_iId != WEAPON_USP
|
||||
&& m_iId != WEAPON_GLOCK18
|
||||
&& m_iId != WEAPON_P228
|
||||
&& m_iId != WEAPON_DEAGLE
|
||||
&& m_iId != WEAPON_KNIFE)
|
||||
&& m_iId != WEAPON_KNIFE
|
||||
#else
|
||||
!IsSecondaryWeapon(m_iId)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -623,11 +658,11 @@ void CBasePlayerWeapon::SetPlayerShieldAnim()
|
||||
|
||||
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
|
||||
{
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shield");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shield");
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgun");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgun");
|
||||
}
|
||||
}
|
||||
|
||||
@ -637,7 +672,7 @@ void CBasePlayerWeapon::ResetPlayerShieldAnim()
|
||||
{
|
||||
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
|
||||
{
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgun");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgun");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -668,7 +703,7 @@ bool CBasePlayerWeapon::ShieldSecondaryFire(int iUpAnim, int iDownAnim)
|
||||
{
|
||||
m_iWeaponState &= ~WPNSTATE_SHIELD_DRAWN;
|
||||
SendWeaponAnim(iDownAnim, UseDecrement() != FALSE);
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgun");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgun");
|
||||
m_fMaxSpeed = 250.0f;
|
||||
m_pPlayer->m_bShieldDrawn = false;
|
||||
}
|
||||
@ -676,7 +711,7 @@ bool CBasePlayerWeapon::ShieldSecondaryFire(int iUpAnim, int iDownAnim)
|
||||
{
|
||||
m_iWeaponState |= WPNSTATE_SHIELD_DRAWN;
|
||||
SendWeaponAnim(iUpAnim, UseDecrement() != FALSE);
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shielded");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shielded");
|
||||
m_fMaxSpeed = 180.0f;
|
||||
m_pPlayer->m_bShieldDrawn = true;
|
||||
}
|
||||
@ -691,8 +726,45 @@ bool CBasePlayerWeapon::ShieldSecondaryFire(int iUpAnim, int iDownAnim)
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBasePlayerWeapon::KickBack(float up_base, float lateral_base, float up_modifier, float lateral_modifier, float up_max, float lateral_max, int direction_change)
|
||||
LINK_HOOK_CLASS_VOID_CHAIN(CBasePlayerWeapon, KickBack, (float up_base, float lateral_base, float up_modifier, float lateral_modifier, float up_max, float lateral_max, int direction_change), up_base, lateral_base, up_modifier, lateral_modifier, up_max, lateral_max, direction_change)
|
||||
|
||||
void EXT_FUNC CBasePlayerWeapon::__API_HOOK(KickBack)(float up_base, float lateral_base, float up_modifier, float lateral_modifier, float up_max, float lateral_max, int direction_change)
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
real_t flKickUp = up_base;
|
||||
float flKickLateral = lateral_base;
|
||||
|
||||
if (m_iShotsFired > 1) // consider == 0 case
|
||||
{
|
||||
flKickUp += m_iShotsFired * up_modifier;
|
||||
flKickLateral += m_iShotsFired * lateral_modifier;
|
||||
}
|
||||
|
||||
if (up_max == 0.0f) // boundaryless vertical kick
|
||||
{
|
||||
m_pPlayer->pev->punchangle.x -= flKickUp;
|
||||
}
|
||||
else if (m_pPlayer->pev->punchangle.x > -up_max) // do not kick when already out of boundaries
|
||||
{
|
||||
m_pPlayer->pev->punchangle.x = Q_max<real_t>(m_pPlayer->pev->punchangle.x - flKickUp, -up_max);
|
||||
}
|
||||
|
||||
if (lateral_max == 0.0f) // boundaryless horizontal kick
|
||||
{
|
||||
m_pPlayer->pev->punchangle.y += flKickLateral * (m_iDirection * 2 - 1);
|
||||
}
|
||||
else if (Q_fabs(m_pPlayer->pev->punchangle.y) < lateral_max) // do not kick when already out of boundaries
|
||||
{
|
||||
m_pPlayer->pev->punchangle.y = (m_iDirection == 1) ?
|
||||
Q_min(m_pPlayer->pev->punchangle.y + flKickLateral, lateral_max) :
|
||||
Q_max(m_pPlayer->pev->punchangle.y - flKickLateral, -lateral_max);
|
||||
}
|
||||
|
||||
if (direction_change > 0 && !RANDOM_LONG(0, direction_change)) // be sure to not waste RNG consumption
|
||||
{
|
||||
m_iDirection = !m_iDirection;
|
||||
}
|
||||
#else
|
||||
real_t flKickUp;
|
||||
float flKickLateral;
|
||||
|
||||
@ -733,6 +805,7 @@ void CBasePlayerWeapon::KickBack(float up_base, float lateral_base, float up_mod
|
||||
{
|
||||
m_iDirection = !m_iDirection;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL bIsGlock)
|
||||
@ -758,9 +831,15 @@ void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL bI
|
||||
flag = 0;
|
||||
#endif
|
||||
|
||||
#ifdef REGAMEDLL_API
|
||||
float flBaseDamage = CSPlayerWeapon()->m_flBaseDamage;
|
||||
#else
|
||||
float flBaseDamage = bIsGlock ? GLOCK18_DAMAGE : FAMAS_DAMAGE;
|
||||
#endif
|
||||
|
||||
if (bIsGlock)
|
||||
{
|
||||
vecDir = m_pPlayer->FireBullets3(vecSrc, gpGlobals->v_forward, 0.05, 8192, 1, BULLET_PLAYER_9MM, 18, 0.9, m_pPlayer->pev, true, m_pPlayer->random_seed);
|
||||
vecDir = m_pPlayer->FireBullets3(vecSrc, gpGlobals->v_forward, 0.05, 8192, 1, BULLET_PLAYER_9MM, flBaseDamage, 0.9, m_pPlayer->pev, true, m_pPlayer->random_seed);
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
--m_pPlayer->ammo_9mm;
|
||||
#endif
|
||||
@ -769,8 +848,7 @@ void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL bI
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
vecDir = m_pPlayer->FireBullets3(vecSrc, gpGlobals->v_forward, m_fBurstSpread, 8192, 2, BULLET_PLAYER_556MM, 30, 0.96, m_pPlayer->pev, false, m_pPlayer->random_seed);
|
||||
vecDir = m_pPlayer->FireBullets3(vecSrc, gpGlobals->v_forward, m_fBurstSpread, 8192, 2, BULLET_PLAYER_556MM, flBaseDamage, 0.96, m_pPlayer->pev, false, m_pPlayer->random_seed);
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
--m_pPlayer->ammo_556nato;
|
||||
#endif
|
||||
@ -814,18 +892,26 @@ BOOL CanAttack(float attack_time, float curtime, BOOL isPredicted)
|
||||
|
||||
bool CBasePlayerWeapon::HasSecondaryAttack()
|
||||
{
|
||||
#ifdef REGAMEDLL_API
|
||||
if (CSPlayerWeapon()->m_iStateSecondaryAttack != WEAPON_SECONDARY_ATTACK_NONE)
|
||||
{
|
||||
switch (CSPlayerWeapon()->m_iStateSecondaryAttack)
|
||||
{
|
||||
case WEAPON_SECONDARY_ATTACK_SET:
|
||||
return true;
|
||||
case WEAPON_SECONDARY_ATTACK_BLOCK:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_pPlayer && m_pPlayer->HasShield())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_API
|
||||
if (CSPlayerWeapon()->m_bHasSecondaryAttack)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (m_iId)
|
||||
{
|
||||
case WEAPON_AK47:
|
||||
@ -888,7 +974,9 @@ void CBasePlayerWeapon::HandleInfiniteAmmo()
|
||||
}
|
||||
}
|
||||
|
||||
void CBasePlayerWeapon::ItemPostFrame()
|
||||
LINK_HOOK_CLASS_VOID_CHAIN2(CBasePlayerWeapon, ItemPostFrame)
|
||||
|
||||
void EXT_FUNC CBasePlayerWeapon::__API_HOOK(ItemPostFrame)()
|
||||
{
|
||||
int usableButtons = m_pPlayer->pev->button;
|
||||
|
||||
@ -1109,8 +1197,10 @@ void CBasePlayerWeapon::ItemPostFrame()
|
||||
}
|
||||
}
|
||||
|
||||
void CBasePlayerItem::DestroyItem()
|
||||
bool CBasePlayerItem::DestroyItem()
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (m_pPlayer)
|
||||
{
|
||||
// if attached to a player, remove.
|
||||
@ -1118,18 +1208,31 @@ void CBasePlayerItem::DestroyItem()
|
||||
{
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (m_iId == WEAPON_C4) {
|
||||
m_pPlayer->m_bHasC4 = false;
|
||||
m_pPlayer->pev->body = 0;
|
||||
m_pPlayer->SetBombIcon(FALSE);
|
||||
m_pPlayer->SetProgressBarTime(0);
|
||||
}
|
||||
|
||||
m_pPlayer->pev->weapons &= ~(1 << m_iId);
|
||||
|
||||
// No more weapon
|
||||
if ((m_pPlayer->pev->weapons & ~(1 << WEAPON_SUIT)) == 0) {
|
||||
m_pPlayer->m_iHideHUD |= HIDEHUD_WEAPONS;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_pPlayer->m_rgpPlayerItems[PRIMARY_WEAPON_SLOT]) {
|
||||
m_pPlayer->m_bHasPrimary = false;
|
||||
}
|
||||
#endif
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
Kill();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
int CBasePlayerItem::AddToPlayer(CBasePlayer *pPlayer)
|
||||
@ -1195,8 +1298,6 @@ void CBasePlayerWeapon::Spawn()
|
||||
if (GetItemInfo(&info)) {
|
||||
CSPlayerItem()->SetItemInfo(&info);
|
||||
}
|
||||
|
||||
CSPlayerWeapon()->m_bHasSecondaryAttack = HasSecondaryAttack();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1222,8 +1323,18 @@ int CBasePlayerWeapon::AddToPlayer(CBasePlayer *pPlayer)
|
||||
if (!m_iPrimaryAmmoType)
|
||||
{
|
||||
m_iPrimaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo1());
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
m_iSecondaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo2());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
// (3rd party support) if someone updates (or screws) the secondary ammo type later
|
||||
if (!m_iSecondaryAmmoType)
|
||||
{
|
||||
m_iSecondaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo2());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (AddWeapon())
|
||||
{
|
||||
@ -1279,7 +1390,9 @@ int CBasePlayerWeapon::UpdateClientData(CBasePlayer *pPlayer)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CBasePlayerWeapon::SendWeaponAnim(int iAnim, int skiplocal)
|
||||
LINK_HOOK_CLASS_VOID_CHAIN(CBasePlayerWeapon, SendWeaponAnim, (int iAnim, int skiplocal), iAnim, skiplocal)
|
||||
|
||||
void EXT_FUNC CBasePlayerWeapon::__API_HOOK(SendWeaponAnim)(int iAnim, int skiplocal)
|
||||
{
|
||||
m_pPlayer->pev->weaponanim = iAnim;
|
||||
|
||||
@ -1384,7 +1497,7 @@ BOOL EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultDeploy)(char *szViewModel, ch
|
||||
m_pPlayer->pev->weaponmodel = MAKE_STRING(szWeaponModel);
|
||||
#endif
|
||||
model_name = m_pPlayer->pev->viewmodel;
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, szAnimExt);
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, szAnimExt);
|
||||
SendWeaponAnim(iAnim, skiplocal);
|
||||
|
||||
m_pPlayer->m_flNextAttack = 0.75f;
|
||||
@ -1405,9 +1518,12 @@ void CBasePlayerWeapon::ReloadSound()
|
||||
CBasePlayer *pPlayer = nullptr;
|
||||
while ((pPlayer = UTIL_FindEntityByClassname(pPlayer, "player")))
|
||||
{
|
||||
if (pPlayer->IsDormant())
|
||||
if (FNullEnt(pPlayer->edict()))
|
||||
break;
|
||||
|
||||
if (pPlayer->IsDormant())
|
||||
continue;
|
||||
|
||||
if (pPlayer == m_pPlayer)
|
||||
continue;
|
||||
|
||||
@ -1548,7 +1664,11 @@ int CBasePlayerWeapon::PrimaryAmmoIndex()
|
||||
|
||||
int CBasePlayerWeapon::SecondaryAmmoIndex()
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
return m_iSecondaryAmmoType;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CBasePlayerWeapon::Holster(int skiplocal)
|
||||
@ -1557,6 +1677,10 @@ void CBasePlayerWeapon::Holster(int skiplocal)
|
||||
m_fInReload = FALSE;
|
||||
m_pPlayer->pev->viewmodel = 0;
|
||||
m_pPlayer->pev->weaponmodel = 0;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
m_fInSpecialReload = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// called by the new item with the existing item as parameter
|
||||
@ -1578,7 +1702,7 @@ int CBasePlayerWeapon::ExtractAmmo(CBasePlayerWeapon *pWeapon)
|
||||
|
||||
if (pszAmmo2())
|
||||
{
|
||||
res = AddSecondaryAmmo(0, (char *)pszAmmo2(), iMaxAmmo2());
|
||||
res = pWeapon->AddSecondaryAmmo(0, (char *)pszAmmo2(), iMaxAmmo2());
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -1793,6 +1917,91 @@ void CWeaponBox::Kill()
|
||||
UTIL_Remove(this);
|
||||
}
|
||||
|
||||
bool CWeaponBox::GiveAmmoToPlayer(CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon, int iCurrentAmmo, const char *pszAmmo, int iMaxAmmo, CBasePlayerItem **pGivenItem)
|
||||
{
|
||||
if (iCurrentAmmo >= iMaxAmmo)
|
||||
return false; // can't pickup more, these ammo are full in backpack
|
||||
|
||||
// If already have a weapon in backpack, just refill ammo for it
|
||||
int iAmmoIndex = GetAmmoIndex(pszAmmo);
|
||||
if (iAmmoIndex > 0)
|
||||
{
|
||||
// How many weapon ammo can pick up?
|
||||
int iAmmoPickup = min(m_rgAmmo[iAmmoIndex], iMaxAmmo - iCurrentAmmo);
|
||||
if (iAmmoPickup > 0)
|
||||
{
|
||||
if (iCurrentAmmo == 0 && !(pPlayer->pev->weapons & (1<<pWeapon->m_iId)) && (pWeapon->iFlags() & ITEM_FLAG_EXHAUSTIBLE))
|
||||
{
|
||||
if (m_rgAmmo[iAmmoIndex] > iMaxAmmo)
|
||||
{
|
||||
// If ammo capacity of the dropped weapon exceeds the player's backpack capacity,
|
||||
// make a copy of dropped weapon and give it to the player
|
||||
CBasePlayerItem *copyItem = (CBasePlayerItem *)pPlayer->GiveCopyItem(pWeapon);
|
||||
if (copyItem)
|
||||
{
|
||||
// The cloned weapon must inherit properties from a dropped weapon, such as Item Info
|
||||
#ifdef REGAMEDLL_API
|
||||
ItemInfo info;
|
||||
if (pWeapon->CSPlayerItem()->GetItemInfo(&info))
|
||||
copyItem->CSPlayerItem()->SetItemInfo(&info);
|
||||
#endif
|
||||
m_rgAmmo[iAmmoIndex]--;
|
||||
iAmmoPickup--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no weapon in backpack, then issue weapon
|
||||
if (pPlayer->AddPlayerItem(pWeapon))
|
||||
{
|
||||
pWeapon->AttachToPlayer(pPlayer);
|
||||
if (pGivenItem) *pGivenItem = pWeapon;
|
||||
}
|
||||
|
||||
// unlink this weapon from the box
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(iAmmoPickup != 0);
|
||||
Assert(m_rgAmmo[iAmmoIndex] != 0);
|
||||
|
||||
if (!FStringNull(m_rgiszAmmo[iAmmoIndex]) &&
|
||||
pPlayer->GiveAmmo(iAmmoPickup, STRING(m_rgiszAmmo[iAmmoIndex]), iMaxAmmo) != -1)
|
||||
{
|
||||
m_rgAmmo[iAmmoIndex] -= iAmmoPickup;
|
||||
|
||||
if (m_rgAmmo[iAmmoIndex] < 0)
|
||||
m_rgAmmo[iAmmoIndex] = 0;
|
||||
|
||||
EMIT_SOUND(pPlayer->edict(), CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
|
||||
// ammo exhausted, remove this weapon
|
||||
if (m_rgAmmo[iAmmoIndex] <= 0)
|
||||
{
|
||||
pWeapon->Kill();
|
||||
|
||||
// unlink this weapon from the box
|
||||
return true;
|
||||
}
|
||||
|
||||
// ammo has not been exhausted yet, keep this weapon in weaponbox
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no weapon in backpack, then issue weapon
|
||||
if (pPlayer->AddPlayerItem(pWeapon))
|
||||
{
|
||||
pWeapon->AttachToPlayer(pPlayer);
|
||||
if (pGivenItem) *pGivenItem = pWeapon;
|
||||
}
|
||||
|
||||
// unlink this weapon from the box
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to add my contents to the toucher if the toucher is a player.
|
||||
void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
{
|
||||
@ -1821,7 +2030,12 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
pPlayer->OnTouchingWeapon(this);
|
||||
|
||||
bool bRemove = true;
|
||||
bool bEmitSound = false;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
CBasePlayerItem *givenItem = nullptr;
|
||||
#else
|
||||
bool givenItem = false;
|
||||
#endif
|
||||
|
||||
// go through my weapons and try to give the usable ones to the player.
|
||||
// it's important the the player be given ammo first, so the weapons code doesn't refuse
|
||||
@ -1831,6 +2045,7 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
if (!m_rgpPlayerItems[i])
|
||||
continue;
|
||||
|
||||
CBasePlayerItem *pPrev = NULL;
|
||||
CBasePlayerItem *pItem = m_rgpPlayerItems[i];
|
||||
|
||||
// have at least one weapon in this slot
|
||||
@ -1881,8 +2096,8 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
MESSAGE_END();
|
||||
|
||||
pPlayer->m_bHasC4 = true;
|
||||
pPlayer->SetBombIcon(FALSE);
|
||||
pPlayer->pev->body = 1;
|
||||
pPlayer->SetBombIcon(FALSE);
|
||||
|
||||
CBaseEntity *pEntity = nullptr;
|
||||
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
|
||||
@ -1893,7 +2108,7 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
if (!pEntity->IsPlayer())
|
||||
continue;
|
||||
|
||||
if (pEntity->pev->flags == FL_DORMANT)
|
||||
if (pEntity->IsDormant())
|
||||
continue;
|
||||
|
||||
CBasePlayer *pTempPlayer = GetClassPtr<CCSPlayer>((CBasePlayer *)pEntity->pev);
|
||||
@ -1927,44 +2142,38 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
}
|
||||
else if (i == GRENADE_SLOT)
|
||||
{
|
||||
CBasePlayerWeapon *pGrenade = static_cast<CBasePlayerWeapon *>(m_rgpPlayerItems[i]);
|
||||
CBasePlayerWeapon *pGrenade = static_cast<CBasePlayerWeapon *>(pItem);
|
||||
if (pGrenade && pGrenade->IsWeapon())
|
||||
{
|
||||
int playerGrenades = pPlayer->m_rgAmmo[pGrenade->m_iPrimaryAmmoType];
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
// sorry for hardcode :(
|
||||
const int boxAmmoSlot = 1;
|
||||
CBasePlayerItem *pNext = pItem->m_pNext;
|
||||
|
||||
if (playerGrenades < pGrenade->iMaxAmmo1())
|
||||
// Determine the max ammo capacity for the picked-up grenade
|
||||
int iMaxPickupAmmo = pGrenade->iMaxAmmo1();
|
||||
|
||||
// If the player already has the same weapon in inventory,
|
||||
// prioritize the max ammo capacity value over the one from the dropped weapon
|
||||
// When the pickup occurs, ammo will be granted up to
|
||||
// the max ammo capacity of the weapon currently held by the player
|
||||
CBasePlayerItem *pInventoryItem = (CBasePlayerItem *)pPlayer->GetItemById((WeaponIdType)pGrenade->m_iId);
|
||||
if (pInventoryItem && !Q_stricmp(pInventoryItem->pszAmmo1(), pGrenade->pszAmmo1()))
|
||||
iMaxPickupAmmo = pInventoryItem->iMaxAmmo1();
|
||||
|
||||
// Pickup grenade item or refill ammo
|
||||
if (GiveAmmoToPlayer(pPlayer, pGrenade,
|
||||
playerGrenades, pGrenade->pszAmmo1(), iMaxPickupAmmo, &givenItem))
|
||||
{
|
||||
if (m_rgAmmo[boxAmmoSlot] > 1 && playerGrenades > 0)
|
||||
{
|
||||
if (!FStringNull(m_rgiszAmmo[boxAmmoSlot])
|
||||
&& pPlayer->GiveAmmo(1, STRING(m_rgiszAmmo[boxAmmoSlot]), pGrenade->iMaxAmmo1()) != -1)
|
||||
{
|
||||
m_rgAmmo[boxAmmoSlot]--;
|
||||
|
||||
EMIT_SOUND(pPlayer->edict(), CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
// unlink this weapon from the box
|
||||
if (pPrev)
|
||||
pPrev->m_pNext = pItem = pNext;
|
||||
else
|
||||
{
|
||||
auto pNext = m_rgpPlayerItems[i]->m_pNext;
|
||||
|
||||
if (pPlayer->AddPlayerItem(pItem))
|
||||
{
|
||||
pItem->AttachToPlayer(pPlayer);
|
||||
bEmitSound = true;
|
||||
}
|
||||
|
||||
// unlink this weapon from the box
|
||||
m_rgpPlayerItems[i] = pItem = pNext;
|
||||
continue;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
|
||||
int maxGrenades = 0;
|
||||
const char *grenadeName = nullptr;
|
||||
|
||||
@ -1992,7 +2201,7 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
// there we will see only get one grenade. Next step - pick it up, do check again `entity_dump`,
|
||||
// but this time we'll see them x2.
|
||||
|
||||
bEmitSound = true;
|
||||
givenItem = true;
|
||||
pPlayer->GiveNamedItem(grenadeName);
|
||||
|
||||
// unlink this weapon from the box
|
||||
@ -2010,20 +2219,30 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
}
|
||||
else
|
||||
{
|
||||
auto pNext = m_rgpPlayerItems[i]->m_pNext;
|
||||
CBasePlayerItem *pNext = pItem->m_pNext;
|
||||
|
||||
if (pPlayer->AddPlayerItem(pItem))
|
||||
{
|
||||
pItem->AttachToPlayer(pPlayer);
|
||||
bEmitSound = true;
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
givenItem = pItem;
|
||||
#else
|
||||
givenItem = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// unlink this weapon from the box
|
||||
m_rgpPlayerItems[i] = pItem = pNext;
|
||||
if (pPrev)
|
||||
pPrev->m_pNext = pNext;
|
||||
else
|
||||
m_rgpPlayerItems[i] = pItem = pNext;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
bRemove = false;
|
||||
pItem = m_rgpPlayerItems[i]->m_pNext;
|
||||
pPrev = pItem;
|
||||
pItem = pItem->m_pNext;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2034,13 +2253,18 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
{
|
||||
if (!FStringNull(m_rgiszAmmo[n]))
|
||||
{
|
||||
// there's some ammo of this type.
|
||||
#ifndef REGAMEDLL_ADD
|
||||
pPlayer->GiveAmmo(m_rgAmmo[n], (char *)STRING(m_rgiszAmmo[n]), MaxAmmoCarry(m_rgiszAmmo[n]));
|
||||
// there's some ammo of this type
|
||||
if (m_rgAmmo[n] > 0)
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
int iMaxAmmo = m_rgAmmo[n];
|
||||
#else
|
||||
pPlayer->GiveAmmo(m_rgAmmo[n], STRING(m_rgiszAmmo[n]), m_rgAmmo[n]);
|
||||
int iMaxAmmo = MaxAmmoCarry(m_rgiszAmmo[n]);
|
||||
#endif
|
||||
|
||||
pPlayer->GiveAmmo(m_rgAmmo[n], STRING(m_rgiszAmmo[n]), iMaxAmmo);
|
||||
}
|
||||
|
||||
// now empty the ammo from the weaponbox since we just gave it to the player
|
||||
m_rgiszAmmo[n] = iStringNull;
|
||||
m_rgAmmo[n] = 0;
|
||||
@ -2048,9 +2272,21 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
|
||||
}
|
||||
}
|
||||
|
||||
if (bEmitSound)
|
||||
if (givenItem)
|
||||
{
|
||||
EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM);
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
// BUGBUG: weaponbox links gun to player, then ammo is given
|
||||
// so FShouldSwitchWeapon's CanHolster (which checks ammo) check inside AddPlayerItem
|
||||
// return FALSE, causing an unarmed player to not deploy any weaponbox grenade
|
||||
if (pPlayer->m_pActiveItem != givenItem && CSGameRules()->FShouldSwitchWeapon(pPlayer, givenItem))
|
||||
{
|
||||
// This re-check is done after ammo is given
|
||||
// so it ensures player properly deploys grenade from floor
|
||||
pPlayer->SwitchWeapon(givenItem);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bRemove)
|
||||
@ -2168,6 +2404,24 @@ int CWeaponBox::GiveAmmo(int iCount, char *szName, int iMax, int *pIndex)
|
||||
return i;
|
||||
}
|
||||
|
||||
int CWeaponBox::GetAmmoIndex(const char *psz) const
|
||||
{
|
||||
if (!psz)
|
||||
return -1;
|
||||
|
||||
int i;
|
||||
for (i = 1; i < MAX_AMMO_SLOTS; i++)
|
||||
{
|
||||
if (FStringNull(m_rgiszAmmo[i]))
|
||||
continue;
|
||||
|
||||
if (!Q_stricmp(STRING(m_rgiszAmmo[i]), psz))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Is a weapon of this type already packed in this box?
|
||||
BOOL CWeaponBox::HasWeapon(CBasePlayerItem *pCheckItem)
|
||||
{
|
||||
@ -2638,3 +2892,4 @@ int CBasePlayerItem::iFlags() const
|
||||
{
|
||||
return m_ItemInfoEx.iFlags;
|
||||
}
|
||||
|
||||
|
@ -35,12 +35,16 @@ const float MAX_DIST_RELOAD_SOUND = 512.0f;
|
||||
|
||||
#define MAX_WEAPONS 32
|
||||
|
||||
#define ITEM_FLAG_SELECTONEMPTY BIT(0)
|
||||
#define ITEM_FLAG_NOAUTORELOAD BIT(1)
|
||||
#define ITEM_FLAG_NOAUTOSWITCHEMPTY BIT(2)
|
||||
#define ITEM_FLAG_LIMITINWORLD BIT(3)
|
||||
#define ITEM_FLAG_EXHAUSTIBLE BIT(4) // A player can totally exhaust their ammo supply and lose this weapon
|
||||
#define ITEM_FLAG_NOFIREUNDERWATER BIT(5)
|
||||
#define ITEM_FLAG_SELECTONEMPTY BIT(0)
|
||||
#define ITEM_FLAG_NOAUTORELOAD BIT(1)
|
||||
#define ITEM_FLAG_NOAUTOSWITCHEMPTY BIT(2)
|
||||
#define ITEM_FLAG_LIMITINWORLD BIT(3)
|
||||
#define ITEM_FLAG_EXHAUSTIBLE BIT(4) // A player can totally exhaust their ammo supply and lose this weapon
|
||||
#define ITEM_FLAG_NOFIREUNDERWATER BIT(5)
|
||||
#define ITEM_FLAG_EXHAUST_SECONDARYAMMO BIT(6) // A player will exhaust weapon's secondary ammo supply if dropped (ITEM_FLAG_EXHAUSTIBLE does both)
|
||||
|
||||
// if someone has an idea for another flag pack it here, so client prediction will not be screwed (or something) if PLAY_GAMEDLL is defined
|
||||
#define ITEM_FLAG_CUSTOM (ITEM_FLAG_NOFIREUNDERWATER | ITEM_FLAG_EXHAUST_SECONDARYAMMO)
|
||||
|
||||
#define WEAPON_IS_ONTARGET 0x40
|
||||
|
||||
@ -129,7 +133,7 @@ struct AmmoInfo
|
||||
|
||||
struct MULTIDAMAGE
|
||||
{
|
||||
CBaseEntity *pEntity;
|
||||
EntityHandle<CBaseEntity> hEntity;
|
||||
float amount;
|
||||
int type;
|
||||
};
|
||||
@ -296,7 +300,7 @@ public:
|
||||
virtual int iItemSlot() { return 0; } // return 0 to MAX_ITEMS_SLOTS, used in hud
|
||||
|
||||
public:
|
||||
void EXPORT DestroyItem();
|
||||
bool EXPORT DestroyItem();
|
||||
void EXPORT DefaultTouch(CBaseEntity *pOther);
|
||||
void EXPORT FallThink();
|
||||
void EXPORT Materialize();
|
||||
@ -403,6 +407,9 @@ public:
|
||||
BOOL DefaultDeploy_OrigFunc(char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal);
|
||||
BOOL DefaultReload_OrigFunc(int iClipSize, int iAnim, float fDelay);
|
||||
bool DefaultShotgunReload_OrigFunc(int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1, const char *pszReloadSound2);
|
||||
void KickBack_OrigFunc(float up_base, float lateral_base, float up_modifier, float lateral_modifier, float up_max, float lateral_max, int direction_change);
|
||||
void SendWeaponAnim_OrigFunc(int iAnim, int skiplocal);
|
||||
void ItemPostFrame_OrigFunc();
|
||||
|
||||
CCSPlayerWeapon *CSPlayerWeapon() const;
|
||||
#endif
|
||||
@ -470,6 +477,9 @@ public:
|
||||
public:
|
||||
BOOL IsEmpty();
|
||||
int GiveAmmo(int iCount, char *szName, int iMax, int *pIndex = nullptr);
|
||||
int GetAmmoIndex(const char *psz) const;
|
||||
bool GiveAmmoToPlayer(CBasePlayer *pPlayer, CBasePlayerWeapon *pWeapon,
|
||||
int iCurrentAmmo, const char *pszAmmo, int iMaxAmmo, CBasePlayerItem **pGivenItem = NULL);
|
||||
|
||||
void EXPORT Kill();
|
||||
void EXPORT BombThink();
|
||||
@ -534,7 +544,7 @@ enum usp_shield_e
|
||||
USP_SHIELD_SHOOT_EMPTY,
|
||||
USP_SHIELD_RELOAD,
|
||||
USP_SHIELD_DRAW,
|
||||
USP_SHIELD_UP_IDLE,
|
||||
USP_SHIELD_IDLE_UP,
|
||||
USP_SHIELD_UP,
|
||||
USP_SHIELD_DOWN,
|
||||
};
|
||||
@ -900,6 +910,19 @@ enum deagle_e
|
||||
DEAGLE_DRAW,
|
||||
};
|
||||
|
||||
enum deagle_shield_e
|
||||
{
|
||||
DEAGLE_SHIELD_IDLE1,
|
||||
DEAGLE_SHIELD_SHOOT,
|
||||
DEAGLE_SHIELD_SHOOT2,
|
||||
DEAGLE_SHIELD_SHOOT_EMPTY,
|
||||
DEAGLE_SHIELD_RELOAD,
|
||||
DEAGLE_SHIELD_DRAW,
|
||||
DEAGLE_SHIELD_IDLE_UP,
|
||||
DEAGLE_SHIELD_UP,
|
||||
DEAGLE_SHIELD_DOWN,
|
||||
};
|
||||
|
||||
class CDEAGLE: public CBasePlayerWeapon
|
||||
{
|
||||
public:
|
||||
@ -1065,7 +1088,7 @@ enum glock18_shield_e
|
||||
GLOCK18_SHIELD_SHOOT_EMPTY,
|
||||
GLOCK18_SHIELD_RELOAD,
|
||||
GLOCK18_SHIELD_DRAW,
|
||||
GLOCK18_SHIELD_IDLE,
|
||||
GLOCK18_SHIELD_IDLE_UP,
|
||||
GLOCK18_SHIELD_UP,
|
||||
GLOCK18_SHIELD_DOWN,
|
||||
};
|
||||
@ -1180,7 +1203,7 @@ enum knife_shield_e
|
||||
KNIFE_SHIELD_SLASH,
|
||||
KNIFE_SHIELD_ATTACKHIT,
|
||||
KNIFE_SHIELD_DRAW,
|
||||
KNIFE_SHIELD_UPIDLE,
|
||||
KNIFE_SHIELD_IDLE_UP,
|
||||
KNIFE_SHIELD_UP,
|
||||
KNIFE_SHIELD_DOWN,
|
||||
};
|
||||
@ -1249,7 +1272,7 @@ inline float CKnife::KnifeSwingDamage(bool fast) const { return fast ? m_flSwing
|
||||
inline float CKnife::KnifeStabDistance() const { return m_flStabDistance; }
|
||||
inline float CKnife::KnifeSwingDistance() const { return m_flSwingDistance; }
|
||||
inline float CKnife::KnifeBackStabMultiplier() const { return m_flBackStabMultiplier; }
|
||||
#else
|
||||
#else
|
||||
inline float CKnife::KnifeStabDamage() const { return KNIFE_STAB_DAMAGE; }
|
||||
inline float CKnife::KnifeSwingDamage(bool fast) const { return fast ? KNIFE_SWING_DAMAGE_FAST : KNIFE_SWING_DAMAGE; }
|
||||
inline float CKnife::KnifeStabDistance() const { return KNIFE_STAB_DISTANCE; }
|
||||
@ -1310,7 +1333,6 @@ private:
|
||||
|
||||
const float M3_MAX_SPEED = 230.0f;
|
||||
const float M3_DAMAGE = 20.0f;
|
||||
const Vector M3_CONE_VECTOR = Vector(0.0675, 0.0675, 0.0); // special shotgun spreads
|
||||
|
||||
enum m3_e
|
||||
{
|
||||
@ -1741,7 +1763,6 @@ private:
|
||||
|
||||
const float XM1014_MAX_SPEED = 240.0f;
|
||||
const float XM1014_DAMAGE = 20.0f;
|
||||
const Vector XM1014_CONE_VECTOR = Vector(0.0725, 0.0725, 0.0); // special shotgun spreads
|
||||
|
||||
enum xm1014_e
|
||||
{
|
||||
@ -1858,6 +1879,19 @@ enum fiveseven_e
|
||||
FIVESEVEN_DRAW,
|
||||
};
|
||||
|
||||
enum fiveseven_shield_e
|
||||
{
|
||||
FIVESEVEN_SHIELD_IDLE1,
|
||||
FIVESEVEN_SHIELD_SHOOT,
|
||||
FIVESEVEN_SHIELD_SHOOT2,
|
||||
FIVESEVEN_SHIELD_SHOOT_EMPTY,
|
||||
FIVESEVEN_SHIELD_RELOAD,
|
||||
FIVESEVEN_SHIELD_DRAW,
|
||||
FIVESEVEN_SHIELD_IDLE_UP,
|
||||
FIVESEVEN_SHIELD_UP,
|
||||
FIVESEVEN_SHIELD_DOWN,
|
||||
};
|
||||
|
||||
class CFiveSeven: public CBasePlayerWeapon
|
||||
{
|
||||
public:
|
||||
@ -2136,7 +2170,13 @@ int DamageDecal(CBaseEntity *pEntity, int bitsDamageType);
|
||||
void DecalGunshot(TraceResult *pTrace, int iBulletType, bool ClientOnly, entvars_t *pShooter, bool bHitMetal);
|
||||
void EjectBrass(const Vector &vecOrigin, const Vector &vecLeft, const Vector &vecVelocity, float rotation, int model, int soundtype, int entityIndex);
|
||||
void EjectBrass2(const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype, entvars_t *pev);
|
||||
void AddAmmoNameToAmmoRegistry(const char *szAmmoname);
|
||||
int AddAmmoNameToAmmoRegistry(const char *szAmmoname);
|
||||
void UTIL_PrecacheOtherWeapon(const char *szClassname);
|
||||
BOOL CanAttack(float attack_time, float curtime, BOOL isPredicted);
|
||||
float GetBaseAccuracy(WeaponIdType id);
|
||||
|
||||
#ifdef REGAMEDLL_API
|
||||
void ClearMultiDamage_OrigFunc();
|
||||
void ApplyMultiDamage_OrigFunc(entvars_t *pevInflictor, entvars_t *pevAttacker);
|
||||
void AddMultiDamage_OrigFunc(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType);
|
||||
#endif
|
||||
|
@ -290,7 +290,7 @@ AmmoInfoStruct g_ammoInfo_default[] =
|
||||
|
||||
AmmoInfoStruct g_ammoInfo[ARRAYSIZE(g_ammoInfo_default)];
|
||||
|
||||
WeaponSlotInfo g_weaponSlotInfo[] = {
|
||||
WeaponSlotInfo g_weaponSlotInfo_default[] = {
|
||||
{ WEAPON_C4, C4_SLOT, "weapon_c4" },
|
||||
{ WEAPON_KNIFE, KNIFE_SLOT, "weapon_knife" },
|
||||
{ WEAPON_P228, PISTOL_SLOT, "weapon_p228" },
|
||||
@ -324,6 +324,8 @@ WeaponSlotInfo g_weaponSlotInfo[] = {
|
||||
{ WEAPON_SHIELDGUN, NONE_SLOT, "weapon_shield" },
|
||||
};
|
||||
|
||||
WeaponSlotInfo g_weaponSlotInfo[ARRAYSIZE(g_weaponSlotInfo_default)];
|
||||
|
||||
// Given an alias, return the associated weapon ID
|
||||
WeaponIdType AliasToWeaponID(const char *alias)
|
||||
{
|
||||
@ -529,10 +531,21 @@ WeaponInfoStruct *GetWeaponInfo(const char *weaponName)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WeaponInfoStruct *GetDefaultWeaponInfo(int weaponID)
|
||||
{
|
||||
for (auto& info : g_weaponInfo_default) {
|
||||
if (info.id == weaponID) {
|
||||
return &info;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AmmoInfoStruct *GetAmmoInfo(const char *ammoName)
|
||||
{
|
||||
for (auto& info : g_ammoInfo) {
|
||||
if (!Q_stricmp(info.ammoName1, ammoName)) {
|
||||
if (info.ammoName1 && !Q_stricmp(info.ammoName1, ammoName)) {
|
||||
return &info;
|
||||
}
|
||||
}
|
||||
@ -555,6 +568,7 @@ void WeaponInfoReset()
|
||||
{
|
||||
Q_memcpy(g_weaponInfo, g_weaponInfo_default, sizeof(g_weaponInfo));
|
||||
Q_memcpy(g_ammoInfo, g_ammoInfo_default, sizeof(g_ammoInfo));
|
||||
Q_memcpy(g_weaponSlotInfo, g_weaponSlotInfo_default, sizeof(g_weaponSlotInfo));
|
||||
}
|
||||
|
||||
WeaponSlotInfo *GetWeaponSlot(WeaponIdType weaponID)
|
||||
|
@ -318,25 +318,12 @@ enum AmmoBuyAmount
|
||||
AMMO_SMOKEGRENADE_BUY = 1,
|
||||
};
|
||||
|
||||
enum shieldgun_e
|
||||
{
|
||||
SHIELDGUN_IDLE,
|
||||
SHIELDGUN_SHOOT1,
|
||||
SHIELDGUN_SHOOT2,
|
||||
SHIELDGUN_SHOOT_EMPTY,
|
||||
SHIELDGUN_RELOAD,
|
||||
SHIELDGUN_DRAW,
|
||||
SHIELDGUN_DRAWN_IDLE,
|
||||
SHIELDGUN_UP,
|
||||
SHIELDGUN_DOWN,
|
||||
};
|
||||
|
||||
// custom
|
||||
enum shieldgren_e
|
||||
{
|
||||
SHIELDREN_IDLE = 4,
|
||||
SHIELDREN_UP,
|
||||
SHIELDREN_DOWN
|
||||
SHIELDGREN_IDLE = 4, // 3 is last grenade viewmodel sequence
|
||||
SHIELDGREN_UP,
|
||||
SHIELDGREN_DOWN
|
||||
};
|
||||
|
||||
enum InventorySlotType
|
||||
@ -458,6 +445,8 @@ void WeaponInfoReset();
|
||||
WeaponInfoStruct *GetWeaponInfo(int weaponID);
|
||||
WeaponInfoStruct *GetWeaponInfo(const char *weaponName);
|
||||
|
||||
WeaponInfoStruct *GetDefaultWeaponInfo(int weaponID);
|
||||
|
||||
AmmoInfoStruct *GetAmmoInfo(AmmoType ammoID);
|
||||
AmmoInfoStruct *GetAmmoInfo(const char *ammoName);
|
||||
|
||||
|
@ -216,7 +216,7 @@ void CWorld::Spawn()
|
||||
Precache();
|
||||
|
||||
g_szMapBriefingText[0] = '\0';
|
||||
Q_sprintf(szMapBriefingFile, "maps/%s.txt", STRING(gpGlobals->mapname));
|
||||
Q_snprintf(szMapBriefingFile, sizeof(szMapBriefingFile), "maps/%s.txt", STRING(gpGlobals->mapname));
|
||||
|
||||
int flength = 0;
|
||||
char *pFile = (char *)LOAD_FILE_FOR_ME(szMapBriefingFile, &flength);
|
||||
|
@ -73,6 +73,15 @@ void CAUG::SecondaryAttack()
|
||||
else
|
||||
m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 90;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (TheBots)
|
||||
{
|
||||
TheBots->OnEvent(EVENT_WEAPON_ZOOMED, m_pPlayer);
|
||||
}
|
||||
|
||||
m_pPlayer->ResetMaxSpeed();
|
||||
#endif
|
||||
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.3f;
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,11 @@ void CAWP::AWPFire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
|
||||
}
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
||||
#else
|
||||
m_pPlayer->pev->punchangle.x -= 2.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CAWP::Reload()
|
||||
|
@ -93,7 +93,7 @@ void CDEAGLE::PrimaryAttack()
|
||||
|
||||
void CDEAGLE::SecondaryAttack()
|
||||
{
|
||||
ShieldSecondaryFire(SHIELDGUN_UP, SHIELDGUN_DOWN);
|
||||
ShieldSecondaryFire(DEAGLE_SHIELD_UP, DEAGLE_SHIELD_DOWN);
|
||||
}
|
||||
|
||||
void CDEAGLE::DEAGLEFire(float flSpread, float flCycleTime, BOOL fUseSemi)
|
||||
@ -177,7 +177,11 @@ void CDEAGLE::DEAGLEFire(float flSpread, float flCycleTime, BOOL fUseSemi)
|
||||
}
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.8f;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
||||
#else
|
||||
m_pPlayer->pev->punchangle.x -= 2;
|
||||
#endif
|
||||
ResetPlayerShieldAnim();
|
||||
}
|
||||
|
||||
@ -200,11 +204,23 @@ void CDEAGLE::WeaponIdle()
|
||||
|
||||
if (m_flTimeWeaponIdle <= UTIL_WeaponTimeBase())
|
||||
{
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 20.0f;
|
||||
|
||||
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (m_pPlayer->HasShield())
|
||||
#endif
|
||||
{
|
||||
SendWeaponAnim(SHIELDGUN_DRAWN_IDLE, UseDecrement() != FALSE);
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 20.0f;
|
||||
|
||||
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
|
||||
{
|
||||
SendWeaponAnim(DEAGLE_SHIELD_IDLE_UP, UseDecrement() != FALSE);
|
||||
}
|
||||
}
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
else if (m_iClip)
|
||||
{
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3.0625f;
|
||||
SendWeaponAnim(DEAGLE_IDLE1, UseDecrement() != FALSE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,11 @@ void CELITE::ELITEFire(float flSpread, float flCycleTime, BOOL fUseSemi)
|
||||
}
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
||||
#else
|
||||
m_pPlayer->pev->punchangle.x -= 2.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CELITE::Reload()
|
||||
|
@ -92,7 +92,7 @@ void CFiveSeven::PrimaryAttack()
|
||||
|
||||
void CFiveSeven::SecondaryAttack()
|
||||
{
|
||||
ShieldSecondaryFire(SHIELDGUN_UP, SHIELDGUN_DOWN);
|
||||
ShieldSecondaryFire(FIVESEVEN_SHIELD_UP, FIVESEVEN_SHIELD_DOWN);
|
||||
}
|
||||
|
||||
void CFiveSeven::FiveSevenFire(float flSpread, float flCycleTime, BOOL fUseSemi)
|
||||
@ -176,7 +176,11 @@ void CFiveSeven::FiveSevenFire(float flSpread, float flCycleTime, BOOL fUseSemi)
|
||||
}
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
KickBack(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
||||
#else
|
||||
m_pPlayer->pev->punchangle.x -= 2.0f;
|
||||
#endif
|
||||
ResetPlayerShieldAnim();
|
||||
}
|
||||
|
||||
@ -208,7 +212,7 @@ void CFiveSeven::WeaponIdle()
|
||||
|
||||
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
|
||||
{
|
||||
SendWeaponAnim(SHIELDGUN_DRAWN_IDLE, UseDecrement() != FALSE);
|
||||
SendWeaponAnim(FIVESEVEN_SHIELD_IDLE_UP, UseDecrement() != FALSE);
|
||||
}
|
||||
}
|
||||
else if (m_iClip)
|
||||
|
@ -114,7 +114,7 @@ bool CFlashbang::ShieldSecondaryFire(int iUpAnim, int iDownAnim)
|
||||
m_iWeaponState &= ~WPNSTATE_SHIELD_DRAWN;
|
||||
SendWeaponAnim(iDownAnim, UseDecrement() != FALSE);
|
||||
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren");
|
||||
|
||||
m_fMaxSpeed = FLASHBANG_MAX_SPEED;
|
||||
m_pPlayer->m_bShieldDrawn = false;
|
||||
@ -124,7 +124,7 @@ bool CFlashbang::ShieldSecondaryFire(int iUpAnim, int iDownAnim)
|
||||
m_iWeaponState |= WPNSTATE_SHIELD_DRAWN;
|
||||
SendWeaponAnim(iUpAnim, UseDecrement() != FALSE);
|
||||
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shielded");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shielded");
|
||||
|
||||
m_fMaxSpeed = FLASHBANG_MAX_SPEED_SHIELD;
|
||||
m_pPlayer->m_bShieldDrawn = true;
|
||||
@ -142,7 +142,7 @@ bool CFlashbang::ShieldSecondaryFire(int iUpAnim, int iDownAnim)
|
||||
|
||||
void CFlashbang::SecondaryAttack()
|
||||
{
|
||||
ShieldSecondaryFire(SHIELDGUN_DRAW, SHIELDGUN_DRAWN_IDLE);
|
||||
ShieldSecondaryFire(SHIELDGREN_UP, SHIELDGREN_DOWN);
|
||||
}
|
||||
|
||||
void CFlashbang::SetPlayerShieldAnim()
|
||||
@ -151,9 +151,9 @@ void CFlashbang::SetPlayerShieldAnim()
|
||||
return;
|
||||
|
||||
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shield");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shield");
|
||||
else
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren");
|
||||
}
|
||||
|
||||
void CFlashbang::ResetPlayerShieldAnim()
|
||||
@ -163,7 +163,7 @@ void CFlashbang::ResetPlayerShieldAnim()
|
||||
|
||||
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
|
||||
{
|
||||
Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldgren");
|
||||
Q_strlcpy(m_pPlayer->m_szAnimExtention, "shieldgren");
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,7 +236,7 @@ void CFlashbang::WeaponIdle()
|
||||
|
||||
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
|
||||
{
|
||||
SendWeaponAnim(SHIELDREN_IDLE, UseDecrement() != FALSE);
|
||||
SendWeaponAnim(SHIELDGREN_IDLE, UseDecrement() != FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -185,8 +185,15 @@ void CG3SG1::G3SG1Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.8f;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
m_iDirection = 1; // force positive Y addition
|
||||
KickBack(UTIL_SharedRandomFloat(m_pPlayer->random_seed + 4, 0.75, 1.75) + m_pPlayer->pev->punchangle.x * 0.25f,
|
||||
UTIL_SharedRandomFloat(m_pPlayer->random_seed + 5, -0.75, 0.75),
|
||||
0.0, 0.0, 0.0, 0.0, 0);
|
||||
#else
|
||||
m_pPlayer->pev->punchangle.x -= UTIL_SharedRandomFloat(m_pPlayer->random_seed + 4, 0.75, 1.75) + m_pPlayer->pev->punchangle.x * 0.25f;
|
||||
m_pPlayer->pev->punchangle.y += UTIL_SharedRandomFloat(m_pPlayer->random_seed + 5, -0.75, 0.75);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CG3SG1::Reload()
|
||||
|
@ -253,6 +253,9 @@ void CGLOCK18::GLOCK18Fire(float flSpread, float flCycleTime, BOOL bFireBurst)
|
||||
m_flGlock18Shoot = gpGlobals->time + 0.1f;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
KickBack(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); // dummy call, API useful
|
||||
#endif
|
||||
ResetPlayerShieldAnim();
|
||||
}
|
||||
|
||||
@ -295,7 +298,7 @@ void CGLOCK18::WeaponIdle()
|
||||
|
||||
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
|
||||
{
|
||||
SendWeaponAnim(GLOCK18_SHIELD_IDLE, UseDecrement() != FALSE);
|
||||
SendWeaponAnim(GLOCK18_SHIELD_IDLE_UP, UseDecrement() != FALSE);
|
||||
}
|
||||
}
|
||||
// only idle if the slid isn't back
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user