Merge branch 'master' into sohl1.2

This commit is contained in:
Andrey Akhmichin 2024-02-23 01:46:33 +05:00
commit 65a1492b12
128 changed files with 4199 additions and 2330 deletions

View File

@ -52,13 +52,13 @@ jobs:
- name: Build on Linux
if: startsWith(matrix.os, 'ubuntu')
run: |
schroot --chroot steamrt_scout_i386 -- cmake -B build -S . -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DCMAKE_INSTALL_PREFIX="$PWD/dist"
schroot --chroot steamrt_scout_i386 -- cmake -DCMAKE_BUILD_TYPE=Release -DPOLLY=ON -B build -S . -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DCMAKE_INSTALL_PREFIX="$PWD/dist"
schroot --chroot steamrt_scout_i386 -- cmake --build build --target all
schroot --chroot steamrt_scout_i386 -- cmake --build build --target install
- name: Build on Linux with vgui
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.cc, 'gcc')
run: |
schroot --chroot steamrt_scout_i386 -- cmake -B build-vgui -S . -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VGUI=ON -DCMAKE_INSTALL_PREFIX="$PWD/dist-vgui"
schroot --chroot steamrt_scout_i386 -- cmake -DCMAKE_BUILD_TYPE=Release -DPOLLY=ON -B build-vgui -S . -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VGUI=ON -DCMAKE_INSTALL_PREFIX="$PWD/dist-vgui"
cp vgui_support/vgui-dev/lib/vgui.so build-vgui/cl_dll
schroot --chroot steamrt_scout_i386 -- cmake --build build-vgui --target all
schroot --chroot steamrt_scout_i386 -- cmake --build build-vgui --target install

10
.gitignore vendored
View File

@ -29,3 +29,13 @@ CMakeSettings.json
CMakeFiles
CMakeCache.txt
Makefile
# Android Studio/Gradle
.gradle/
.externalNativeBuild
.cxx/
.idea/
local.properties
.project
.classpath
.settings

View File

@ -20,7 +20,8 @@
# SOFTWARE.
#
cmake_minimum_required(VERSION 2.8.12)
# 3.9 added captures in if(MATCHES)
cmake_minimum_required(VERSION 3.9)
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.15.0")
cmake_policy(SET CMP0091 NEW)
@ -32,6 +33,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
include(CheckIncludeFile)
include(CheckCSourceCompiles)
include(VSForceXPToolchain) # Force XP toolchain for Visual Studio
include(CheckIPOSupported)
project (HLSDK-PORTABLE)
@ -45,49 +47,71 @@ option(USE_NOVGUI_SCOREBOARD "Prefer non-VGUI Scoreboard when USE_VGUI is enable
option(USE_VOICEMGR "Enable VOICE MANAGER." OFF)
option(BUILD_CLIENT "Build client dll" ON)
option(BUILD_SERVER "Build server dll" ON)
option(LTO "Enable interprocedural optimization" OFF)
option(POLLY "Enable pollyhedral optimization" OFF)
if (CMAKE_SIZEOF_VOID_P EQUAL 4 OR
if(CMAKE_SIZEOF_VOID_P EQUAL 4 OR
((WIN32 OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
AND (CMAKE_SYSTEM_PROCESSOR STREQUAL "x64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "X64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")))
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "X86_64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "EM64T")))
option(64BIT "Disable auto -m32 appending to compiler flags" OFF)
option(GOLDSOURCE_SUPPORT "Build goldsource compatible client library" ON)
else()
option(64BIT "Disable auto -m32 appending to compiler flags" ON)
option(GOLDSOURCE_SUPPORT "Build goldsource compatible client library" OFF)
endif()
option(BARNACLE_FIX_VISIBILITY "Enable barnacle tongue length fix" OFF)
option(CLIENT_WEAPONS "Enable client local weapons prediction" ON)
option(CROWBAR_IDLE_ANIM "Enable crowbar idle animation" OFF)
option(CROWBAR_DELAY_FIX "Enable crowbar attack delay fix" OFF)
option(CROWBAR_FIX_RAPID_CROWBAR "Enable rapid crowbar fix" OFF)
option(GAUSS_OVERCHARGE_FIX "Enable gauss overcharge fix" OFF)
option(TRIPMINE_BEAM_DUPLICATION_FIX "Enable fix of tripmine beam duplication on level transition" OFF)
option(HANDGRENADE_DEPLOY_FIX "Enable handgrenade deploy animation fix after finishing a throw" OFF)
option(WEAPONS_ANIMATION_TIMES_FIX "Enable animation times fix for some weapons" OFF)
option(OEM_BUILD "Enable OEM Build" OFF)
option(HLDEMO_BUILD "Enable Demo Build" OFF)
option(XENWARRIOR "Compile as Xen-Warrior" OFF)
set(SERVER_INSTALL_DIR "dlls" CACHE STRING "Where put server dll")
set(CLIENT_INSTALL_DIR "cl_dlls" CACHE STRING "Where put client dll")
set(SERVER_LIBRARY_NAME "spirit" CACHE STRING "Library name for PC platforms")
if(XENWARRIOR)
set(GAMEDIR "xenwar" CACHE STRING "Gamedir path")
add_definitions(-DXENWARRIOR)
message(STATUS "Xen-Warrior")
# It seems CMAKE_SYSTEM_PROCESSOR parameter completely useless for APPLE platform,
# so may need to set options here manually.
if((WIN32 OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
AND (((CMAKE_SYSTEM_PROCESSOR STREQUAL "x64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "X64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "X86_64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "EM64T") AND NOT 64BIT)
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x86"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "X86"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "i386"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "i486"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "i586"
OR CMAKE_SYSTEM_PROCESSOR STREQUAL "i686"))
option(GOLDSOURCE_SUPPORT "Build goldsource compatible client library" ON)
else()
set(GAMEDIR "Spirit" CACHE STRING "Gamedir path")
message(STATUS "Spirit of Half-Life 1.2")
option(GOLDSOURCE_SUPPORT "Build goldsource compatible client library" OFF)
endif()
#-----------------
# MAIN BUILD CODE \
###################\
file(STRINGS "mod_options.txt" MOD_OPTIONS_STRINGS REGEX "^([A-Za-z0-9_]+)=([A-Za-z0-9_]+)\ \#\ (.*)$")
foreach(LINE IN LISTS MOD_OPTIONS_STRINGS)
# file() itself doesn't populate CMAKE_MATCH_<n>, so
# reparse the string
if(${LINE} MATCHES "^([A-Za-z0-9_]+)=([A-Za-z0-9_]+)\ \#\ (.*)$")
# detect boolean options
if(${CMAKE_MATCH_2} STREQUAL "ON" OR ${CMAKE_MATCH_2} STREQUAL "OFF")
option(${CMAKE_MATCH_1} "${CMAKE_MATCH_3}" ${CMAKE_MATCH_2})
# let's check it here as well
if(${CMAKE_MATCH_1})
message(STATUS ${CMAKE_MATCH_3} " is enabled")
add_definitions(-D${CMAKE_MATCH_1})
else()
message(STATUS ${CMAKE_MATCH_3} " is disabled")
endif()
else()
set(${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE STRING "${CMAKE_MATCH_3}")
endif()
endif()
endforeach()
if(HLDEMO_BUILD AND OEM_BUILD)
message(FATAL_ERROR "Don't mix Demo and OEM builds!")
endif()
@ -117,76 +141,11 @@ else()
message(STATUS "Building for 32 Bit")
endif()
if(CLIENT_WEAPONS)
message(STATUS "Client weapons enabled.")
add_definitions(-DCLIENT_WEAPONS)
endif()
if(BARNACLE_FIX_VISIBILITY)
message(STATUS "Barnacle tongue fix enabled")
add_definitions(-DBARNACLE_FIX_VISIBILITY)
endif()
if(CROWBAR_IDLE_ANIM)
message(STATUS "Crowbar idle animation enabled")
add_definitions(-DCROWBAR_IDLE_ANIM)
endif()
if(CROWBAR_DELAY_FIX)
message(STATUS "Crowbar attack delay fix enabled")
add_definitions(-DCROWBAR_DELAY_FIX)
endif()
if(CROWBAR_FIX_RAPID_CROWBAR)
message(STATUS "Rapid crowbar fix enabled")
add_definitions(-DCROWBAR_FIX_RAPID_CROWBAR)
endif()
if(GAUSS_OVERCHARGE_FIX)
message(STATUS "Gauss overcharge fix enabled")
add_definitions(-DGAUSS_OVERCHARGE_FIX)
endif()
if(TRIPMINE_BEAM_DUPLICATION_FIX)
message(STATUS "Tripmine beam duplication fix enabled")
add_definitions(-DTRIPMINE_BEAM_DUPLICATION_FIX)
endif()
if(HANDGRENADE_DEPLOY_FIX)
message(STATUS "Handgrenade deploy animation fix enabled")
add_definitions(-DHANDGRENADE_DEPLOY_FIX)
endif()
if(WEAPONS_ANIMATION_TIMES_FIX)
message(STATUS "Weapons animation times fix enabled")
add_definitions(-DWEAPONS_ANIMATION_TIMES_FIX)
endif()
if(OEM_BUILD)
message(STATUS "OEM build enabled")
add_definitions(-DOEM_BUILD)
endif()
if(HLDEMO_BUILD)
message(STATUS "Demo build enabled")
add_definitions(-DHLDEMO_BUILD)
endif()
if (MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--add-stdcall-alias")
endif()
# add_compile_options for older cmake versions
if(${CMAKE_VERSION} VERSION_LESS "3.0.2")
macro(add_compile_options)
set(list_var "${ARGV}")
foreach(arg IN LISTS list_var)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${arg}")
endforeach()
endmacro()
endif()
if(NOT MSVC)
#add_compile_options(-Wempty-body) # GCC/Clang flag
add_compile_options(-Wreturn-type) # GCC/Clang flag
@ -198,6 +157,15 @@ if(VITA)
add_compile_options(-fno-use-cxa-atexit)
endif()
if(LTO)
check_ipo_supported(RESULT HAVE_LTO OUTPUT LTO_ERROR)
if(HAVE_LTO)
message(STATUS "IPO / LTO enabled")
else()
message(STATUS "IPO / LTO not supported: ${LTO_ERROR}")
endif()
endif()
check_include_file("tgmath.h" HAVE_TGMATH_H)
if(HAVE_TGMATH_H)
if(NOT MSVC)
@ -224,3 +192,11 @@ endif()
if(NOT BUILD_SERVER AND NOT BUILD_CLIENT)
message(FATAL_ERROR "Nothing to build")
endif()
if(POLLY)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-mllvm -polly)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-fgraphite-identity -floop-interchange -floop-block)
endif()
endif()

View File

@ -80,7 +80,7 @@ git clone --recursive https://github.com/FWGS/hlsdk-portable
### Prerequisites
Install and run [Visual Studio Installer](https://visualstudio.microsoft.com/downloads/). The installer allows you to choose specific components. Select `Desktop development with C++`. You can untick everything you don't need in Installation details, but you must keep `MSVC` ticked. You may also keep `C++ CMake tools for Windows` ticked as you'll need **cmake**. Alternatively you can install **cmake** from the [cmake.org](https://cmake.org/download/) and during installation tick *Add to the PATH...*.
Install and run [Visual Studio Installer](https://visualstudio.microsoft.com/downloads/). The installer allows you to choose specific components. Select `Desktop development with C++`. You can untick everything you don't need in Installation details, but you must keep `MSVC` and corresponding Windows SDK (e.g. Windows 10 SDK or Windows 11 SDK) ticked. You may also keep `C++ CMake tools for Windows` ticked as you'll need **cmake**. Alternatively you can install **cmake** from the [cmake.org](https://cmake.org/download/) and during installation tick *Add to the PATH...*.
### Opening command prompt
@ -164,7 +164,7 @@ sudo ./setup_chroot.sh --i386 --tarball ./com.valvesoftware.SteamRuntime.Sdk-i38
Now you can use cmake and make prepending the commands with `schroot --chroot steamrt_scout_i386 --`:
```
schroot --chroot steamrt_scout_i386 -- cmake -B build-in-steamrt -S .
schroot --chroot steamrt_scout_i386 -- cmake -DCMAKE_BUILD_TYPE=Release -B build-in-steamrt -S .
schroot --chroot steamrt_scout_i386 -- cmake --build build-in-steamrt
```
@ -180,13 +180,20 @@ sudo apt install cmake build-essential gcc-multilib g++-multilib libsdl2-dev:i38
### Building
```
cmake -B build -S .
cmake -DCMAKE_BUILD_TYPE=Release -B build -S .
cmake --build build
```
Note that the libraries built this way might be not compatible with Steam Half-Life. If you have such issue you can configure it to build statically with c++ and gcc libraries:
```
cmake .. -DCMAKE_C_FLAGS="-static-libstdc++ -static-libgcc"
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc" -B build -S .
cmake --build build
```
Alternatively, you can avoid libstdc++/libgcc_s linking using small libsupc++ library and optimization build flags instead(Really just set Release build type and set C compiler as C++ compiler):
```
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=cc -B build -S .
cmake --build build
```
To ensure portability it's still better to build using Steam Runtime or another chroot of some older distro.
@ -229,13 +236,36 @@ Insert your actual user name in place of `yourusername`.
Prepend any make or cmake call with `schroot -c jessie --`:
```
schroot --chroot jessie -- cmake -B build-in-chroot -S .
schroot --chroot jessie -- cmake -DCMAKE_BUILD_TYPE=Release -B build-in-chroot -S .
schroot --chroot jessie -- cmake --build build-in-chroot
```
## Android
1. Set up [Android Studio/Android SDK](https://developer.android.com/studio).
TODO
### Android Studio
Open the project located in the `android` folder and build.
### Command-line
```
cd android
./gradlew assembleRelease
```
### Customizing the build
settings.gradle:
* **rootProject.name** - project name displayed in Android Studio (optional).
app/build.gradle:
* **android->namespace** and **android->defaultConfig->applicationId** - set both to desired package name.
* **getBuildNum** function - set **releaseDate** variable as desired.
app/java/su/xash/hlsdk/MainActivity.java:
* **.putExtra("gamedir", ...)** - set desired gamedir.
src/main/AndroidManifest.xml:
* **application->android:label** - set desired application name.
* **su.xash.engine.gamedir** value - set to same as above.
## Nintendo Switch
@ -307,7 +337,13 @@ Install C and C++ compilers (like gcc or clang), cmake and make.
### Building
```
cmake -B build -S .
cmake -DCMAKE_BUILD_TYPE=Release -B build -S .
cmake --build build
```
Force 64-bit build:
```
cmake -DCMAKE_BUILD_TYPE=Release -D64BIT=1 -B build -S .
cmake --build build
```
@ -316,15 +352,22 @@ cmake --build build
To use waf, you need to install python (2.7 minimum)
```
(./waf configure -T release)
(./waf)
./waf configure -T release
./waf
```
Force 64-bit build:
```
./waf configure -T release -8
./waf
```
## Build options
Some useful build options that can be set during the cmake step.
* **GOLDSOURCE_SUPPORT** - allows to turn off/on the support for GoldSource input. Set to **ON** by default on Windows and Linux, **OFF** on other platforms.
* **GOLDSOURCE_SUPPORT** - allows to turn off/on the support for GoldSource input. Set to **ON** by default on x86 Windows and x86 Linux, **OFF** on other platforms.
* **64BIT** - allows to turn off/on 64-bit build. Set to **OFF** by default on x86_64 Windows, x86_64 Linux and 32-bit platforms, **ON** on other 64-bit platforms.
* **USE_VGUI** - whether to use VGUI library. **OFF** by default. You need to init `vgui_support` submodule in order to build with VGUI.
This list is incomplete. Look at `CMakeLists.txt` to see all available options.

73
android/app/build.gradle Normal file
View File

@ -0,0 +1,73 @@
import java.time.LocalDateTime
import java.time.Month
import java.time.temporal.ChronoUnit
apply plugin: 'com.android.application'
android {
ndkVersion '26.1.10909125'
namespace 'com.example.hlsdk'
defaultConfig {
applicationId 'com.example.hlsdk'
versionName '1.0'
versionCode getBuildNum()
minSdkVersion 3
targetSdk 34
compileSdk 34
externalNativeBuild {
cmake {
arguments '-DPOLLY=ON'
}
}
}
externalNativeBuild {
cmake {
version '3.22.1'
path file('../../CMakeLists.txt')
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
debug {
minifyEnabled false
shrinkResources false
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
release {
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
lint {
abortOnError false
}
androidResources {
noCompress += ''
}
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}
static def getBuildNum() {
LocalDateTime now = LocalDateTime.now()
LocalDateTime releaseDate = LocalDateTime.of(2023, Month.DECEMBER, 28, 0, 0, 0)
int qBuildNum = releaseDate.until(now, ChronoUnit.DAYS)
int minuteOfDay = now.getHour() * 60 + now.getMinute()
return qBuildNum * 10000 + minuteOfDay
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:forceQueryable="true"
android:icon="@android:mipmap/sym_def_app_icon"
android:label="hlsdk-portable"
tools:targetApi="r">
<meta-data
android:name="su.xash.engine.gamedir"
android:value="valve" />
<activity
android:name="su.xash.hlsdk.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="su.xash.engine.MOD" />
</intent-filter>
</activity>
</application>
<queries>
<package android:name="su.xash.engine" />
<package android:name="su.xash.engine.test" />
</queries>
</manifest>

View File

@ -0,0 +1,37 @@
package su.xash.hlsdk;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String pkg = "su.xash.engine.test";
try {
getPackageManager().getPackageInfo(pkg, 0);
} catch (PackageManager.NameNotFoundException e) {
try {
pkg = "su.xash.engine";
getPackageManager().getPackageInfo(pkg, 0);
} catch (PackageManager.NameNotFoundException ex) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=su.xash.engine")).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK));
finish();
return;
}
}
startActivity(new Intent().setComponent(new ComponentName(pkg, "su.xash.engine.XashActivity"))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
.putExtra("gamedir", "valve")
.putExtra("gamelibdir", getApplicationInfo().nativeLibraryDir)
.putExtra("package", getPackageName()));
finish();
}
}

17
android/build.gradle Normal file
View File

@ -0,0 +1,17 @@
buildscript {
repositories {
mavenCentral()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.2.0'
}
}
allprojects {
repositories {
mavenCentral()
google()
}
}

21
android/gradle.properties Normal file
View File

@ -0,0 +1,21 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=384m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# android.useDeprecatedNdk=true
android.enableJetifier=true
android.useAndroidX=true

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Thu Dec 28 14:36:02 EET 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

160
android/gradlew vendored Executable file
View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
android/gradlew.bat vendored Normal file
View File

@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

3
android/settings.gradle Normal file
View File

@ -0,0 +1,3 @@
include ':app'
rootProject.name = 'hlsdk-portable'

View File

@ -70,6 +70,7 @@ SRCS+=./in_camera.cpp
SRCS+=./input.cpp
SRCS+=./input_goldsource.cpp
SRCS+=./input_mouse.cpp
SRCS+=./interpolation.cpp
#SRCS+=./inputw32.cpp
SRCS+=./menu.cpp
SRCS+=./message.cpp

View File

@ -20,7 +20,7 @@
# SOFTWARE.
#
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.9)
project (CLDLL)
set (CLDLL_LIBRARY client)
@ -29,13 +29,21 @@ add_definitions(-DCLIENT_DLL)
if(NOT MSVC)
add_compile_options(-fno-exceptions) # GCC/Clang flag
add_compile_options(-Wno-write-strings) # GCC/Clang flag
add_compile_options(-fno-rtti) # GCC/Clang flag
add_compile_options(-fvisibility=hidden) # GCC/Clang flag
add_definitions(-D_LINUX -DLINUX) # It seems enough for all non-Win32 systems
add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp)
if(NOT MINGW)
add_definitions(-D_snprintf=snprintf -D_vsnprintf=vsnprintf)
endif()
if(CMAKE_BUILD_TYPE MATCHES "Release"
OR (CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo"
AND CMAKE_SYSTEM_NAME STREQUAL "Android"))
add_compile_options(-fno-unwind-tables -fno-asynchronous-unwind-tables) # GCC/Clang flag
add_compile_options(-fomit-frame-pointer) # GCC/Clang flag
add_compile_options(-ftree-vectorize) # GCC/Clang flag
add_compile_options(-funsafe-math-optimizations) # GCC/Clang flag
endif()
else()
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
endif()
@ -99,6 +107,7 @@ set (CLDLL_SOURCES
input_goldsource.cpp
input_mouse.cpp
input_xash3d.cpp
interpolation.cpp
menu.cpp
message.cpp
parsemsg.cpp
@ -211,8 +220,16 @@ if(MSVC)
set_property(TARGET ${CLDLL_LIBRARY} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
if(HAVE_LTO)
set_property(TARGET ${CLDLL_LIBRARY} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
install( TARGETS ${CLDLL_LIBRARY}
DESTINATION "${GAMEDIR}/${CLIENT_INSTALL_DIR}/"
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE )
add_custom_command(TARGET ${CLDLL_LIBRARY}
POST_BUILD DEPENDS ${CLDLL_LIBRARY}
COMMAND $<$<CONFIG:release>:${CMAKE_STRIP}> -s $<TARGET_FILE:${CLDLL_LIBRARY}>)

View File

@ -73,7 +73,7 @@ int CHudMOTD::Draw( float fTime )
//bool bScroll;
// find the top of where the MOTD should be drawn, so the whole thing is centered in the screen
int ypos = ( ScreenHeight - LINE_HEIGHT * m_iLines ) / 2; // shift it up slightly
char *ch = m_szMOTD;
unsigned char *ch = (unsigned char*)m_szMOTD;
int xpos = ( ScreenWidth - gHUD.m_scrinfo.charWidths['M'] * m_iMaxLength ) / 2;
if( xpos < 30 )
xpos = 30;
@ -95,11 +95,13 @@ int CHudMOTD::Draw( float fTime )
gHUD.DrawDarkRectangle( xpos - 5, ypos_r - 5, xmax - xpos + 10, height + 10 );
while( *ch )
{
char *next_line;
int line_length = 0; // count the length of the current line
unsigned char *next_line;
for( next_line = ch; *next_line != '\n' && *next_line != 0; next_line++ )
line_length += gHUD.m_scrinfo.charWidths[*next_line];
char *top = next_line;
;
// int line_length = 0; // count the length of the current line
// for( next_line = ch; *next_line != '\n' && *next_line != 0; next_line++ )
// line_length += gHUD.m_scrinfo.charWidths[*next_line];
unsigned char *top = next_line;
if( *top == '\n' )
*top = 0;
else
@ -107,7 +109,7 @@ int CHudMOTD::Draw( float fTime )
// find where to start drawing the line
if( ( ypos > ROW_RANGE_MIN ) && ( ypos + LINE_HEIGHT <= ypos_r + height ) )
DrawUtfString( xpos, ypos, xmax, ch, 255, 180, 0 );
DrawUtfString( xpos, ypos, xmax, (const char*)ch, 255, 180, 0 );
ypos += LINE_HEIGHT;

View File

@ -28,7 +28,7 @@
#include "vgui_TeamFortressViewport.h"
#endif
#if GOLDSOURCE_SUPPORT && (_WIN32 || __linux__ || __APPLE__) && (__i386 || _M_IX86)
#if GOLDSOURCE_SUPPORT && (XASH_WIN32 || XASH_LINUX || XASH_APPLE) && XASH_X86
#define USE_FAKE_VGUI !USE_VGUI
#if USE_FAKE_VGUI
#include "VGUI_Panel.h"
@ -50,20 +50,10 @@ TeamFortressViewport *gViewPort = NULL;
#endif
mobile_engfuncs_t *gMobileEngfuncs = NULL;
extern "C" int g_bhopcap;
void InitInput( void );
void EV_HookEvents( void );
void IN_Commands( void );
int __MsgFunc_Bhopcap( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
g_bhopcap = READ_BYTE();
return 1;
}
/*
==========================
Initialize
@ -299,8 +289,6 @@ void DLLEXPORT HUD_Init( void )
#if USE_VGUI
Scheme_Init();
#endif
gEngfuncs.pfnHookUserMsg( "Bhopcap", __MsgFunc_Bhopcap );
}
/*

View File

@ -28,6 +28,7 @@
#pragma once
#if !defined(CL_DLL_H)
#define CL_DLL_H
#include "build.h"
typedef unsigned char byte;
typedef unsigned short word;
typedef float vec_t;
@ -39,7 +40,7 @@ typedef float vec_t;
#include "../engine/cdll_int.h"
#include "../dlls/cdll_dll.h"
#if !_WIN32
#if !XASH_WIN32
#define _cdecl
#endif
#include "exportdef.h"
@ -49,9 +50,6 @@ typedef float vec_t;
#else
#include <math.h>
#endif
#if __LP64__ || __LLP64__ || _WIN64 || (__x86_64__ && !__ILP32__) || _M_X64 || __ia64 || _M_IA64 || __aarch64__ || __powerpc64__
#define XASH_64BIT 1
#endif
extern cl_enginefunc_t gEngfuncs;
#include "../engine/mobility_int.h"

View File

@ -166,7 +166,8 @@ void VectorScale( const float *in, float scale, float *out );
float VectorNormalize( float *v );
void VectorInverse( float *v );
extern vec3_t vec3_origin;
// extern vec3_t vec3_origin;
extern float vec3_origin[3];
// disable 'possible loss of data converting float to int' warning message
#pragma warning( disable: 4244 )

View File

@ -52,6 +52,7 @@ set SOURCES=../dlls/crossbow.cpp ^
input_goldsource.cpp ^
input_mouse.cpp ^
input_xash3d.cpp ^
interpolation.cpp ^
menu.cpp ^
message.cpp ^
parsemsg.cpp ^

View File

@ -70,6 +70,7 @@ void EV_TripmineFire( struct event_args_s *args );
void EV_SnarkFire( struct event_args_s *args );
void EV_TrainPitchAdjust( struct event_args_s *args );
void EV_VehiclePitchAdjust( event_args_t *args );
}
#define VECTOR_CONE_1DEGREES Vector( 0.00873f, 0.00873f, 0.00873f )
@ -98,6 +99,7 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v
int cnt;
float fattn = ATTN_NORM;
int entity;
cl_entity_t *ent;
char *pTextureName;
char texname[64];
char szbuffer[64];
@ -109,7 +111,8 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v
chTextureType = 0;
// Player
if( entity >= 1 && entity <= gEngfuncs.GetMaxClients() )
if( ( entity >= 1 && entity <= gEngfuncs.GetMaxClients() )
|| ( ( ent = gEngfuncs.GetEntityByIndex( entity )) && ( ent->curstate.eflags & EFLAG_MONSTER )))
{
// hit body
chTextureType = CHAR_TEX_FLESH;
@ -420,7 +423,7 @@ void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int
gEngfuncs.pEventAPI->EV_SetSolidPlayers( idx - 1 );
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr );
gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_NORMAL, -1, &tr );
tracer = EV_HLDM_CheckTracer( idx, vecSrc, tr.endpos, forward, right, iBulletType, iTracerFreq, tracerCount );
@ -883,7 +886,7 @@ void EV_FireGauss( event_args_t *args )
gEngfuncs.pEventAPI->EV_SetSolidPlayers( idx - 1 );
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecDest, PM_STUDIO_BOX, -1, &tr );
gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecDest, PM_NORMAL, -1, &tr );
gEngfuncs.pEventAPI->EV_PopPMStates();
@ -1004,14 +1007,14 @@ void EV_FireGauss( event_args_t *args )
gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 );
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
gEngfuncs.pEventAPI->EV_PlayerTrace( start, vecDest, PM_STUDIO_BOX, -1, &beam_tr );
gEngfuncs.pEventAPI->EV_PlayerTrace( start, vecDest, PM_NORMAL, -1, &beam_tr );
if( !beam_tr.allsolid )
{
vec3_t delta;
// trace backwards to find exit point
gEngfuncs.pEventAPI->EV_PlayerTrace( beam_tr.endpos, tr.endpos, PM_STUDIO_BOX, -1, &beam_tr );
gEngfuncs.pEventAPI->EV_PlayerTrace( beam_tr.endpos, tr.endpos, PM_NORMAL, -1, &beam_tr );
VectorSubtract( beam_tr.endpos, tr.endpos, delta );
@ -1214,7 +1217,7 @@ void EV_FireCrossbow2( event_args_t *args )
// Now add in all of the players.
gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 );
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr );
gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_NORMAL, -1, &tr );
//We hit something
if( tr.fraction < 1.0f )
@ -1450,7 +1453,7 @@ void EV_EgonFire( event_args_t *args )
gEngfuncs.pEventAPI->EV_SetSolidPlayers( idx - 1 );
gEngfuncs.pEventAPI->EV_SetTraceHull( 2 );
gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr );
gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_NORMAL, -1, &tr );
gEngfuncs.pEventAPI->EV_PopPMStates();
@ -1752,6 +1755,65 @@ void EV_TrainPitchAdjust( event_args_t *args )
}
}
void EV_VehiclePitchAdjust( event_args_t *args )
{
int idx;
vec3_t origin;
unsigned short us_params;
int noise;
float m_flVolume;
int pitch;
int stop;
const char *pszSound;
idx = args->entindex;
VectorCopy( args->origin, origin );
us_params = (unsigned short)args->iparam1;
stop = args->bparam1;
m_flVolume = (float)( us_params & 0x003f ) / 40.0f;
noise = (int)( ( ( us_params ) >> 12 ) & 0x0007 );
pitch = (int)( 10.0f * (float)( ( us_params >> 6 ) & 0x003f ) );
switch( noise )
{
case 1:
pszSound = "plats/vehicle1.wav";
break;
case 2:
pszSound = "plats/vehicle2.wav";
break;
case 3:
pszSound = "plats/vehicle3.wav";
break;
case 4:
pszSound = "plats/vehicle4.wav";
break;
case 5:
pszSound = "plats/vehicle6.wav";
break;
case 6:
pszSound = "plats/vehicle7.wav";
break;
default:
// no sound
return;
}
if( stop )
{
gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, pszSound );
}
else
{
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, pszSound, m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, pitch );
}
}
int EV_TFC_IsAllyTeam( int iTeam1, int iTeam2 )
{
return 0;

View File

@ -213,9 +213,9 @@ BOOL CBaseMonster::FindLateralCover( const Vector &vecThreat, const Vector &vecV
Vector CBaseMonster::ShootAtEnemy( const Vector &shootOrigin ) { return g_vecZero; }
BOOL CBaseMonster::FacingIdeal( void ) { return FALSE; }
BOOL CBaseMonster::FCanActiveIdle( void ) { return FALSE; }
void CBaseMonster::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ) { }
void CBaseMonster::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ) { }
void CBaseMonster::SentenceStop( void ) { }
void CBaseToggle::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ) { }
void CBaseToggle::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ) { }
void CBaseToggle::SentenceStop( void ) { }
void CBaseMonster::CorpseFallThink( void ) { }
void CBaseMonster::MonsterInitDead( void ) { }
BOOL CBaseMonster::BBoxFlat( void ) { return TRUE; }

View File

@ -40,6 +40,7 @@ void EV_TripmineFire( struct event_args_s *args );
void EV_SnarkFire( struct event_args_s *args );
void EV_TrainPitchAdjust( struct event_args_s *args );
void EV_VehiclePitchAdjust( event_args_t *args );
}
/*
@ -76,4 +77,5 @@ void Game_HookEvents( void )
gEngfuncs.pfnHookEvent( "events/firehornet.sc", EV_HornetGunFire );
gEngfuncs.pfnHookEvent( "events/tripfire.sc", EV_TripmineFire );
gEngfuncs.pfnHookEvent( "events/snarkfire.sc", EV_SnarkFire );
gEngfuncs.pfnHookEvent( "events/vehicle.sc", EV_VehiclePitchAdjust );
}

View File

@ -436,7 +436,7 @@ void CHud::Init( void )
m_pCvarStealMouse = CVAR_CREATE( "hud_capturemouse", "1", FCVAR_ARCHIVE );
m_pCvarDraw = CVAR_CREATE( "hud_draw", "1", FCVAR_ARCHIVE );
cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" );
cl_viewbob = CVAR_CREATE( "cl_viewbob", "0", FCVAR_ARCHIVE );
cl_viewbob = CVAR_CREATE( "cl_viewbob", "1", FCVAR_ARCHIVE );
m_pSpriteList = NULL;
m_pShinySurface = NULL; //LRC
@ -488,6 +488,8 @@ void CHud::Init( void )
m_Menu.Init();
MsgFunc_ResetHUD( 0, 0, NULL );
ClientCmd( "richpresence_gamemode\n" );
ClientCmd( "richpresence_update\n" );
}
// CHud destructor

View File

@ -215,6 +215,11 @@ int CHud::MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf )
BEGIN_READ( pbuf, iSize );
m_Teamplay = READ_BYTE();
if( m_Teamplay )
ClientCmd( "richpresence_gamemode Teamplay\n" );
else
ClientCmd( "richpresence_gamemode\n" );
ClientCmd( "richpresence_update\n" );
return 1;
}

View File

@ -87,6 +87,11 @@ void CHud::Think( void )
// only let players adjust up in fov, and only if they are not overriden by something else
m_iFOV = Q_max( default_fov->value, 90 );
}
if( gEngfuncs.IsSpectateOnly() )
{
m_iFOV = gHUD.m_Spectator.GetFOV(); // default_fov->value;
}
}
//LRC - fog fading values

View File

@ -37,8 +37,6 @@ extern "C" float vJumpAngles[3];
extern void V_GetInEyePos( int entity, float * origin, float * angles );
extern void V_ResetChaseCam();
extern void V_GetChasePos( int target, float * cl_angles, float * origin, float * angles );
extern void VectorAngles( const float *forward, float *angles );
extern "C" void NormalizeAngles( float *angles );
extern float * GetClientColor( int clientIndex );
extern vec3_t v_origin; // last view origin
@ -46,6 +44,37 @@ extern vec3_t v_angles; // last view angle
extern vec3_t v_cl_angles; // last client/mouse angle
extern vec3_t v_sim_org; // last sim origin
#if 0
const char *GetSpectatorLabel( int iMode )
{
switch( iMode )
{
case OBS_CHASE_LOCKED:
return "#OBS_CHASE_LOCKED";
case OBS_CHASE_FREE:
return "#OBS_CHASE_FREE";
case OBS_ROAMING:
return "#OBS_ROAMING";
case OBS_IN_EYE:
return "#OBS_IN_EYE";
case OBS_MAP_FREE:
return "#OBS_MAP_FREE";
case OBS_MAP_CHASE:
return "#OBS_MAP_CHASE";
case OBS_NONE:
default:
return "#OBS_NONE";
}
}
#endif
void SpectatorMode( void )
{
if( gEngfuncs.Cmd_Argc() <= 1 )
@ -152,6 +181,7 @@ int CHudSpectator::Init()
m_flNextObserverInput = 0.0f;
m_zoomDelta = 0.0f;
m_moveDelta = 0.0f;
m_FOV = 90.0f;
m_chatEnabled = ( gHUD.m_SayText.m_HUD_saytext->value != 0 );
iJumpSpectator = 0;
@ -363,6 +393,178 @@ void CHudSpectator::SetSpectatorStartPosition()
iJumpSpectator = 1; // jump anyway
}
void CHudSpectator::SetCameraView( vec3_t pos, vec3_t angle, float fov )
{
m_FOV = fov;
VectorCopy( pos, vJumpOrigin );
VectorCopy( angle, vJumpAngles );
gEngfuncs.SetViewAngles( vJumpAngles );
iJumpSpectator = 1; // jump anyway
}
void CHudSpectator::AddWaypoint( float time, vec3_t pos, vec3_t angle, float fov, int flags )
{
if( flags == 0 && time == 0.0f )
{
// switch instantly to this camera view
SetCameraView( pos, angle, fov );
return;
}
if( m_NumWayPoints >= MAX_CAM_WAYPOINTS )
{
gEngfuncs.Con_Printf( "Too many camera waypoints!\n" );
return;
}
VectorCopy( angle, m_CamPath[m_NumWayPoints].angle );
VectorCopy( pos, m_CamPath[m_NumWayPoints].position );
m_CamPath[m_NumWayPoints].flags = flags;
m_CamPath[m_NumWayPoints].fov = fov;
m_CamPath[m_NumWayPoints].time = time;
gEngfuncs.Con_DPrintf( "Added waypoint %i\n", m_NumWayPoints );
m_NumWayPoints++;
}
void CHudSpectator::SetWayInterpolation( cameraWayPoint_t *prev, cameraWayPoint_t *start, cameraWayPoint_t *end, cameraWayPoint_t *next )
{
m_WayInterpolation.SetViewAngles( start->angle, end->angle );
m_WayInterpolation.SetFOVs( start->fov, end->fov );
m_WayInterpolation.SetSmoothing( ( start->flags & DRC_FLAG_SLOWSTART ) != 0,
( start->flags & DRC_FLAG_SLOWEND ) != 0 );
if( prev && next )
{
m_WayInterpolation.SetWaypoints( &prev->position, start->position, end->position, &next->position );
}
else if( prev )
{
m_WayInterpolation.SetWaypoints( &prev->position, start->position, end->position, NULL );
}
else if( next )
{
m_WayInterpolation.SetWaypoints( NULL, start->position, end->position, &next->position );
}
else
{
m_WayInterpolation.SetWaypoints( NULL, start->position, end->position, NULL );
}
}
bool CHudSpectator::GetDirectorCamera( vec3_t &position, vec3_t &angle )
{
float now = gHUD.m_flTime;
float fov = 90.0f;
if( m_ChaseEntity )
{
cl_entity_t *ent = gEngfuncs.GetEntityByIndex( m_ChaseEntity );
if( ent )
{
vec3_t vt = ent->curstate.origin;
if( m_ChaseEntity <= gEngfuncs.GetMaxClients())
{
if( ent->curstate.solid == SOLID_NOT )
{
vt[2]+= -8 ; // PM_DEAD_VIEWHEIGHT
}
else if( ent->curstate.usehull == 1 )
{
vt[2]+= 12; // VEC_DUCK_VIEW;
}
else
{
vt[2]+= 28; // DEFAULT_VIEWHEIGHT
}
}
vt = vt - position;
VectorAngles( vt, angle );
angle[0] = -angle[0];
return true;
}
else
{
return false;
}
}
if( !m_IsInterpolating )
return false;
if( m_WayPoint < 0 || m_WayPoint >= ( m_NumWayPoints - 1 ))
return false;
cameraWayPoint_t *wp1 = &m_CamPath[m_WayPoint];
cameraWayPoint_t *wp2 = &m_CamPath[m_WayPoint+1];
if( now < wp1->time )
return false;
while( now > wp2->time )
{
// go to next waypoint, if possible
m_WayPoint++;
if( m_WayPoint >= ( m_NumWayPoints - 1 ))
{
m_IsInterpolating = false;
return false; // there is no following waypoint
}
wp1 = wp2;
wp2 = &m_CamPath[m_WayPoint + 1];
if( m_WayPoint > 0 )
{
// we have a predecessor
if( m_WayPoint < ( m_NumWayPoints - 1 ))
{
// we have also a successor
SetWayInterpolation( &m_CamPath[m_WayPoint - 1], wp1, wp2, &m_CamPath[m_WayPoint + 2] );
}
else
{
SetWayInterpolation( &m_CamPath[m_WayPoint - 1], wp1, wp2, NULL );
}
}
else if( m_WayPoint < ( m_NumWayPoints - 1 ))
{
// we only have a successor
SetWayInterpolation( NULL, wp1, wp2, &m_CamPath[m_WayPoint + 2] );
}
else
{
// we have only two waypoints
SetWayInterpolation( NULL, wp1, wp2, NULL );
}
}
if( wp2->time <= wp1->time )
return false;
float fraction = ( now - wp1->time ) / ( wp2->time - wp1->time );
if( fraction < 0.0f )
fraction = 0.0f;
else if( fraction > 1.0f )
fraction = 1.0f;
m_WayInterpolation.Interpolate( fraction, position, angle, &fov );
// gEngfuncs.Con_Printf( "Interpolate time: %.2f, fraction %.2f, point : %.2f,%.2f,%.2f\n", now, fraction, position[0], position[1], position[2] );
SetCameraView( position, angle, fov );
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Loads new icons
//-----------------------------------------------------------------------------
@ -377,9 +579,21 @@ int CHudSpectator::VidInit()
m_hsprCamera = SPR_Load( "sprites/camera.spr" );
m_hCrosshair = SPR_Load( "sprites/crosshairs.spr" );
m_lastPrimaryObject = m_lastSecondaryObject = 0;
m_flNextObserverInput = 0.0f;
m_lastHudMessage = 0;
m_iSpectatorNumber = 0;
iJumpSpectator = 0;
g_iUser1 = g_iUser2 = 0;
return 1;
}
float CHudSpectator::GetFOV( void )
{
return m_FOV;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : flTime -
@ -427,8 +641,11 @@ int CHudSpectator::Draw( float flTime )
return 1;
// make sure we have player info
#if USE_VGUI
gViewPort->GetAllPlayersInfo();
#else
gHUD.GetAllPlayersInfo();
#endif
// loop through all the players and draw additional infos to their sprites on the map
for( int i = 0; i < MAX_PLAYERS; i++ )
{
@ -461,8 +678,10 @@ int CHudSpectator::Draw( float flTime )
void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
{
float value;
float f1, f2;
char *string;
vec3_t v1, v2;
int i1, i2, i3;
BEGIN_READ( pbuf, iSize );
@ -479,7 +698,7 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
gHUD.MsgFunc_InitHUD( NULL, 0, NULL );
gHUD.MsgFunc_ResetHUD( NULL, 0, NULL );
break;
case DRC_CMD_EVENT:
case DRC_CMD_EVENT: // old director style message
m_lastPrimaryObject = READ_WORD();
m_lastSecondaryObject = READ_WORD();
m_iObserverFlags = READ_LONG();
@ -502,19 +721,22 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
}
break;
case DRC_CMD_CAMERA:
v1[0] = READ_COORD(); // position
v1[1] = READ_COORD();
v1[2] = READ_COORD(); // vJumpOrigin
v1[0] = READ_COORD(); // view angle
v1[1] = READ_COORD(); // vJumpAngles
v1[2] = READ_COORD();
f1 = READ_BYTE(); // fov
i1 = READ_WORD(); // target
if( m_autoDirector->value )
{
vJumpOrigin[0] = READ_COORD(); // position
vJumpOrigin[1] = READ_COORD();
vJumpOrigin[2] = READ_COORD();
vJumpAngles[0] = READ_COORD(); // view angle
vJumpAngles[1] = READ_COORD();
vJumpAngles[2] = READ_COORD();
gEngfuncs.SetViewAngles( vJumpAngles );
iJumpSpectator = 1;
SetModes( OBS_ROAMING, -1 );
SetCameraView( v1, v2, f1 );
m_ChaseEntity = i1;
}
break;
case DRC_CMD_MESSAGE:
@ -551,13 +773,13 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
break;
case DRC_CMD_SOUND:
string = READ_STRING();
value = READ_FLOAT();
f1 = READ_FLOAT();
// gEngfuncs.Con_Printf("DRC_CMD_FX_SOUND: %s %.2f\n", string, value );
gEngfuncs.pEventAPI->EV_PlaySound( 0, v_origin, CHAN_BODY, string, value, ATTN_NORM, 0, PITCH_NORM );
// gEngfuncs.Con_Printf("DRC_CMD_FX_SOUND: %s %.2f\n", string, f1 );
gEngfuncs.pEventAPI->EV_PlaySound( 0, v_origin, CHAN_BODY, string, f1, ATTN_NORM, 0, PITCH_NORM );
break;
case DRC_CMD_TIMESCALE:
value = READ_FLOAT();
f1 = READ_FLOAT();
break;
case DRC_CMD_STATUS:
READ_LONG(); // total number of spectator slots
@ -574,13 +796,71 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
gViewPort->UpdateSpectatorPanel();
#endif
break;
case DRC_CMD_FADE:
break;
case DRC_CMD_STUFFTEXT:
gEngfuncs.pfnFilteredClientCmd( READ_STRING() );
break;
case DRC_CMD_CAMPATH:
v1[0] = READ_COORD(); // position
v1[1] = READ_COORD();
v1[2] = READ_COORD(); // vJumpOrigin
v2[0] = READ_COORD(); // view angle
v2[1] = READ_COORD(); // vJumpAngles
v2[2] = READ_COORD();
f1 = READ_BYTE(); // FOV
i1 = READ_BYTE(); // flags
if( m_autoDirector->value )
{
SetModes( OBS_ROAMING, -1 );
SetCameraView( v1, v2, f1 );
}
break;
case DRC_CMD_WAYPOINTS:
i1 = READ_BYTE();
m_NumWayPoints = 0;
m_WayPoint = 0;
for( i2 = 0; i2 < i1; i2++ )
{
f1 = gHUD.m_flTime + (float)( READ_SHORT()) / 100.0f;
v1[0] = READ_COORD(); // position
v1[1] = READ_COORD();
v1[2] = READ_COORD(); // vJumpOrigin
v2[0] = READ_COORD(); // view angle
v2[1] = READ_COORD(); // vJumpAngles
v2[2] = READ_COORD();
f2 = READ_BYTE(); // fov
i3 = READ_BYTE(); // flags
AddWaypoint( f1, v1, v2, f2, i3 );
}
// gEngfuncs.Con_Printf( "CHudSpectator::DirectorMessage: waypoints %i.\n", m_NumWayPoints );
if( !m_autoDirector->value )
{
// ignore waypoints
m_NumWayPoints = 0;
break;
}
SetModes( OBS_ROAMING, -1 );
m_IsInterpolating = true;
if( m_NumWayPoints > 2 )
{
SetWayInterpolation( NULL, &m_CamPath[0], &m_CamPath[1], &m_CamPath[2] );
}
else
{
SetWayInterpolation( NULL, &m_CamPath[0], &m_CamPath[1], NULL );
}
break;
default:
gEngfuncs.Con_DPrintf( "CHudSpectator::DirectorMessage: unknown command %i.\n", cmd );
break;
}
}
@ -595,9 +875,10 @@ void CHudSpectator::FindNextPlayer( bool bReverse )
// if we are NOT in HLTV mode, spectator targets are set on server
if( !gEngfuncs.IsSpectateOnly() )
{
char cmdstring[32];
char cmdstring[256];
// forward command to server
sprintf( cmdstring, "follownext %i", bReverse ? 1 : 0 );
_snprintf( cmdstring, sizeof( cmdstring ) - 1,"follownext %i", bReverse ? 1 : 0 );
cmdstring[sizeof( cmdstring ) - 1] = '\0';
gEngfuncs.pfnServerCmd( cmdstring );
return;
}
@ -614,8 +895,11 @@ void CHudSpectator::FindNextPlayer( bool bReverse )
int iDir = bReverse ? -1 : 1;
// make sure we have player info
#if USE_VGUI
gViewPort->GetAllPlayersInfo();
#else
gHUD.GetAllPlayersInfo();
#endif
do
{
iCurrent += iDir;
@ -656,7 +940,7 @@ void CHudSpectator::FindNextPlayer( bool bReverse )
#endif
}
void CHudSpectator::FindPlayer(const char *name)
void CHudSpectator::FindPlayer( const char *name )
{
// MOD AUTHORS: Modify the logic of this function if you want to restrict the observer to watching
// only a subset of the players. e.g. Make it check the target's team.
@ -664,18 +948,22 @@ void CHudSpectator::FindPlayer(const char *name)
// if we are NOT in HLTV mode, spectator targets are set on server
if ( !gEngfuncs.IsSpectateOnly() )
{
char cmdstring[32];
char cmdstring[256];
// forward command to server
sprintf(cmdstring,"follow %s",name);
gEngfuncs.pfnServerCmd(cmdstring);
_snprintf( cmdstring, sizeof( cmdstring ) - 1, "follow %s", name );
cmdstring[sizeof( cmdstring ) - 1] = '\0';
gEngfuncs.pfnServerCmd( cmdstring );
return;
}
g_iUser2 = 0;
// make sure we have player info
#if USE_VGUI
gViewPort->GetAllPlayersInfo();
#else
gHUD.GetAllPlayersInfo();
#endif
cl_entity_t * pEnt = NULL;
for (int i = 1; i < MAX_PLAYERS; i++ )
@ -847,12 +1135,20 @@ void CHudSpectator::SetModes( int iNewMainMode, int iNewInsetMode )
return;
}
// main modes ettings will override inset window settings
m_IsInterpolating = false;
m_ChaseEntity = 0;
// main modes settings will override inset window settings
if( iNewMainMode != g_iUser1 )
{
// if we are NOT in HLTV mode, main spectator mode is set on server
if( !gEngfuncs.IsSpectateOnly() )
{
char cmdstring[256];
// forward command to server
_snprintf( cmdstring, sizeof( cmdstring ) - 1,"specmode %i", iNewMainMode );
cmdstring[sizeof( cmdstring ) - 1] = '\0';
gEngfuncs.pfnServerCmd( cmdstring );
return;
}
@ -1548,8 +1844,9 @@ void CHudSpectator::CheckSettings()
if( gEngfuncs.IsSpectateOnly() )
{
// tell proxy our new chat mode
char chatcmd[32];
sprintf( chatcmd, "ignoremsg %i", m_chatEnabled ? 0 : 1 );
char chatcmd[256];
_snprintf( chatcmd, sizeof( chatcmd ) - 1, "ignoremsg %i", m_chatEnabled ? 0 : 1 );
chatcmd[sizeof( chatcmd ) - 1] = '\0';
gEngfuncs.pfnServerCmd( chatcmd );
}
}
@ -1626,6 +1923,12 @@ void CHudSpectator::Reset()
memset( &m_OverviewEntities, 0, sizeof(m_OverviewEntities) );
m_FOV = 90.0f;
m_IsInterpolating = false;
m_ChaseEntity = 0;
SetSpectatorStartPosition();
}
@ -1648,7 +1951,7 @@ void CHudSpectator::InitHUDData()
Reset();
SetModes( OBS_CHASE_FREE, INSET_OFF );
SetModes( OBS_CHASE_LOCKED, INSET_OFF );
g_iUser2 = 0; // fake not target until first camera command

View File

@ -10,6 +10,7 @@
#define HUD_SPECTATOR_H
#include "cl_entity.h"
#include "interpolation.h"
#define INSET_OFF 0
#define INSET_CHASE_FREE 1
@ -22,6 +23,9 @@
#define OVERVIEW_TILE_SIZE 128 // don't change this
#define OVERVIEW_MAX_LAYERS 1
extern void VectorAngles( const float *forward, float *angles );
extern "C" void NormalizeAngles( float *angles );
//-----------------------------------------------------------------------------
// Purpose: Handles the drawing of the spectator stuff (camera & top-down map and all the things on it )
//-----------------------------------------------------------------------------
@ -49,7 +53,17 @@ typedef struct overviewEntity_s
double killTime;
} overviewEntity_t;
typedef struct cameraWayPoint_s
{
float time;
vec3_t position;
vec3_t angle;
float fov;
int flags;
} cameraWayPoint_t;
#define MAX_OVERVIEW_ENTITIES 128
#define MAX_CAM_WAYPOINTS 32
class CHudSpectator : public CHudBase
{
@ -73,7 +87,7 @@ public:
void HandleButtonsDown( int ButtonPressed );
void HandleButtonsUp( int ButtonPressed );
void FindNextPlayer( bool bReverse );
void FindPlayer(const char *name);
void FindPlayer( const char *name );
void DirectorMessage( int iSize, void *pbuf );
void SetSpectatorStartPosition();
int Init();
@ -81,6 +95,13 @@ public:
int Draw( float flTime );
void AddWaypoint( float time, vec3_t pos, vec3_t angle, float fov, int flags );
void SetCameraView( vec3_t pos, vec3_t angle, float fov );
float GetFOV();
bool GetDirectorCamera( vec3_t &position, vec3_t &angle );
void SetWayInterpolation( cameraWayPoint_t *prev, cameraWayPoint_t *start, cameraWayPoint_t *end, cameraWayPoint_t *next );
int m_iDrawCycle;
client_textmessage_t m_HUDMessages[MAX_SPEC_HUD_MESSAGES];
char m_HUDMessageText[MAX_SPEC_HUD_MESSAGES][128];
@ -100,8 +121,13 @@ public:
qboolean m_chatEnabled;
qboolean m_IsInterpolating;
int m_ChaseEntity; // if != 0, follow this entity with viewangles
int m_WayPoint; // current waypoint 1
int m_NumWayPoints; // current number of waypoints
vec3_t m_cameraOrigin; // a help camera
vec3_t m_cameraAngles; // and it's angles
CInterpolation m_WayInterpolation;
private:
vec3_t m_vPlayerPos[MAX_PLAYERS];
@ -119,9 +145,11 @@ private:
struct model_s *m_MapSprite; // each layer image is saved in one sprite, where each tile is a sprite frame
float m_flNextObserverInput;
float m_FOV;
float m_zoomDelta;
float m_moveDelta;
int m_lastPrimaryObject;
int m_lastSecondaryObject;
cameraWayPoint_t m_CamPath[MAX_CAM_WAYPOINTS];
};
#endif // SPECTATOR_H

View File

@ -15,7 +15,7 @@
#include "camera.h"
#include "in_defs.h"
#if _WIN32
#if XASH_WIN32
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define WIN32_EXTRA_LEAN
#define HSPRITE WINDOWS_HSPRITE

View File

@ -23,7 +23,7 @@
#include "keydefs.h"
#include "view.h"
#if !_WIN32
#if !XASH_WIN32
#define USE_SDL2 1
#endif
@ -114,7 +114,7 @@ static SDLFunction sdlFunctions[] = {
};
#endif
#if _WIN32
#if XASH_WIN32
#include <process.h>
#else
typedef unsigned int DWORD;
@ -149,7 +149,7 @@ extern cvar_t *cl_forwardspeed;
extern cvar_t *cl_pitchspeed;
extern cvar_t *cl_movespeedkey;
#if _WIN32
#if XASH_WIN32
static cvar_t* m_rawinput = NULL;
static double s_flRawInputUpdateTime = 0.0f;
static bool m_bRawInput = false;
@ -157,7 +157,7 @@ static bool m_bMouseThread = false;
bool isMouseRelative = false;
#endif
#if _WIN32
#if XASH_WIN32
#include "progdefs.h"
#endif
@ -184,7 +184,7 @@ static cvar_t *m_customaccel_max;
//Mouse move is raised to this power before being scaled by scale factor
static cvar_t *m_customaccel_exponent;
#if _WIN32
#if XASH_WIN32
// if threaded mouse is enabled then the time to sleep between polls
static cvar_t *m_mousethread_sleep;
#endif
@ -218,7 +218,7 @@ enum _ControlList
AxisTurn
};
#if !USE_SDL2 && _WIN32
#if !USE_SDL2 && XASH_WIN32
DWORD dwAxisFlags[JOY_MAX_AXES] =
{
JOY_RETURNX,
@ -234,7 +234,7 @@ DWORD dwAxisMap[ JOY_MAX_AXES ];
DWORD dwControlMap[ JOY_MAX_AXES ];
#if USE_SDL2
int pdwRawValue[ JOY_MAX_AXES ];
#elif _WIN32
#elif XASH_WIN32
PDWORD pdwRawValue[ JOY_MAX_AXES ];
#endif
DWORD joy_oldbuttonstate, joy_oldpovstate;
@ -244,7 +244,7 @@ DWORD joy_numbuttons;
#if USE_SDL2
SDL_GameController *s_pJoystick = NULL;
#elif _WIN32
#elif XASH_WIN32
DWORD joy_flags;
static JOYINFOEX ji;
#endif
@ -276,7 +276,7 @@ cvar_t *joy_wwhack2;
int joy_avail, joy_advancedinit, joy_haspov;
#if _WIN32
#if XASH_WIN32
unsigned int s_hMouseThreadId = 0;
HANDLE s_hMouseThread = 0;
HANDLE s_hMouseQuitEvent = 0;
@ -300,7 +300,7 @@ void Force_CenterView_f (void)
}
}
#if _WIN32
#if XASH_WIN32
LONG mouseThreadActive = 0;
LONG mouseThreadCenterX = 0;
@ -382,7 +382,7 @@ void IN_SetMouseMode(bool enable)
if(enable)
{
#if _WIN32
#if XASH_WIN32
if (mouseparmsvalid)
restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0);
@ -402,7 +402,7 @@ void IN_SetMouseMode(bool enable)
}
else
{
#if _WIN32
#if XASH_WIN32
if(isMouseRelative)
{
#if USE_SDL2
@ -423,7 +423,7 @@ void IN_SetMouseMode(bool enable)
void IN_SetVisibleMouse(bool visible)
{
#if _WIN32
#if XASH_WIN32
bool lockEntered = MouseThread_ActiveLock_Enter();
#endif
@ -431,7 +431,7 @@ void IN_SetVisibleMouse(bool visible)
IN_SetMouseMode(!visible);
#if _WIN32
#if XASH_WIN32
UpdateMouseThreadActive();
if(lockEntered) MouseThread_ActiveLock_Exit();
#endif
@ -448,7 +448,7 @@ void GoldSourceInput::IN_ActivateMouse (void)
{
if (mouseinitialized)
{
#if _WIN32
#if XASH_WIN32
bool lockEntered = MouseThread_ActiveLock_Enter();
#endif
@ -456,7 +456,7 @@ void GoldSourceInput::IN_ActivateMouse (void)
mouseactive = 1;
#if _WIN32
#if XASH_WIN32
UpdateMouseThreadActive();
if(lockEntered) MouseThread_ActiveLock_Exit();
#endif
@ -476,7 +476,7 @@ void GoldSourceInput::IN_DeactivateMouse (void)
{
if (mouseinitialized)
{
#if _WIN32
#if XASH_WIN32
bool lockEntered = MouseThread_ActiveLock_Enter();
#endif
@ -484,7 +484,7 @@ void GoldSourceInput::IN_DeactivateMouse (void)
mouseactive = 0;
#if _WIN32
#if XASH_WIN32
UpdateMouseThreadActive();
if(lockEntered) MouseThread_ActiveLock_Exit();
#endif
@ -502,7 +502,7 @@ void GoldSourceInput::IN_StartupMouse (void)
return;
mouseinitialized = 1;
#if _WIN32
#if XASH_WIN32
mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0);
if (mouseparmsvalid)
@ -537,7 +537,7 @@ void GoldSourceInput::IN_Shutdown (void)
{
IN_DeactivateMouse ();
#if _WIN32
#if XASH_WIN32
if ( s_hMouseQuitEvent )
{
SetEvent( s_hMouseQuitEvent );
@ -597,7 +597,7 @@ FIXME: Call through to engine?
void IN_ResetMouse( void )
{
// no work to do in SDL
#if _WIN32
#if XASH_WIN32
// reset only if mouse is active and not in visible mode:
if(mouseactive && !iVisibleMouse && gEngfuncs.GetWindowCenterX && gEngfuncs.GetWindowCenterY)
{
@ -712,7 +712,7 @@ void GoldSourceInput::IN_GetMouseDelta( int *pOutX, int *pOutY)
if(active)
{
int deltaX, deltaY;
#if _WIN32
#if XASH_WIN32
if ( !m_bRawInput )
{
if ( m_bMouseThread )
@ -746,7 +746,7 @@ void GoldSourceInput::IN_GetMouseDelta( int *pOutX, int *pOutY)
#endif
}
#if _WIN32
#if XASH_WIN32
if ( !m_bRawInput )
{
if ( m_bMouseThread )
@ -771,7 +771,7 @@ void GoldSourceInput::IN_GetMouseDelta( int *pOutX, int *pOutY)
my_accum = 0;
// reset mouse position if required, so there is room to move:
#if _WIN32
#if XASH_WIN32
// do not reset if mousethread would do it:
if ( m_bRawInput || !m_bMouseThread )
#else
@ -779,7 +779,7 @@ void GoldSourceInput::IN_GetMouseDelta( int *pOutX, int *pOutY)
#endif
IN_ResetMouse();
#if _WIN32
#if XASH_WIN32
// update m_bRawInput occasionally:
const float currentTime = gEngfuncs.GetClientTime();
if ( currentTime - s_flRawInputUpdateTime > 1.0f || s_flRawInputUpdateTime == 0.0f )
@ -929,7 +929,7 @@ void GoldSourceInput::IN_Accumulate (void)
{
if (mouseactive)
{
#if _WIN32
#if XASH_WIN32
if ( !m_bRawInput )
{
if ( !m_bMouseThread )
@ -957,7 +957,7 @@ void GoldSourceInput::IN_Accumulate (void)
}
// force the mouse to the center, so there's room to move
#if _WIN32
#if XASH_WIN32
// do not reset if mousethread would do it:
if ( m_bRawInput || !m_bMouseThread )
#else
@ -1030,7 +1030,7 @@ void IN_StartupJoystick (void)
{
gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n");
}
#elif _WIN32
#elif XASH_WIN32
int numdevs;
JOYCAPS jc;
MMRESULT mmr;
@ -1102,7 +1102,7 @@ int RawValuePointer (int axis)
}
}
#elif _WIN32
#elif XASH_WIN32
PDWORD RawValuePointer (int axis)
{
switch (axis)
@ -1185,7 +1185,7 @@ void Joy_AdvancedUpdate_f (void)
dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS;
}
#if !USE_SDL2 && _WIN32
#if !USE_SDL2 && XASH_WIN32
// compute the axes to collect from DirectInput
joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV;
for (i = 0; i < JOY_MAX_AXES; i++)
@ -1231,7 +1231,7 @@ void GoldSourceInput::IN_Commands (void)
{
pdwRawValue[i] = RawValuePointer(i);
}
#elif _WIN32
#elif XASH_WIN32
buttonstate = ji.dwButtons;
#endif
@ -1257,7 +1257,7 @@ void GoldSourceInput::IN_Commands (void)
// this avoids any potential problems related to moving from one
// direction to another without going through the center position
povstate = 0;
#if !USE_SDL2 && _WIN32
#if !USE_SDL2 && XASH_WIN32
if(ji.dwPOV != JOY_POVCENTERED)
{
if (ji.dwPOV == JOY_POVFORWARD)
@ -1298,7 +1298,7 @@ int IN_ReadJoystick (void)
#if USE_SDL2
safe_pfnSDL_JoystickUpdate();
return 1;
#elif _WIN32
#elif XASH_WIN32
memset (&ji, 0, sizeof(ji));
ji.dwSize = sizeof(ji);
ji.dwFlags = joy_flags;
@ -1377,7 +1377,7 @@ void IN_JoyMove ( float frametime, usercmd_t *cmd )
// get the floating point zero-centered, potentially-inverted data for the current axis
#if USE_SDL2
fAxisValue = (float)pdwRawValue[i];
#elif _WIN32
#elif XASH_WIN32
fAxisValue = (float) *pdwRawValue[i];
fAxisValue -= 32768.0;
#endif
@ -1571,7 +1571,7 @@ void GoldSourceInput::IN_Init (void)
m_customaccel_max = gEngfuncs.pfnRegisterVariable ( "m_customaccel_max", "0", FCVAR_ARCHIVE );
m_customaccel_exponent = gEngfuncs.pfnRegisterVariable ( "m_customaccel_exponent", "1", FCVAR_ARCHIVE );
#if _WIN32
#if XASH_WIN32
m_rawinput = gEngfuncs.pfnGetCvarPointer("m_rawinput");
m_bRawInput = m_rawinput && m_rawinput->value != 0;
m_bMouseThread = gEngfuncs.CheckParm ("-mousethread", NULL ) != NULL;
@ -1603,7 +1603,7 @@ void GoldSourceInput::IN_Init (void)
#endif
#if USE_SDL2
#if __APPLE__
#if XASH_APPLE
#define SDL2_FULL_LIBNAME "libsdl2-2.0.0.dylib"
#else
#define SDL2_FULL_LIBNAME "libSDL2-2.0.so.0"

View File

@ -1,7 +1,4 @@
#pragma once
#include "build.h"
#if !defined(INPUT_MOUSE_H)
#define INPUT_MOUSE_H
#include "cl_dll.h"
@ -51,7 +48,7 @@ protected:
#if GOLDSOURCE_SUPPORT && ( XASH_WIN32 || ( XASH_LINUX && !XASH_ANDROID ) || XASH_APPLE ) && XASH_X86
#define SUPPORT_GOLDSOURCE_INPUT 1
#if _WIN32
#if XASH_WIN32
#define HSPRITE WINDOWS_HSPRITE
#include <windows.h>
#undef HSPRITE

217
cl_dll/interpolation.cpp Normal file
View File

@ -0,0 +1,217 @@
/************ (C) Copyright 2003 Valve, L.L.C. All rights reserved. ***********
**
** The copyright to the contents herein is the property of Valve, L.L.C.
** The contents may be used and/or copied only with the written permission of
** Valve, L.L.C., or in accordance with the terms and conditions stipulated in
** the agreement/contract under which the contents have been supplied.
**
*******************************************************************************
**
** Contents:
**
** interpolation.cpp: implementation of the interpolation class
**
******************************************************************************/
#include "hud.h"
#include "cl_util.h"
#include "interpolation.h"
// = determinant of matrix a,b,c
#define Determinant( a, b, c ) ( (a)[2] * ( (b)[0]*(c)[1] - (b)[1]*(c)[0] ) + \
(a)[1] * ( (b)[2]*(c)[0] - (b)[0]*(c)[2] ) + \
(a)[0] * ( (b)[1]*(c)[2] - (b)[2]*(c)[1] ) )
// solve 3 vector linear system of equations v0 = x*v1 + y*v2 + z*v3 (if possible)
bool SolveLSE( vec3_t v0, vec3_t v1, vec3_t v2, vec3_t v3, float * x, float * y, float * z )
{
float d = Determinant( v1, v2, v3 );
if( d == 0.0f )
return false;
if( x )
*x = Determinant( v0, v2, v3 ) / d;
if( y )
*y= Determinant( v1, v0, v3 ) / d;
if( z )
*z= Determinant( v1, v2, v0 ) / d;
return true;
}
// p = closest point between vector lines a1+x*m1 and a2+x*m2
bool GetPointBetweenLines( vec3_t &p, vec3_t a1, vec3_t m1, vec3_t a2, vec3_t m2 )
{
float x, z;
vec3_t t1 = CrossProduct( m1, m2 );
vec3_t t2 = a2 - a1;
if( !SolveLSE( t2, m1, t1, m2, &x , NULL, &z ) )
return false;
t1 = a1 + x * m1;
t2 = a2 + ( -z ) * m2;
p = ( t1 + t2 ) / 2.0f;
return true;
}
// Bernstein Poynom B(u) with n = 2, i = 0
#define BernsteinPolynom20(u) ( ( 1.0f - u ) * ( 1.0f - u ))
#define BernsteinPolynom21(u) ( 2.0f * u * ( 1.0f - u ) )
#define BernsteinPolynom22(u) ( u * u )
CInterpolation::CInterpolation()
{
}
CInterpolation::~CInterpolation()
{
m_SmoothStart = m_SmoothEnd = false;
}
void CInterpolation::SetViewAngles( vec3_t start, vec3_t end )
{
m_StartAngle = start;
m_EndAngle = end;
NormalizeAngles( m_StartAngle );
NormalizeAngles( m_EndAngle );
}
void CInterpolation::SetFOVs( float start, float end )
{
m_StartFov = start;
m_EndFov = end;
}
void CInterpolation::SetWaypoints( vec3_t *prev, vec3_t start, vec3_t end, vec3_t *next )
{
m_StartPoint = start;
m_EndPoint = end;
vec3_t a, b, c, d;
if( !prev && !next )
{
// no direction given, straight linear interpolation
m_Center = ( m_StartPoint + m_EndPoint ) / 2.0f;
}
else if( !prev )
{
a = start - end;
float dist = a.Length() / 2.0f;
a = a.Normalize();
b = *next - end;
b = b.Normalize();
c = a - b;
c = c.Normalize();
m_Center = end + c * dist;
}
else if( !next )
{
a = *prev - start;
a = a.Normalize();
b = end - start;
float dist = b.Length() / 2.0f;
b = b.Normalize();
c = b - a;
c = c.Normalize();
m_Center = start + c * dist;
}
else
{
// we have a previous and a next point, great!
a = *prev - start;
a = a.Normalize();
b = end - start;
b = b.Normalize();
c = b - a;
a = start - end;
a = a.Normalize();
b = *next - end;
b = b.Normalize();
d = a - b;
GetPointBetweenLines( m_Center, start, c, end, d );
}
}
void CInterpolation::Interpolate( float t, vec3_t &point, vec3_t &angle, float *fov )
{
if( m_SmoothStart && m_SmoothEnd )
{
t = ( 1.0f - t ) * ( t * t ) + t * ( 1.0f - ( ( t - 1.0f ) * ( t - 1.0f )));
}
else if( m_SmoothStart )
{
t = t * t;
}
else if( m_SmoothEnd )
{
t = t - 1.0f;
t = -( t * t ) + 1;
}
if( point )
{
BezierInterpolatePoint( t, point );
}
if( angle )
{
InterpolateAngle( t, angle );
}
if( fov )
{
*fov = m_StartFov + ( t * ( m_EndFov - m_StartFov ));
}
}
void CInterpolation::BezierInterpolatePoint( float t, vec3_t &point )
{
point = m_StartPoint * BernsteinPolynom20( t );
point = point + m_Center * BernsteinPolynom21( t );
point = point + m_EndPoint * BernsteinPolynom22( t );
}
void CInterpolation::SetSmoothing( bool start, bool end )
{
m_SmoothStart = start;
m_SmoothEnd = end;
}
void CInterpolation::InterpolateAngle( float t, vec3_t &angle )
{
int i;
float ang1, ang2;
float d;
for( i = 0; i < 3; i++ )
{
ang1 = m_StartAngle[i];
ang2 = m_EndAngle[i];
d = ang2 - ang1;
if ( d > 180 )
{
d -= 360;
}
else if ( d < -180 )
{
d += 360;
}
angle[i] = ang1 + d * t;
}
NormalizeAngles( angle );
}

52
cl_dll/interpolation.h Normal file
View File

@ -0,0 +1,52 @@
/************ (C) Copyright 2003 Valve, L.L.C. All rights reserved. ***********
**
** The copyright to the contents herein is the property of Valve, L.L.C.
** The contents may be used and/or copied only with the written permission of
** Valve, L.L.C., or in accordance with the terms and conditions stipulated in
** the agreement/contract under which the contents have been supplied.
**
*******************************************************************************
**
** Contents:
**
** interpolation.h: Bezier inpolation classes
**
******************************************************************************/
#pragma once
#if !defined(INTERPOLATION_H)
#define INTERPOLATION_H
// interpolation class
class CInterpolation
{
public:
CInterpolation();
virtual ~CInterpolation();
void SetWaypoints( vec3_t *prev, vec3_t start, vec3_t end, vec3_t *next );
void SetViewAngles( vec3_t start, vec3_t end );
void SetFOVs( float start, float end );
void SetSmoothing( bool start, bool end );
// get interpolated point 0 =< t =< 1, 0 = start, 1 = end
void Interpolate( float t, vec3_t &point, vec3_t &angle, float * fov );
protected:
void BezierInterpolatePoint( float t, vec3_t &point );
void InterpolateAngle( float t, vec3_t &angle );
vec3_t m_StartPoint;
vec3_t m_EndPoint;
vec3_t m_StartAngle;
vec3_t m_EndAngle;
vec3_t m_Center;
float m_StartFov;
float m_EndFov;
bool m_SmoothStart;
bool m_SmoothEnd;
};
#endif // INTERPOLATION_H

View File

@ -100,10 +100,11 @@ int CHudSayText::Draw( float flTime )
int y = Y_START;
#if USE_VGUI
if( ( gViewPort && gViewPort->AllowedToPrintText() == FALSE ) || !m_HUD_saytext->value )
if( ( gViewPort && gViewPort->AllowedToPrintText() == FALSE ) )
return 1;
#endif
if ( !m_HUD_saytext->value )
return 1;
// make sure the scrolltime is within reasonable bounds, to guard against the clock being reset
flScrollTime = Q_min( flScrollTime, flTime + m_HUD_saytext_time->value );
@ -173,8 +174,6 @@ void CHudSayText::SayTextPrint( const char *pszBuf, int iBufSize, int clientInde
ConsolePrint( pszBuf );
return;
}
#else
ConsolePrint( pszBuf );
#endif
int i;

View File

@ -33,11 +33,11 @@
#if !defined(M_PI_F)
#define M_PI_F (float)M_PI
#endif
extern vec3_t vec3_origin;
// extern vec3_t vec3_origin;
// if C++ mangling differs from C symbol name
#if _MSC_VER || __WATCOMC__
vec3_t vec3_origin;
float vec3_origin[3];
#endif
float Length( const float *v )

View File

@ -673,7 +673,7 @@ int TeamFortressViewport::CreateCommandMenu( const char *menuFile, int direction
return newIndex;
}
#ifdef _WIN32
#if XASH_WIN32
try
{
#endif
@ -841,7 +841,7 @@ int TeamFortressViewport::CreateCommandMenu( const char *menuFile, int direction
{
gEngfuncs.Con_Printf( "Too many menus in %s past '%s'\n", menuFile, szLastButtonText );
}
else
else if( pButton )
{
// Create the menu
m_pCommandMenus[m_iNumMenus] = CreateSubMenu( pButton, m_pCurrentCommandMenu, iButtonY );
@ -873,7 +873,7 @@ int TeamFortressViewport::CreateCommandMenu( const char *menuFile, int direction
pfile = gEngfuncs.COM_ParseFile( pfile, token );
}
#ifdef _WIN32
#if XASH_WIN32
}
catch( CException *e )
{

View File

@ -295,8 +295,11 @@ void V_CalcGunAngle( struct ref_params_s *pparams )
viewent->angles[PITCH] -= v_idlescale * sin( pparams->time * v_ipitch_cycle.value ) * ( v_ipitch_level.value * 0.5f );
viewent->angles[YAW] -= v_idlescale * sin( pparams->time * v_iyaw_cycle.value ) * v_iyaw_level.value;
VectorCopy( viewent->angles, viewent->curstate.angles );
VectorCopy( viewent->angles, viewent->latched.prevangles );
if( !( cl_viewbob && cl_viewbob->value ))
{
VectorCopy( viewent->angles, viewent->curstate.angles );
VectorCopy( viewent->angles, viewent->latched.prevangles );
}
}
/*
@ -603,6 +606,7 @@ void V_CalcNormalRefdef( struct ref_params_s *pparams )
{
VectorCopy( pparams->cl_viewangles, view->angles );
}
// set up gun position
V_CalcGunAngle( pparams );
@ -625,9 +629,6 @@ void V_CalcNormalRefdef( struct ref_params_s *pparams )
view->angles[ROLL] -= bob * 1.0f;
view->angles[PITCH] -= bob * 0.3f;
if( cl_viewbob && cl_viewbob->value )
VectorCopy( view->angles, view->curstate.angles );
// pushing the view origin down off of the same X/Z plane as the ent's origin will give the
// gun a very nice 'shifting' effect when the player looks up/down. If there is a problem
// with view model distortion, this may be a cause. (SJB).
@ -796,6 +797,14 @@ void V_CalcNormalRefdef( struct ref_params_s *pparams )
}
}
if( cl_viewbob && cl_viewbob->value )
{
VectorCopy( view->origin, view->curstate.origin );
VectorCopy( view->origin, view->latched.prevorigin );
VectorCopy( view->angles, view->curstate.angles );
VectorCopy( view->angles, view->latched.prevangles );
}
lasttime = pparams->time;
v_origin = pparams->vieworg;
@ -1502,6 +1511,8 @@ void V_CalcSpectatorRefdef( struct ref_params_s * pparams )
case OBS_ROAMING:
VectorCopy( v_cl_angles, v_angles );
VectorCopy( v_sim_org, v_origin );
// override values if director is active
gHUD.m_Spectator.GetDirectorCamera(v_origin, v_angles);
break;
case OBS_IN_EYE:
V_CalcNormalRefdef( pparams );

View File

@ -6,27 +6,70 @@ from waflib import Utils
import os
def options(opt):
# stub
return
grp = opt.add_option_group('Client options')
grp.add_option('--enable-vgui', action = 'store_true', dest = 'USE_VGUI', default = False,
help = 'Enable VGUI1')
grp.add_option('--enable-vgui2', action = 'store_true', dest = 'USE_VGUI2', default = False,
help = 'Enable VGUI2. UNDONE')
grp.add_option('--enable-novgui-motd', action = 'store_true', dest = 'USE_NOVGUI_MOTD', default = False,
help = 'Prefer non-VGUI MOTD when USE_VGUI is enabled')
grp.add_option('--enable-novgui-scoreboard', action = 'store_true', dest = 'USE_NOVGUI_SCOREBOARD', default = False,
help = 'Prefer non-VGUI Scoreboard when USE_VGUI is enabled')
grp.add_option('--disable-goldsrc-support', action = 'store_false', dest = 'GOLDSOURCE_SUPPORT',
default=True, help = 'disable GoldSource compatibility')
opt.load('vgui')
def configure(conf):
if conf.env.DEST_OS == 'win32':
conf.check_cxx(lib='user32')
if conf.env.GOLDSRC:
if conf.env.DEST_OS == 'win32':
conf.check_cxx(lib='winmm')
else:
conf.check_cc(lib='dl')
conf.env.USE_VGUI = conf.options.USE_VGUI
conf.env.USE_NOVGUI_MOTD = conf.options.USE_NOVGUI_MOTD
conf.env.USE_NOVGUI_SCOREBOARD = conf.options.USE_NOVGUI_SCOREBOARD
conf.env.USE_VOICEMGR = conf.options.USE_VOICEMGR
conf.env.GOLDSOURCE_SUPPORT = conf.options.GOLDSOURCE_SUPPORT
if conf.env.USE_VGUI:
conf.load('vgui')
if not conf.check_vgui():
conf.fatal('VGUI was enabled but VGUI cannot be used')
def build(bld):
source = bld.path.parent.ant_glob([
'pm_shared/*.c'
])
source += bld.path.ant_glob([
'hl/*.cpp'
])
libs = []
defines = ['CLIENT_DLL']
includes = ['.',
'../dlls',
'../common',
'../engine',
'../pm_shared',
'../game_shared',
'../public']
excluded_files = ['GameStudioModelRenderer_Sample.cpp',
'game_shared/voice_vgui_tweakdlg.cpp',
'game_shared/voice_gamemgr.cpp',
'game_shared/voice_status.cpp']
if bld.env.USE_VGUI:
defines += ['USE_VGUI']
libs += ['VGUI']
if bld.env.USE_NOVGUI_MOTD:
defines += ['USE_NOVGUI_MOTD']
else:
excluded_files += ['MOTD.cpp']
if bld.env.USE_NOVGUI_SCOREBOARD:
defines += ['USE_NOVGUI_SCOREBOARD']
else:
excluded_files += ['scoreboard.cpp']
else:
includes += ['../utils/fake_vgui/include']
excluded_files += ['voice_status.cpp',
'vgui_*.cpp',
'game_shared/vgui_*.cpp',
'game_shared/voice_banmgr.cpp']
source = bld.path.ant_glob('**/*.cpp', excl=excluded_files)
source += bld.path.parent.ant_glob('game_shared/*.cpp', excl=excluded_files)
source += bld.path.parent.ant_glob([
'pm_shared/*.c',
'dlls/crossbow.cpp',
'dlls/crowbar.cpp',
'dlls/egon.cpp',
@ -42,81 +85,21 @@ def build(bld):
'dlls/squeakgrenade.cpp',
'dlls/tripmine.cpp'
])
source += [
'GameStudioModelRenderer.cpp',
'MOTD.cpp',
'StudioModelRenderer.cpp',
'ammo.cpp',
'ammo_secondary.cpp',
'ammohistory.cpp',
'battery.cpp',
'cdll_int.cpp',
'com_weapons.cpp',
'death.cpp',
'demo.cpp',
'entity.cpp',
'ev_hldm.cpp',
'ev_common.cpp',
'events.cpp',
'flashlight.cpp',
'geiger.cpp',
'health.cpp',
'hud.cpp',
'hud_msg.cpp',
'hud_redraw.cpp',
'hud_spectator.cpp',
'hud_update.cpp',
'in_camera.cpp',
'input.cpp',
'input_goldsource.cpp',
'input_mouse.cpp',
'input_xash3d.cpp',
'menu.cpp',
'message.cpp',
'parsemsg.cpp',
'particlemgr.cpp',
'particlemsg.cpp',
'particlesys.cpp',
'saytext.cpp',
'scoreboard.cpp',
'status_icons.cpp',
'statusbar.cpp',
'studio_util.cpp',
'text_message.cpp',
'train.cpp',
'tri.cpp',
'util.cpp',
'view.cpp'
]
includes = [
'.',
'hl/',
'../dlls',
'../common',
'../engine',
'../pm_shared',
'../game_shared',
'../public',
'../utils/fake_vgui/include'
]
defines = ['CLIENT_DLL']
if bld.env.GOLDSRC:
if bld.env.DEST_OS == 'win32':
libs += ['USER32']
if bld.env.GOLDSOURCE_SUPPORT:
defines += ['GOLDSOURCE_SUPPORT']
libs = []
if bld.env.DEST_OS == 'win32':
libs += ["USER32"]
if bld.env.GOLDSRC:
if bld.env.DEST_OS == 'win32':
libs += ["WINMM"]
else:
libs += ['DL']
if bld.env.DEST_OS not in ['android', 'dos']:
install_path = os.path.join(bld.env.GAMEDIR, bld.env.CLIENT_DIR)
install_path = os.path.join(bld.env.GAMEDIR, bld.env.CLIENT_INSTALL_DIR)
else:
install_path = bld.env.PREFIX
@ -130,6 +113,6 @@ def build(bld):
use = libs,
install_path = install_path,
subsystem = bld.env.MSVC_SUBSYSTEM,
idx = bld.get_taskgen_count()
idx = bld.get_taskgen_count()
)

View File

@ -1,49 +1,83 @@
include(CheckSymbolExists)
# generated(see comments in public/build.h)
# cat build.h | grep '^#undef XASH' | awk '{ print "check_symbol_exists(" $2 " \"build.h\" " $2 ")" }'
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_symbol_exists(XASH_64BIT "build.h" XASH_64BIT)
check_symbol_exists(XASH_AMD64 "build.h" XASH_AMD64)
check_symbol_exists(XASH_ANDROID "build.h" XASH_ANDROID)
check_symbol_exists(XASH_APPLE "build.h" XASH_APPLE)
check_symbol_exists(XASH_ARM "build.h" XASH_ARM)
check_symbol_exists(XASH_ARM_HARDFP "build.h" XASH_ARM_HARDFP)
check_symbol_exists(XASH_ARM_SOFTFP "build.h" XASH_ARM_SOFTFP)
check_symbol_exists(XASH_ARMv4 "build.h" XASH_ARMv4)
check_symbol_exists(XASH_ARMv5 "build.h" XASH_ARMv5)
check_symbol_exists(XASH_ARMv6 "build.h" XASH_ARMv6)
check_symbol_exists(XASH_ARMv7 "build.h" XASH_ARMv7)
check_symbol_exists(XASH_ARMv8 "build.h" XASH_ARMv8)
check_symbol_exists(XASH_BIG_ENDIAN "build.h" XASH_BIG_ENDIAN)
check_symbol_exists(XASH_BSD "build.h" XASH_BSD)
check_symbol_exists(XASH_DOS4GW "build.h" XASH_DOS4GW)
check_symbol_exists(XASH_E2K "build.h" XASH_E2K)
check_symbol_exists(XASH_EMSCRIPTEN "build.h" XASH_EMSCRIPTEN)
check_symbol_exists(XASH_FREEBSD "build.h" XASH_FREEBSD)
check_symbol_exists(XASH_HAIKU "build.h" XASH_HAIKU)
check_symbol_exists(XASH_IOS "build.h" XASH_IOS)
check_symbol_exists(XASH_JS "build.h" XASH_JS)
check_symbol_exists(XASH_LINUX "build.h" XASH_LINUX)
check_symbol_exists(XASH_LITTLE_ENDIAN "build.h" XASH_LITTLE_ENDIAN)
check_symbol_exists(XASH_MINGW "build.h" XASH_MINGW)
check_symbol_exists(XASH_MIPS "build.h" XASH_MIPS)
check_symbol_exists(XASH_PPC "build.h" XASH_PPC)
check_symbol_exists(XASH_MOBILE_PLATFORM "build.h" XASH_MOBILE_PLATFORM)
check_symbol_exists(XASH_MSVC "build.h" XASH_MSVC)
check_symbol_exists(XASH_NETBSD "build.h" XASH_NETBSD)
check_symbol_exists(XASH_OPENBSD "build.h" XASH_OPENBSD)
check_symbol_exists(XASH_POSIX "build.h" XASH_POSIX)
check_symbol_exists(XASH_RISCV "build.h" XASH_RISCV)
check_symbol_exists(XASH_RISCV_DOUBLEFP "build.h" XASH_RISCV_DOUBLEFP)
check_symbol_exists(XASH_RISCV_SINGLEFP "build.h" XASH_RISCV_SINGLEFP)
check_symbol_exists(XASH_RISCV_SOFTFP "build.h" XASH_RISCV_SOFTFP)
check_symbol_exists(XASH_SERENITY "build.h" XASH_SERENITY)
check_symbol_exists(XASH_WIN32 "build.h" XASH_WIN32)
check_symbol_exists(XASH_WIN64 "build.h" XASH_WIN64)
check_symbol_exists(XASH_X86 "build.h" XASH_X86)
check_symbol_exists(XASH_NSWITCH "build.h" XASH_NSWITCH)
check_symbol_exists(XASH_PSVITA "build.h" XASH_PSVITA)
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_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
@ -69,6 +103,8 @@ elseif(XASH_NSWITCH)
set(BUILDOS "nswitch")
elseif(XASH_PSVITA)
set(BUILDOS "psvita")
elseif(XASH_IRIX)
set(BUILDOS "irix")
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()
@ -113,15 +149,6 @@ elseif(XASH_MIPS)
if(XASH_LITTLE_ENDIAN)
set(BUILDARCH "${BUILDARCH}el")
endif()
elseif(XASH_PPC)
set(BUILDARCH "powerpc")
if(XASH_64BIT)
set(BUILDARCH "${BUILDARCH}64")
endif()
if(XASH_LITTLE_ENDIAN)
set(BUILDARCH "${BUILDARCH}le")
endif()
elseif(XASH_RISCV)
set(BUILDARCH "riscv")
if(XASH_64BIT)
@ -139,6 +166,15 @@ 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()

View File

@ -1,4 +1,4 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//

View File

@ -127,7 +127,8 @@
// entity flags
#define EFLAG_SLERP 1 // do studio interpolation of this entity
#define EFLAG_MONSTER 2
//
// temp entity events
//

View File

@ -37,11 +37,14 @@
#define DRC_CMD_SOUND 7 // plays a particular sound
#define DRC_CMD_STATUS 8 // status info about broadcast
#define DRC_CMD_BANNER 9 // banner file name for HLTV gui
#define DRC_CMD_FADE 10 // send screen fade command
#define DRC_CMD_SHAKE 11 // send screen shake command
#define DRC_CMD_STUFFTEXT 12 // like the normal svc_stufftext but as director command
#define DRC_CMD_STUFFTEXT 10 // like the normal svc_stufftext but as director command
#define DRC_CMD_CHASE 11 // chase a certain player
#define DRC_CMD_INEYE 12 // view player through own eyes
#define DRC_CMD_MAP 13 // show overview map
#define DRC_CMD_CAMPATH 14 // define camera waypoint
#define DRC_CMD_WAYPOINTS 15 // start moving camera, inetranl message
#define DRC_CMD_LAST 12
#define DRC_CMD_LAST 15
// HLTV_EVENT event flags
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
@ -53,7 +56,9 @@
#define DRC_FLAG_FINAL (1<<9) // is a final scene
#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
#define MAX_DIRECTOR_CMD_PARAMETERS 4
#define MAX_DIRECTOR_CMD_STRING 128
// DRC_CMD_WAYPOINT flags
#define DRC_FLAG_STARTPATH 1 // end with speed 0.0
#define DRC_FLAG_SLOWSTART 2 // start with speed 0.0
#define DRC_FLAG_SLOWEND 4 // end with speed 0.0
#endif//HLTV_H

View File

@ -219,6 +219,7 @@ files{"dlls/agrunt.cpp",
"dlls/triggers.cpp",
"dlls/turret.cpp",
"dlls/util.cpp",
"dlls/vehicle.cpp",
"dlls/weapons.cpp",
"dlls/world.cpp",
"dlls/xen.cpp",
@ -269,6 +270,7 @@ files{"cl_dll/hl/hl_baseentity.cpp",
"cl_dll/input_goldsource.cpp",
"cl_dll/input_mouse.cpp",
"cl_dll/input_xash3d.cpp",
"cl_dll/interpolation.cpp",
"cl_dll/menu.cpp",
"cl_dll/message.cpp",
"cl_dll/overview.cpp",

View File

@ -21,6 +21,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \
$(LOCAL_PATH)/../pm_shared \
$(LOCAL_PATH)/../game_shared
<<<<<<< HEAD
LOCAL_SRC_FILES := aflock.cpp agrunt.cpp schedule.cpp airtank.cpp \
alias.cpp animating.cpp animation.cpp apache.cpp barnacle.cpp barney.cpp \
bigmomma.cpp bloater.cpp bmodels.cpp bullsquid.cpp buttons.cpp cbase.cpp \
@ -39,6 +40,111 @@ LOCAL_SRC_FILES := aflock.cpp agrunt.cpp schedule.cpp airtank.cpp \
tentacle.cpp triggers.cpp tripmine.cpp turret.cpp util.cpp weapons.cpp world.cpp xen.cpp \
zombie.cpp glock.cpp \
../pm_shared/pm_debug.c ../pm_shared/pm_math.c ../pm_shared/pm_shared.c
=======
LOCAL_SRC_FILES := agrunt.cpp airtank.cpp \
aflock.cpp \
animating.cpp \
animation.cpp \
apache.cpp \
barnacle.cpp \
barney.cpp \
bigmomma.cpp \
bloater.cpp \
bmodels.cpp \
bullsquid.cpp \
buttons.cpp \
cbase.cpp \
client.cpp \
combat.cpp \
controller.cpp \
crossbow.cpp \
crowbar.cpp \
defaultai.cpp \
doors.cpp \
effects.cpp \
egon.cpp \
explode.cpp \
flyingmonster.cpp \
func_break.cpp \
func_tank.cpp \
game.cpp \
gamerules.cpp \
gargantua.cpp \
gauss.cpp \
genericmonster.cpp \
ggrenade.cpp \
globals.cpp \
glock.cpp \
gman.cpp \
h_ai.cpp \
h_battery.cpp \
h_cycler.cpp \
h_cine.cpp \
h_export.cpp \
handgrenade.cpp \
hassassin.cpp \
headcrab.cpp \
healthkit.cpp \
hgrunt.cpp \
hornet.cpp \
hornetgun.cpp \
houndeye.cpp \
ichthyosaur.cpp \
islave.cpp \
items.cpp \
leech.cpp \
lights.cpp \
maprules.cpp \
monstermaker.cpp \
monsters.cpp \
monsterstate.cpp \
mortar.cpp \
mp5.cpp \
multiplay_gamerules.cpp \
nihilanth.cpp \
nodes.cpp \
observer.cpp \
osprey.cpp \
pathcorner.cpp \
plane.cpp \
plats.cpp \
player.cpp \
playermonster.cpp \
python.cpp \
rat.cpp \
roach.cpp \
rpg.cpp \
satchel.cpp \
schedule.cpp \
scientist.cpp \
scripted.cpp \
shotgun.cpp \
singleplay_gamerules.cpp \
skill.cpp \
sound.cpp \
soundent.cpp \
spectator.cpp \
squadmonster.cpp \
squeakgrenade.cpp \
subs.cpp \
talkmonster.cpp \
teamplay_gamerules.cpp \
tentacle.cpp \
tempmonster.cpp \
triggers.cpp \
tripmine.cpp \
turret.cpp \
util.cpp \
vehicle.cpp \
weapons.cpp \
world.cpp \
xen.cpp \
zombie.cpp \
../pm_shared/pm_debug.c \
../pm_shared/pm_math.c \
../pm_shared/pm_shared.c
# ../game_shared/voice_gamemgr.cpp
>>>>>>> master

View File

@ -20,17 +20,26 @@
# SOFTWARE.
#
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.9)
project (SVDLL)
set (SVDLL_LIBRARY server)
if(NOT MSVC)
add_compile_options(-fno-exceptions) # GCC/Clang flag
add_compile_options(-fno-rtti) # GCC/Clang flag
add_compile_options(-Wno-invalid-offsetof) # GCC/Clang flag
add_compile_options(-fvisibility=hidden) # GCC/Clang flag
add_definitions(-D_LINUX) # It seems enough for all non-Win32 systems
add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf )
if(CMAKE_BUILD_TYPE MATCHES "Release"
OR (CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo"
AND CMAKE_SYSTEM_NAME STREQUAL "Android"))
add_compile_options(-fno-unwind-tables -fno-asynchronous-unwind-tables) # GCC/Clang flag
add_compile_options(-fomit-frame-pointer) # GCC/Clang flag
add_compile_options(-ftree-vectorize) # GCC/Clang flag
add_compile_options(-funsafe-math-optimizations) # GCC/Clang flag
endif()
else()
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
endif()
@ -134,6 +143,7 @@ set (SVDLL_SOURCES
tripmine.cpp
turret.cpp
util.cpp
vehicle.cpp
weapons.cpp
world.cpp
xen.cpp
@ -176,8 +186,16 @@ if(MSVC)
set_property(TARGET ${SVDLL_LIBRARY} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
if(HAVE_LTO)
set_property(TARGET ${SVDLL_LIBRARY} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
install( TARGETS ${SVDLL_LIBRARY}
DESTINATION "${GAMEDIR}/${SERVER_INSTALL_DIR}/"
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)
add_custom_command(TARGET ${SVDLL_LIBRARY}
POST_BUILD DEPENDS ${SVDLL_LIBRARY}
COMMAND $<$<CONFIG:release>:${CMAKE_STRIP}> -s $<TARGET_FILE:${SVDLL_LIBRARY}>)

View File

@ -126,6 +126,7 @@ public:
virtual int BloodColor( void ) { return m_bloodColor; }
virtual CBaseMonster *MyMonsterPointer( void ) { return this; }
virtual BOOL IsAllowedToSpeak( void ) { return IsAlive(); }
virtual void Look( int iDistance );// basic sight function for monsters
virtual void RunAI( void );// core ai function!
void Listen( void );
@ -191,13 +192,9 @@ public:
virtual Schedule_t *GetSchedule( void );
virtual void ScheduleChange( void ) {}
// virtual int CanPlaySequence( void ) { return ((m_pCine == NULL) && (m_MonsterState == MONSTERSTATE_NONE || m_MonsterState == MONSTERSTATE_IDLE || m_IdealMonsterState == MONSTERSTATE_IDLE)); }
virtual int CanPlaySequence( int interruptFlags );
// virtual int CanPlaySequence( BOOL fDisregardState, int interruptLevel );
virtual int CanPlaySentence( BOOL fDisregardState ) { return IsAlive(); }
virtual void PlaySentence( const char *pszSentence, float duration, float volume, float attenuation );
virtual void PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener );
virtual void SentenceStop( void );
virtual int CanPlaySequence( int interruptFlags );
// virtual int CanPlaySequence( BOOL fDisregardState, int interruptLevel );
virtual int CanPlaySentence( BOOL fDisregardState ) { return IsAllowedToSpeak(); }
Task_t *GetTask( void );
virtual MONSTERSTATE GetIdealState( void );

View File

@ -1002,7 +1002,7 @@ void CBigMomma::StartTask( Task_t *pTask )
TaskComplete();
break;
case TASK_WAIT_NODE:
m_flWaitFinished = gpGlobals->time + GetNodeDelay();
m_flWait = gpGlobals->time + GetNodeDelay();
if( m_hTargetEnt->pev->spawnflags & SF_INFOBM_WAIT )
ALERT( at_aiconsole, "BM: Wait at node %s forever\n", STRING( pev->netname ) );
else

View File

@ -100,7 +100,7 @@ static DLL_FUNCTIONS gFunctionTable =
static void SetObjectCollisionBox( entvars_t *pev );
#if !_WIN32
#if !XASH_WIN32
extern "C" {
#endif
int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion )
@ -127,7 +127,7 @@ int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion )
return TRUE;
}
#if !_WIN32
#if !XASH_WIN32
}
#endif

View File

@ -125,9 +125,11 @@ typedef void(CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCalle
#define CLASS_FACTION_A 14 //LRC - very simple new classes, for use with Behaves As
#define CLASS_FACTION_B 15
#define CLASS_FACTION_C 16
#define CLASS_VEHICLE 17
#define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures.
class CBaseEntity;
class CBaseToggle;
class CBaseMonster;
class CBasePlayerItem;
class CSquadMonster;
@ -283,6 +285,7 @@ public:
virtual void TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType );
//LRC- superceded by GetState ( pActivator ).
// virtual BOOL IsTriggered( CBaseEntity *pActivator ) {return TRUE;}
virtual CBaseToggle *MyTogglePointer( void ) { return NULL; }
virtual CBaseMonster *MyMonsterPointer( void ) { return NULL; }
virtual CSquadMonster *MySquadMonsterPointer( void ) { return NULL; }
virtual int GetToggleState( void ) { return TS_AT_TOP; }
@ -363,7 +366,6 @@ public:
int Intersects( CBaseEntity *pOther );
void MakeDormant( void );
int IsDormant( void );
BOOL IsLockedByMaster( void ) { return FALSE; }
static CBaseEntity *Instance( edict_t *pent )
{
@ -645,6 +647,7 @@ public:
static TYPEDESCRIPTION m_SaveData[];
CBaseToggle *MyTogglePointer( void ) { return this; }
virtual int GetToggleState( void ) { return m_toggle_state; }
// LRC- overridden because toggling entities have general rules governing their states.
@ -652,6 +655,11 @@ public:
virtual float GetDelay( void ) { return m_flWait; }
virtual void PlaySentence( const char *pszSentence, float duration, float volume, float attenuation );
virtual void PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener );
virtual void SentenceStop( void );
virtual BOOL IsAllowedToSpeak( void ) { return FALSE; }
// common member functions
void LinearMove( Vector vecInput, float flSpeed );
//void LinearMove( Vector vecInput, float flSpeed, BOOL bNow );
@ -825,6 +833,8 @@ public:
static TYPEDESCRIPTION m_SaveData[];
virtual int ObjectCaps( void );
BOOL IsAllowedToSpeak( void ) { return TRUE; }
BOOL m_fStayPushed; // button stays pushed in until touched again?
BOOL m_fRotating; // a rotating button? default is a sliding button.

View File

@ -51,16 +51,12 @@ extern DLL_GLOBAL ULONG g_ulFrameCount;
extern void CopyToBodyQue( entvars_t* pev );
extern int giPrecacheGrunt;
extern int gmsgSayText;
extern int gmsgBhopcap;
extern int gmsgHUDColor;
extern cvar_t allow_spectators;
extern cvar_t multibyte_only;
extern int g_teamplay;
extern cvar_t bhopcap;
extern "C" int g_bhopcap;
void LinkUserMessages( void );
/*
@ -133,6 +129,7 @@ void ClientDisconnect( edict_t *pEntity )
pEntity->v.takedamage = DAMAGE_NO;// don't attract autoaim
pEntity->v.solid = SOLID_NOT;// nonsolid
pEntity->v.effects = 0;// clear any effect
pEntity->v.flags = 0;// clear any flags
UTIL_SetEdictOrigin ( pEntity, pEntity->v.origin );
g_pGameRules->ClientDisconnected( pEntity );
@ -856,14 +853,6 @@ void StartFrame( void )
// CheckDesiredList(); //LRC
CheckAssistList(); //LRC
int oldBhopcap = g_bhopcap;
g_bhopcap = ( g_pGameRules && g_pGameRules->IsMultiplayer() && bhopcap.value != 0.0f ) ? 1 : 0;
if( g_bhopcap != oldBhopcap )
{
MESSAGE_BEGIN( MSG_ALL, gmsgBhopcap, NULL );
WRITE_BYTE( g_bhopcap );
MESSAGE_END();
}
}
void ClientPrecache( void )
@ -938,6 +927,8 @@ void ClientPrecache( void )
PRECACHE_SOUND( "plats/train_use1.wav" ); // use a train
PRECACHE_SOUND( "plats/vehicle_ignition.wav" );
PRECACHE_SOUND( "buttons/spark5.wav" ); // hit computer texture
PRECACHE_SOUND( "buttons/spark6.wav" );
PRECACHE_SOUND( "debris/glass1.wav" );
@ -1170,6 +1161,7 @@ we could also use the pas/ pvs that we set in SetupVisibility, if we wanted to.
int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet )
{
int i;
CBaseEntity *Entity;
// don't send if flagged for NODRAW and it's not the host getting the message
if( ( ent->v.effects & EF_NODRAW ) && ( ent != host ) )
@ -1356,6 +1348,17 @@ int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *h
state->health = (int)ent->v.health;
}
if( ( Entity = CBaseEntity::Instance( ent ))
&& Entity->Classify() != CLASS_NONE
&& Entity->Classify() != CLASS_MACHINE )
{
SetBits( state->eflags, EFLAG_MONSTER );
}
else
{
ClearBits( state->eflags, EFLAG_SLERP | EFLAG_MONSTER );
}
return 1;
}

View File

@ -103,6 +103,7 @@ set SOURCES=agrunt.cpp ^
tripmine.cpp ^
turret.cpp ^
util.cpp ^
vehicle.cpp ^
weapons.cpp ^
world.cpp ^
xen.cpp ^

View File

@ -324,7 +324,7 @@ void CCrossbow::Holster( int skiplocal /* = 0 */ )
{
m_fInReload = FALSE;// cancel any reload in progress.
if( m_fInZoom )
if( m_pPlayer->pev->fov != 0 )
{
SecondaryAttack();
}

View File

@ -291,7 +291,8 @@ void CEgon::Fire( const Vector &vecOrigSrc, const Vector &vecDir )
// multiplayer uses 1 ammo every 1/10th second
if( gpGlobals->time >= m_flAmmoUseTime )
{
UseAmmo( 1 );
if( !g_pGameRules->IsBustingGame())
UseAmmo( 1 );
m_flAmmoUseTime = gpGlobals->time + 0.1f;
}
}
@ -336,7 +337,8 @@ void CEgon::Fire( const Vector &vecOrigSrc, const Vector &vecDir )
//multiplayer uses 5 ammo/second
if( gpGlobals->time >= m_flAmmoUseTime )
{
UseAmmo( 1 );
if( !g_pGameRules->IsBustingGame())
UseAmmo( 1 );
m_flAmmoUseTime = gpGlobals->time + 0.2f;
}
}
@ -499,6 +501,15 @@ void CEgon::WeaponIdle( void )
m_deployed = TRUE;
}
BOOL CEgon::CanHolster( void )
{
#if CLIENT_DLL
return TRUE;
#else
return !g_pGameRules->IsBustingGame();
#endif
}
void CEgon::EndAttack( void )
{
bool bMakeNoise = false;

View File

@ -1,7 +1,7 @@
#pragma once
#if !defined(EXPORTDEF_H)
#define EXPORTDEF_H
#if _WIN32 || __CYGWIN__
#if XASH_WIN32 || __CYGWIN__
#if __GNUC__
#define EXPORT __attribute__ ((dllexport))
#else

View File

@ -15,7 +15,7 @@
#pragma once
#if !defined(EXTDLL_H)
#define EXTDLL_H
#include "build.h"
//
// Global header file for extension DLLs
//
@ -35,7 +35,7 @@
#endif
// Prevent tons of unused windows definitions
#if _WIN32
#if XASH_WIN32
#define WIN32_LEAN_AND_MEAN
#define NOWINRES
#define NOSERVICE
@ -76,10 +76,6 @@ typedef int BOOL;
#define M_PI_F (float)M_PI
#endif
#if __LP64__ || __LLP64__ || _WIN64 || (__x86_64__ && !__ILP32__) || _M_X64 || __ia64 || _M_IA64 || __aarch64__ || __powerpc64__
#define XASH_64BIT 1
#endif
// Header file containing definition of globalvars_t and entvars_t
typedef unsigned int func_t;
typedef int string_t; // from engine's pr_comp.h;

View File

@ -1111,22 +1111,25 @@ void CPushable::Move( CBaseEntity *pOther, int push )
if( pOther->IsPlayer() )
{
// g-cont. fix pushable acceleration bug (now implemented as cvar)
if (pushablemode.value == 1)
{
// Allow player push when moving right, left and back too
if ( push && !(pevToucher->button & (IN_FORWARD|IN_MOVERIGHT|IN_MOVELEFT|IN_BACK)) )
return;
// Require player walking back when applying '+use' on pushable
if ( !push && !(pevToucher->button & (IN_BACK)) )
return;
}
else
if( pushablemode.value == -1 )
{
// Don't push unless the player is pushing forward and NOT use (pull)
if( push && !( pevToucher->button & ( IN_FORWARD | IN_USE ) ) )
if( push && !( pevToucher->button & ( IN_FORWARD | IN_USE )))
return;
}
// g-cont. fix pushable acceleration bug (now implemented as cvar)
else if( pushablemode.value != 0 )
{
// Allow player push when moving right, left and back too
if( push && !( pevToucher->button & ( IN_FORWARD | IN_MOVERIGHT | IN_MOVELEFT | IN_BACK )))
return;
// Require player walking back when applying '+use' on pushable
if( !push && !( pevToucher->button & ( IN_BACK )))
return;
}
// Don't push when +use pressed
else if( push && ( pevToucher->button & ( IN_USE )))
return;
playerTouch = 1;
}
@ -1147,26 +1150,55 @@ void CPushable::Move( CBaseEntity *pOther, int push )
else
factor = 0.25f;
if (!push)
factor *= 0.5f;
if( pushablemode.value != 0 )
{
pev->velocity.x += pevToucher->velocity.x * factor;
pev->velocity.y += pevToucher->velocity.y * factor;
}
else
{
if( push )
{
factor = 0.25f;
pev->velocity.x += pevToucher->velocity.x * factor;
pev->velocity.y += pevToucher->velocity.y * factor;
}
else
{
// fix for pushable acceleration
if( sv_pushable_fixed_tick_fudge.value >= 0 )
factor *= ( sv_pushable_fixed_tick_fudge.value * gpGlobals->frametime );
pev->velocity.x += pevToucher->velocity.x * factor;
pev->velocity.y += pevToucher->velocity.y * factor;
if( fabs( pev->velocity.x ) < fabs( pevToucher->velocity.x - pevToucher->velocity.x * factor ))
pev->velocity.x += pevToucher->velocity.x * factor;
if( fabs( pev->velocity.y ) < fabs( pevToucher->velocity.y - pevToucher->velocity.y * factor ))
pev->velocity.y += pevToucher->velocity.y * factor;
}
}
float length = sqrt( pev->velocity.x * pev->velocity.x + pev->velocity.y * pev->velocity.y );
if( push && ( length > MaxSpeed() ) )
if( ( push && pushablemode.value != 0 )
|| pushablemode.value == 0 )
{
pev->velocity.x = (pev->velocity.x * MaxSpeed() / length );
pev->velocity.y = (pev->velocity.y * MaxSpeed() / length );
if( length > MaxSpeed())
{
pev->velocity.x = ( pev->velocity.x * MaxSpeed() / length );
pev->velocity.y = ( pev->velocity.y * MaxSpeed() / length );
}
}
if( playerTouch )
{
pevToucher->velocity.x = pev->velocity.x;
pevToucher->velocity.y = pev->velocity.y;
if( push || pushablemode.value != 0 )
{
pevToucher->velocity.x = pev->velocity.x;
pevToucher->velocity.y = pev->velocity.y;
}
if( ( gpGlobals->time - m_soundTime ) > 0.7f )
{
m_soundTime = gpGlobals->time;
if( length > 0 && FBitSet( pev->flags,FL_ONGROUND ) )
if( length > 0 && FBitSet( pev->flags, FL_ONGROUND ))
{
m_lastSound = RANDOM_LONG( 0, 2 );
EMIT_SOUND( ENT( pev ), CHAN_WEAPON, m_soundNames[m_lastSound], 0.5f, ATTN_NORM );

View File

@ -34,7 +34,7 @@ cvar_t falldamage = { "mp_falldamage","0", FCVAR_SERVER };
cvar_t weaponstay = { "mp_weaponstay","0", FCVAR_SERVER };
cvar_t selfgauss = { "selfgauss", "1", FCVAR_SERVER };
cvar_t chargerfix = { "chargerfix", "0", FCVAR_SERVER };
cvar_t satchelfix = { "satchelfix", "0", FCVAR_SERVER };
cvar_t satchelfix = { "satchelfix", "1", FCVAR_SERVER };
cvar_t explosionfix = { "explosionfix", "0", FCVAR_SERVER };
cvar_t monsteryawspeedfix = { "monsteryawspeedfix", "1", FCVAR_SERVER };
cvar_t corpsephysics = { "corpsephysics", "0", FCVAR_SERVER };
@ -459,12 +459,15 @@ cvar_t sk_player_leg3 = { "sk_player_leg3","1" };
// END Cvars for Skill Level settings
cvar_t sv_pushable_fixed_tick_fudge = { "sv_pushable_fixed_tick_fudge", "15" };
cvar_t sv_busters = { "sv_busters", "0" };
// Register your console variables here
// This gets called one time when the game is initialied
void GameDLLInit( void )
{
// Register cvars here:
if( CVAR_GET_POINTER( "build" ) )
if( !CVAR_GET_POINTER( "sv_language" ) )
g_fIsXash3D = TRUE;
g_psv_gravity = CVAR_GET_POINTER( "sv_gravity" );
@ -509,7 +512,7 @@ void GameDLLInit( void )
CVAR_REGISTER( &multibyte_only );
CVAR_REGISTER( &mp_chattime );
CVAR_REGISTER( &sv_busters );
// REGISTER CVARS FOR SKILL LEVEL STUFF
@ -887,6 +890,8 @@ void GameDLLInit( void )
CVAR_REGISTER( &sk_player_leg3 );
// END REGISTER CVARS FOR SKILL LEVEL STUFF
CVAR_REGISTER( &sv_pushable_fixed_tick_fudge );
SERVER_COMMAND( "exec skill.cfg\n" );
}

View File

@ -42,6 +42,9 @@ extern cvar_t teamlist;
extern cvar_t teamoverride;
extern cvar_t defaultteam;
extern cvar_t allowmonsters;
extern cvar_t bhopcap;
extern cvar_t sv_pushable_fixed_tick_fudge;
extern cvar_t sv_busters;
// Engine Cvars
extern cvar_t *g_psv_gravity;

View File

@ -337,6 +337,11 @@ CGameRules *InstallGameRules( void )
g_teamplay = 1;
return new CHalfLifeTeamplay;
}
if( sv_busters.value > 0 )
{
g_teamplay = 0;
return new CMultiplayBusters;
}
if( (int)gpGlobals->deathmatch == 1 )
{
// vanilla deathmatch

View File

@ -164,10 +164,11 @@ public:
// Immediately end a multiplayer game
virtual void EndMultiplayerGame( void ) {}
virtual BOOL IsBustingGame( void ){ return FALSE; };
};
extern CGameRules *InstallGameRules( void );
BOOL HLGetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon );
//=========================================================
// CHalfLifeRules - rules for the single player Half-Life
@ -364,5 +365,30 @@ protected:
void SendMOTDToClient( edict_t *client );
};
bool IsPlayerBusting( CBaseEntity *pPlayer );
BOOL BustingCanHaveItem( CBasePlayer *pPlayer, CBaseEntity *pItem );
class CMultiplayBusters : public CHalfLifeMultiplay
{
public:
CMultiplayBusters();
void Think();
void PlayerSpawn( CBasePlayer *pPlayer );
void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer );
int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled );
void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor );
void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor );
BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pItem );
void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon );
int WeaponShouldRespawn( CBasePlayerItem *pWeapon );
BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem );
void CheckForEgons();
void SetPlayerModel( CBasePlayer *pPlayer, BOOL bKnownBuster );
BOOL IsBustingGame( void ){ return TRUE; };
protected:
float m_flEgonBustingCheckTime;
};
extern DLL_GLOBAL CGameRules *g_pGameRules;
#endif // GAMERULES_H

View File

@ -170,6 +170,8 @@ void CGauss::PrimaryAttack()
void CGauss::SecondaryAttack()
{
if( m_pPlayer->m_flStartCharge > gpGlobals->time )
m_pPlayer->m_flStartCharge = gpGlobals->time;
// don't fire underwater
if( m_pPlayer->pev->waterlevel == 3 )
{
@ -315,6 +317,8 @@ void CGauss::StartFire( void )
{
float flDamage;
if( m_pPlayer->m_flStartCharge > gpGlobals->time )
m_pPlayer->m_flStartCharge = gpGlobals->time;
UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle );
Vector vecAiming = gpGlobals->v_forward;
Vector vecSrc = m_pPlayer->GetGunPosition(); // + gpGlobals->v_up * -8 + gpGlobals->v_right * 8;
@ -426,6 +430,8 @@ void CGauss::Fire( Vector vecOrigSrc, Vector vecDir, float flDamage )
if( pEntity->pev->takedamage )
{
ClearMultiDamage();
if( pEntity->pev == m_pPlayer->pev )
tr.iHitgroup = 0;
pEntity->TraceAttack( m_pPlayer->pev, flDamage, vecDir, &tr, DMG_BULLET );
ApplyMultiDamage( m_pPlayer->pev, m_pPlayer->pev );
}

View File

@ -267,6 +267,7 @@ void CGrenade::BounceTouch( CBaseEntity *pOther )
pev->velocity = pev->velocity * 0.8f;
pev->sequence = RANDOM_LONG( 1, 1 );
ResetSequenceInfo();
}
else
{
@ -410,7 +411,9 @@ CGrenade *CGrenade::ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vec
pGrenade->pev->velocity = Vector( 0, 0, 0 );
}
SET_MODEL( ENT( pGrenade->pev ), "models/w_grenade.mdl" );
pGrenade->pev->sequence = RANDOM_LONG( 3, 6 );
pGrenade->ResetSequenceInfo();
pGrenade->pev->framerate = 1.0f;
// Tumble through the air
@ -419,7 +422,6 @@ CGrenade *CGrenade::ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vec
pGrenade->pev->gravity = 0.5f;
pGrenade->pev->friction = 0.8f;
SET_MODEL( ENT( pGrenade->pev ), "models/w_grenade.mdl" );
pGrenade->pev->dmg = 100;
return pGrenade;

View File

@ -49,6 +49,8 @@ public:
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
BOOL IsAllowedToSpeak( void ) { return TRUE; }
int m_animate;
};

View File

@ -29,7 +29,7 @@
enginefuncs_t g_engfuncs;
globalvars_t *gpGlobals;
#if _WIN32
#if XASH_WIN32
// Required DLL entry point
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )

View File

@ -135,9 +135,9 @@ void CHandGrenade::WeaponIdle( void )
else
angThrow.x = -10.0f + angThrow.x * ( ( 90.0f + 10.0f ) / 90.0f );
float flVel = ( 90.0f - angThrow.x ) * 4.0f;
if( flVel > 500.0f )
flVel = 500.0f;
float flVel = ( 90.0f - angThrow.x ) * 6.5f;
if( flVel > 1000.0f )
flVel = 1000.0f;
UTIL_MakeVectors( angThrow );

View File

@ -280,7 +280,7 @@ void CHGrunt::GibMonster( void )
Vector vecGunPos;
Vector vecGunAngles;
if( GetBodygroup( 2 ) != 2 )
if( GetBodygroup( GUN_GROUP ) != GUN_NONE )
{
// throw a gun if the grunt has one
GetAttachment( 0, vecGunPos, vecGunAngles );
@ -606,7 +606,7 @@ void CHGrunt::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir
if( ptr->iHitgroup == 11 )
{
// make sure we're wearing one
if( GetBodygroup( 1 ) == HEAD_GRUNT && ( bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB ) ) )
if( GetBodygroup( HEAD_GROUP ) == HEAD_GRUNT && ( bitsDamageType & (DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB ) ) )
{
// absorb damage
flDamage -= 20;
@ -856,27 +856,30 @@ void CHGrunt::HandleAnimEvent( MonsterEvent_t *pEvent )
{
if (pev->spawnflags & SF_MONSTER_NO_WPN_DROP) break; //LRC
Vector vecGunPos;
Vector vecGunAngles;
GetAttachment( 0, vecGunPos, vecGunAngles );
// switch to body group with no gun.
SetBodygroup( GUN_GROUP, GUN_NONE );
// now spawn a gun.
if( FBitSet( pev->weapons, HGRUNT_SHOTGUN ) )
if ( GetBodygroup( GUN_GROUP ) != GUN_NONE )
{
DropItem( "weapon_shotgun", vecGunPos, vecGunAngles );
}
else
{
DropItem( "weapon_9mmAR", vecGunPos, vecGunAngles );
}
Vector vecGunPos;
Vector vecGunAngles;
if( FBitSet( pev->weapons, HGRUNT_GRENADELAUNCHER ) )
{
DropItem( "ammo_ARgrenades", BodyTarget( pev->origin ), vecGunAngles );
GetAttachment( 0, vecGunPos, vecGunAngles );
// switch to body group with no gun.
SetBodygroup( GUN_GROUP, GUN_NONE );
// now spawn a gun.
if( FBitSet( pev->weapons, HGRUNT_SHOTGUN ) )
{
DropItem( "weapon_shotgun", vecGunPos, vecGunAngles );
}
else
{
DropItem( "weapon_9mmAR", vecGunPos, vecGunAngles );
}
if( FBitSet( pev->weapons, HGRUNT_GRENADELAUNCHER ) )
{
DropItem( "ammo_ARgrenades", BodyTarget( pev->origin ), vecGunAngles );
}
}
}
break;

View File

@ -137,7 +137,12 @@ void CHgun::PrimaryAttack()
CBaseEntity *pHornet = CBaseEntity::Create( "hornet", m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 16.0f + gpGlobals->v_right * 8.0f + gpGlobals->v_up * -12.0f, m_pPlayer->pev->v_angle, m_pPlayer->edict() );
pHornet->pev->velocity = gpGlobals->v_forward * 300.0f;
m_flRechargeTime = gpGlobals->time + 0.5f;
float flRechargeTimePause = 0.5f;
if( g_pGameRules->IsMultiplayer() )
flRechargeTimePause = 0.3f;
m_flRechargeTime = gpGlobals->time + flRechargeTimePause;
#endif
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
@ -223,8 +228,14 @@ void CHgun::SecondaryAttack( void )
pHornet->SetThink( &CHornet::StartDart );
m_flRechargeTime = gpGlobals->time + 0.5f;
float flRechargeTimePause = 0.5f;
if( g_pGameRules->IsMultiplayer() )
flRechargeTimePause = 0.3f;
m_flRechargeTime = gpGlobals->time + flRechargeTimePause;
#endif
int flags;
#if CLIENT_WEAPONS
flags = FEV_NOTHOST;
@ -251,8 +262,16 @@ void CHgun::Reload( void )
while( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] < HORNET_MAX_CARRY && m_flRechargeTime < gpGlobals->time )
{
float flRechargeTimePause = 0.5f;
#if CLIENT_DLL
if( bIsMultiplayer() )
#else
if( g_pGameRules->IsMultiplayer() )
#endif
flRechargeTimePause = 0.3f;
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]++;
m_flRechargeTime += 0.5f;
m_flRechargeTime += flRechargeTimePause;
}
}

View File

@ -772,6 +772,7 @@ void CISlave :: ArmBeam( int side )
m_pBeam[m_iBeams]->SetColor( 96, 128, 16 );
m_pBeam[m_iBeams]->SetBrightness( 64 );
m_pBeam[m_iBeams]->SetNoise( 80 );
m_pBeam[m_iBeams]->pev->spawnflags |= SF_BEAM_TEMPORARY; // Flag these to be destroyed on save/restore or level transition
m_iBeams++;
}
@ -818,6 +819,7 @@ void CISlave :: WackBeam( int side, CBaseEntity *pEntity )
m_pBeam[m_iBeams]->SetColor( 180, 255, 96 );
m_pBeam[m_iBeams]->SetBrightness( 255 );
m_pBeam[m_iBeams]->SetNoise( 80 );
m_pBeam[m_iBeams]->pev->spawnflags |= SF_BEAM_TEMPORARY; // Flag these to be destroyed on save/restore or level transition
m_iBeams++;
}
@ -848,6 +850,7 @@ void CISlave :: ZapBeam( int side )
m_pBeam[m_iBeams]->SetColor( 180, 255, 96 );
m_pBeam[m_iBeams]->SetBrightness( 255 );
m_pBeam[m_iBeams]->SetNoise( 20 );
m_pBeam[m_iBeams]->pev->spawnflags |= SF_BEAM_TEMPORARY; // Flag these to be destroyed on save/restore or level transition
m_iBeams++;
pEntity = CBaseEntity::Instance(tr.pHit);

View File

@ -1400,7 +1400,7 @@ float CBaseMonster::OpenDoorAndWait( entvars_t *pevDoor )
//ALERT( at_aiconsole, "A door. " );
CBaseEntity *pcbeDoor = CBaseEntity::Instance( pevDoor );
if( pcbeDoor && !pcbeDoor->IsLockedByMaster() )
if( pcbeDoor )
{
//ALERT( at_aiconsole, "unlocked! " );
pcbeDoor->Use( this, this, USE_ON, 0.0 );
@ -3248,27 +3248,6 @@ BOOL CBaseMonster::FCanActiveIdle( void )
return FALSE;
}
void CBaseMonster::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation )
{
if( pszSentence && IsAlive() )
{
if( pszSentence[0] == '!' )
EMIT_SOUND_DYN( edict(), CHAN_VOICE, pszSentence, volume, attenuation, 0, PITCH_NORM );
else
SENTENCEG_PlayRndSz( edict(), pszSentence, volume, attenuation, 0, PITCH_NORM );
}
}
void CBaseMonster::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener )
{
PlaySentence( pszSentence, duration, volume, attenuation );
}
void CBaseMonster::SentenceStop( void )
{
EMIT_SOUND( edict(), CHAN_VOICE, "common/null.wav", 1.0, ATTN_IDLE );
}
void CBaseMonster::CorpseFallThink( void )
{
if( pev->flags & FL_ONGROUND )

View File

@ -54,6 +54,13 @@ void CMP5::Spawn()
m_iDefaultAmmo = MP5_DEFAULT_GIVE;
#if CLIENT_DLL
if( bIsMultiplayer() )
#else
if( g_pGameRules->IsMultiplayer() )
#endif
m_iDefaultAmmo = MP5_DEFAULT_GIVE_MP;
FallInit();// get ready to fall down.
}

View File

@ -31,6 +31,7 @@
#include "voice_gamemgr.h"
#endif
#include "hltv.h"
#include "trains.h"
extern DLL_GLOBAL CGameRules *g_pGameRules;
extern DLL_GLOBAL BOOL g_fGameOver;
@ -150,7 +151,7 @@ void CHalfLifeMultiplay::RefreshSkillData( void )
gSkillData.plrDmg9MM = 12;
// 357 Round
gSkillData.plrDmg357 = 40;
gSkillData.plrDmg357 = 50;
// MP5 Round
gSkillData.plrDmgMP5 = 12;
@ -345,70 +346,11 @@ BOOL CHalfLifeMultiplay::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerI
return FALSE;
}
//=========================================================
//=========================================================
BOOL CHalfLifeMultiplay::GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon )
{
CBasePlayerItem *pCheck;
CBasePlayerItem *pBest;// this will be used in the event that we don't find a weapon in the same category.
int iBestWeight;
int i;
iBestWeight = -1;// no weapon lower than -1 can be autoswitched to
pBest = NULL;
if( !pCurrentWeapon->CanHolster() )
{
// can't put this gun away right now, so can't switch.
return FALSE;
}
for( i = 0; i < MAX_ITEM_TYPES; i++ )
{
pCheck = pPlayer->m_rgpPlayerItems[i];
while( pCheck )
{
if( pCheck->iWeight() > -1 && pCheck->iWeight() == pCurrentWeapon->iWeight() && pCheck != pCurrentWeapon )
{
// this weapon is from the same category.
if ( pCheck->CanDeploy() )
{
if ( pPlayer->SwitchWeapon( pCheck ) )
{
return TRUE;
}
}
}
else if( pCheck->iWeight() > iBestWeight && pCheck != pCurrentWeapon )// don't reselect the weapon we're trying to get rid of
{
//ALERT ( at_console, "Considering %s\n", STRING( pCheck->pev->classname ) );
// we keep updating the 'best' weapon just in case we can't find a weapon of the same weight
// that the player was using. This will end up leaving the player with his heaviest-weighted
// weapon.
if( pCheck->CanDeploy() )
{
// if this weapon is useable, flag it as the best
iBestWeight = pCheck->iWeight();
pBest = pCheck;
}
}
pCheck = pCheck->m_pNext;
}
}
// if we make it here, we've checked all the weapons and found no useable
// weapon in the same catagory as the current weapon.
// if pBest is null, we didn't find ANYTHING. Shouldn't be possible- should always
// at least get the crowbar, but ya never know.
if( !pBest )
{
return FALSE;
}
pPlayer->SwitchWeapon( pBest );
return TRUE;
return HLGetNextBestWeapon( pPlayer, pCurrentWeapon );
}
//=========================================================
@ -459,12 +401,13 @@ void CHalfLifeMultiplay::InitHUD( CBasePlayer *pl )
// sending just one score makes the hud scoreboard active; otherwise
// it is just disabled for single play
MESSAGE_BEGIN( MSG_ONE, gmsgScoreInfo, NULL, pl->edict() );
//fix a bug in the information about the player's score when he left the server, so that his score would not be transferred to another player(seems to work)
MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo );
WRITE_BYTE( ENTINDEX(pl->edict()) );
WRITE_SHORT( (int)pl->pev->frags );
WRITE_SHORT( pl->m_iDeaths );
WRITE_SHORT( 0 );
WRITE_SHORT( 0 );
WRITE_SHORT( 0 );
WRITE_SHORT( 0 );
WRITE_SHORT( GetTeamIndex( pl->m_szTeamName ) + 1 );
MESSAGE_END();
SendMOTDToClient( pl->edict() );
@ -647,6 +590,16 @@ void CHalfLifeMultiplay::PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller,
CBaseEntity *ktmp = CBaseEntity::Instance( pKiller );
if( ktmp && (ktmp->Classify() == CLASS_PLAYER ) )
peKiller = (CBasePlayer*)ktmp;
else if( ktmp && ktmp->Classify() == CLASS_VEHICLE )
{
CBasePlayer *pDriver = (CBasePlayer *)( (CFuncVehicle *)ktmp )->m_pDriver;
if( pDriver != NULL )
{
pKiller = pDriver->pev;
peKiller = (CBasePlayer *)pDriver;
}
}
if( pVictim->pev == pKiller )
{
@ -1712,3 +1665,219 @@ void CHalfLifeMultiplay::SendMOTDToClient( edict_t *client )
FREE_FILE( (void*)aFileList );
}
int CMultiplayBusters::WeaponShouldRespawn( CBasePlayerItem *pWeapon )
{
if( pWeapon->m_iId == WEAPON_EGON )
return GR_WEAPON_RESPAWN_NO;
return CHalfLifeMultiplay::WeaponShouldRespawn( pWeapon );
}
BOOL CMultiplayBusters::CanHaveItem( CBasePlayer *pPlayer, CItem *pItem )
{
return BustingCanHaveItem( pPlayer, pItem );
}
BOOL CMultiplayBusters::CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pItem )
{
if( !BustingCanHaveItem( pPlayer, pItem ))
return FALSE;
return CHalfLifeMultiplay::CanHavePlayerItem( pPlayer, pItem );
}
int CMultiplayBusters::IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled )
{
if( IsPlayerBusting( pAttacker ))
return 1;
if( IsPlayerBusting( pKilled ))
return 2;
return 0;
}
void CMultiplayBusters::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor )
{
if( IsPlayerBusting( pVictim )
|| IsPlayerBusting( CBaseEntity::Instance( pKiller )))
CHalfLifeMultiplay::DeathNotice( pVictim, pKiller, pevInflictor );
}
void CMultiplayBusters::PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor )
{
if( IsPlayerBusting( pVictim ))
{
UTIL_ClientPrintAll( HUD_PRINTCENTER, "The Buster is dead!!" );
m_flEgonBustingCheckTime = -1.0f;
CBasePlayer *peKiller = NULL;
CBaseEntity *ktmp = CBaseEntity::Instance( pKiller );
if( ktmp && ( ktmp->Classify() == CLASS_PLAYER ) )
peKiller = (CBasePlayer*)ktmp;
else if( ktmp && ktmp->Classify() == CLASS_VEHICLE )
{
CBasePlayer *pDriver = (CBasePlayer *)( (CFuncVehicle *)ktmp )->m_pDriver;
if( pDriver != NULL )
{
pKiller = pDriver->pev;
peKiller = (CBasePlayer *)pDriver;
}
}
if( peKiller && peKiller->IsPlayer() )
{
UTIL_ClientPrintAll( HUD_PRINTTALK, UTIL_VarArgs( "%s has killed the Buster!", STRING( peKiller->pev->netname )));
}
pVictim->pev->renderfx = 0;
pVictim->pev->rendercolor = g_vecZero;
}
CHalfLifeMultiplay::PlayerKilled( pVictim, pKiller, pInflictor );
}
void CMultiplayBusters::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer )
{
SetPlayerModel( pPlayer, FALSE );
CHalfLifeMultiplay::ClientUserInfoChanged( pPlayer, infobuffer );
}
void CMultiplayBusters::PlayerSpawn( CBasePlayer *pPlayer )
{
CHalfLifeMultiplay::PlayerSpawn( pPlayer );
SetPlayerModel( pPlayer, FALSE );
}
bool IsPlayerBusting( CBaseEntity *pPlayer )
{
if( g_pGameRules->IsBustingGame()
&& pPlayer && pPlayer->IsPlayer()
&& ((CBasePlayer*)pPlayer)->HasPlayerItemFromID( WEAPON_EGON ))
return true;
return false;
}
BOOL BustingCanHaveItem( CBasePlayer *pPlayer, CBaseEntity *pItem )
{
if( IsPlayerBusting( pPlayer )
&& !( strncmp( STRING( pItem->pev->classname ), "weapon_", 7 )
&& strncmp( STRING( pItem->pev->classname ), "ammo_", 5 )))
return FALSE;
return TRUE;
}
CMultiplayBusters::CMultiplayBusters()
{
CHalfLifeMultiplay();
m_flEgonBustingCheckTime = -1.0;
}
void CMultiplayBusters::CheckForEgons( void )
{
CBaseEntity *pPlayer;
CWeaponBox *pWeaponBox = NULL;
CBasePlayerItem *pWeapon;
CBasePlayer *pNewBuster = NULL;
int i, bestfrags = 9999;
if( m_flEgonBustingCheckTime <= 0.0f )
{
m_flEgonBustingCheckTime = gpGlobals->time + 10.0f;
return;
}
if( gpGlobals->time < m_flEgonBustingCheckTime )
return;
m_flEgonBustingCheckTime = -1.0f;
for( i = 1; i <= gpGlobals->maxClients; i++ )
{
pPlayer = UTIL_PlayerByIndex( i );
if( IsPlayerBusting( pPlayer ))
return;
}
for( i = 1; i <= gpGlobals->maxClients; i++ )
{
pPlayer = UTIL_PlayerByIndex( i );
if( pPlayer && pPlayer->pev->frags < bestfrags )
{
pNewBuster = (CBasePlayer*)pPlayer;
bestfrags = pPlayer->pev->frags;
}
}
if( !pNewBuster )
return;
pNewBuster->GiveNamedItem( "weapon_egon" );
while( ( pWeaponBox = (CWeaponBox*)UTIL_FindEntityByClassname( pWeaponBox, "weaponbox" )))
{
// destroy weaponboxes with egons
for( i = 0; i < MAX_ITEM_TYPES; i++ )
{
pWeapon = pWeaponBox->m_rgpPlayerItems[i];
while( pWeapon )
{
if( pWeapon->m_iId != WEAPON_EGON )
{
pWeapon = pWeapon->m_pNext;
continue;
}
pWeaponBox->Kill();
pWeapon = 0;
i = MAX_ITEM_TYPES;
}
}
}
}
void CMultiplayBusters::Think( void )
{
CheckForEgons();
CHalfLifeMultiplay::Think();
}
void CMultiplayBusters::SetPlayerModel( CBasePlayer *pPlayer, BOOL bKnownBuster )
{
const char *pszModel = NULL;
if( bKnownBuster || IsPlayerBusting( pPlayer ))
{
pszModel = "ivan";
}
else
{
pszModel = "skeleton";
}
g_engfuncs.pfnSetClientKeyValue( ENTINDEX( pPlayer->edict()), g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict()), "model", pszModel );
}
void CMultiplayBusters::PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon )
{
if( pWeapon->m_iId != WEAPON_EGON )
return;
pPlayer->RemoveAllItems( FALSE );
UTIL_ClientPrintAll( HUD_PRINTCENTER, "Long live the new Buster!" );
UTIL_ClientPrintAll( HUD_PRINTTALK, UTIL_VarArgs( "%s is busting!\n", STRING( pPlayer->pev->netname )));
SetPlayerModel( pPlayer, TRUE );
pPlayer->pev->health = pPlayer->pev->max_health;
pPlayer->pev->armorvalue = MAX_NORMAL_BATTERY;
pPlayer->pev->renderfx = kRenderFxGlowShell;
pPlayer->pev->renderamt = 25;
pPlayer->pev->rendercolor = Vector( 0, 75, 250 );
pPlayer->m_rgAmmo[pWeapon->PrimaryAmmoIndex()] = pPlayer->ammo_uranium = 100;
}

View File

@ -48,8 +48,6 @@ int gEvilImpulse101;
BOOL g_markFrameBounds = 0; //LRC
extern DLL_GLOBAL int g_iSkillLevel, gDisplayTitle;
extern "C" int g_bhopcap;
BOOL gInitHUD = TRUE;
extern void CopyToBodyQue( entvars_t *pev);
@ -204,7 +202,6 @@ int gmsgShowMenu = 0;
int gmsgGeigerRange = 0;
int gmsgTeamNames = 0;
int gmsgStatusIcon = 0; //LRC
int gmsgBhopcap = 0;
int gmsgStatusText = 0;
int gmsgStatusValue = 0;
@ -261,7 +258,6 @@ void LinkUserMessages( void )
gmsgStatusText = REG_USER_MSG( "StatusText", -1 );
gmsgStatusValue = REG_USER_MSG( "StatusValue", 3 );
gmsgBhopcap = REG_USER_MSG( "Bhopcap", 1 );
}
LINK_ENTITY_TO_CLASS( player, CBasePlayer )
@ -696,7 +692,7 @@ void CBasePlayer::PackDeadPlayerItems( void )
{
int iWeaponRules;
int iAmmoRules;
int i;
int i, j;
CBasePlayerWeapon *rgpPackWeapons[MAX_WEAPONS] = {0,};
int iPackAmmo[MAX_AMMO_SLOTS];
int iPW = 0;// index into packweapons array
@ -731,16 +727,26 @@ void CBasePlayer::PackDeadPlayerItems( void )
if( m_pActiveItem && pPlayerItem == m_pActiveItem )
{
// this is the active item. Pack it.
rgpPackWeapons[iPW++] = (CBasePlayerWeapon *)pPlayerItem;
rgpPackWeapons[iPW] = (CBasePlayerWeapon *)pPlayerItem;
}
break;
case GR_PLR_DROP_GUN_ALL:
rgpPackWeapons[iPW++] = (CBasePlayerWeapon *)pPlayerItem;
rgpPackWeapons[iPW] = (CBasePlayerWeapon *)pPlayerItem;
break;
default:
break;
}
if( rgpPackWeapons[iPW] )
{
// complete the reload.
j = Q_min( rgpPackWeapons[iPW]->iMaxClip() - rgpPackWeapons[iPW]->m_iClip, m_rgAmmo[rgpPackWeapons[iPW]->m_iPrimaryAmmoType] );
// Add them to the clip
rgpPackWeapons[iPW]->m_iClip += j;
m_rgAmmo[rgpPackWeapons[iPW]->m_iPrimaryAmmoType] -= j;
iPW++;
}
pPlayerItem = pPlayerItem->m_pNext;
}
}
@ -790,24 +796,43 @@ void CBasePlayer::PackDeadPlayerItems( void )
iPA = 0;
iPW = 0;
// pack the ammo
while( iPackAmmo[iPA] != -1 )
if( g_pGameRules->IsBustingGame())
{
pWeaponBox->PackAmmo( MAKE_STRING( CBasePlayerItem::AmmoInfoArray[iPackAmmo[iPA]].pszName ), m_rgAmmo[iPackAmmo[iPA]] );
iPA++;
while( rgpPackWeapons[iPW] )
{
// weapon unhooked from the player. Pack it into der box.
if( FClassnameIs( rgpPackWeapons[iPW]->pev, "weapon_egon" ))
{
pWeaponBox->PackWeapon( rgpPackWeapons[iPW] );
SET_MODEL( pWeaponBox->edict(), "models/w_egon.mdl" );
pWeaponBox->pev->velocity = g_vecZero;
pWeaponBox->pev->renderfx = kRenderFxGlowShell;
pWeaponBox->pev->renderamt = 25;
pWeaponBox->pev->rendercolor = Vector( 0, 75, 250 );
break;
}
iPW++;
}
}
// now pack all of the items in the lists
while( rgpPackWeapons[iPW] )
else
{
// weapon unhooked from the player. Pack it into der box.
pWeaponBox->PackWeapon( rgpPackWeapons[iPW] );
// pack the ammo
while( iPackAmmo[iPA] != -1 )
{
pWeaponBox->PackAmmo( MAKE_STRING( CBasePlayerItem::AmmoInfoArray[iPackAmmo[iPA]].pszName ), m_rgAmmo[iPackAmmo[iPA]] );
iPA++;
}
iPW++;
// now pack all of the items in the lists
while( rgpPackWeapons[iPW] )
{
// weapon unhooked from the player. Pack it into der box.
pWeaponBox->PackWeapon( rgpPackWeapons[iPW] );
iPW++;
}
pWeaponBox->pev->velocity = pev->velocity * 1.2f;// weaponbox has player's velocity, then some.
}
pWeaponBox->pev->velocity = pev->velocity * 1.2;// weaponbox has player's velocity, then some.
RemoveAllItems( TRUE );// now strip off everything that wasn't handled by the code above.
}
@ -1034,7 +1059,7 @@ void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib )
SetAnimation( PLAYER_DIE );
m_iRespawnFrames = 0;
m_flRespawnTimer = 0;
pev->modelindex = g_ulModelIndexPlayer; // don't use eyes
@ -1072,6 +1097,9 @@ void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib )
// UNDONE: Put this in, but add FFADE_PERMANENT and make fade time 8.8 instead of 4.12
// UTIL_ScreenFade( edict(), Vector( 128, 0, 0 ), 6, 15, 255, FFADE_OUT | FFADE_MODULATE );
if( g_pGameRules->IsMultiplayer())
pev->solid = SOLID_NOT;
if( ( pev->health < -40 && iGib != GIB_NEVER ) || iGib == GIB_ALWAYS )
{
pev->solid = SOLID_NOT;
@ -1432,23 +1460,30 @@ void CBasePlayer::PlayerDeathThink( void )
PackDeadPlayerItems();
}
if( pev->modelindex && ( !m_fSequenceFinished ) && ( pev->deadflag == DEAD_DYING ) )
if( pev->modelindex && ( !m_fSequenceFinished ) && ( pev->deadflag == DEAD_DYING ))
{
StudioFrameAdvance();
m_iRespawnFrames++; // Note, these aren't necessarily real "frames", so behavior is dependent on # of client movement commands
if( m_iRespawnFrames < 120 ) // Animations should be no longer than this
m_flRespawnTimer = gpGlobals->frametime + m_flRespawnTimer; // Note, these aren't necessarily real "frames", so behavior is dependent on # of client movement commands
if( m_flRespawnTimer < 4.0f ) // Animations should be no longer than this
return;
}
if( pev->deadflag == DEAD_DYING )
{
if( g_pGameRules->IsMultiplayer() && m_fSequenceFinished && pev->movetype == MOVETYPE_NONE )
{
CopyToBodyQue( pev );
pev->modelindex = 0;
}
pev->deadflag = DEAD_DEAD;
}
// once we're done animating our death and we're on the ground, we want to set movetype to None so our dead body won't do collisions and stuff anymore
// this prevents a bug where the dead body would go to a player's head if he walked over it while the dead player was clicking their button to respawn
if( pev->movetype != MOVETYPE_NONE && FBitSet( pev->flags, FL_ONGROUND ) )
pev->movetype = MOVETYPE_NONE;
if( pev->deadflag == DEAD_DYING )
pev->deadflag = DEAD_DEAD;
StopAnimation();
pev->effects |= EF_NOINTERP;
@ -1488,7 +1523,7 @@ void CBasePlayer::PlayerDeathThink( void )
return;
pev->button = 0;
m_iRespawnFrames = 0;
m_flRespawnTimer = 0;
//ALERT( at_console, "Respawn\n" );
@ -1650,18 +1685,31 @@ void CBasePlayer::PlayerUse( void )
{
m_afPhysicsFlags &= ~PFLAG_ONTRAIN;
m_iTrain = TRAIN_NEW|TRAIN_OFF;
CBaseEntity *pTrain = Instance( pev->groundentity );
if( pTrain && pTrain->Classify() == CLASS_VEHICLE )
{
( (CFuncVehicle *)pTrain )->m_pDriver = NULL;
}
return;
}
else
{ // Start controlling the train!
CBaseEntity *pTrain = CBaseEntity::Instance( pev->groundentity );
if( pTrain && !( pev->button & IN_JUMP ) && FBitSet( pev->flags, FL_ONGROUND ) && (pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE ) && pTrain->OnControls( pev ) )
if( pTrain && !( pev->button & IN_JUMP ) && FBitSet( pev->flags, FL_ONGROUND ) && ( pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE ) && pTrain->OnControls( pev ) )
{
m_afPhysicsFlags |= PFLAG_ONTRAIN;
m_iTrain = TrainSpeed( (int)pTrain->pev->speed, pTrain->pev->impulse );
m_iTrain |= TRAIN_NEW;
EMIT_SOUND( ENT( pev ), CHAN_ITEM, "plats/train_use1.wav", 0.8, ATTN_NORM );
if( pTrain->Classify() == CLASS_VEHICLE )
{
EMIT_SOUND( ENT( pev ), CHAN_ITEM, "plats/vehicle_ignition.wav", 0.8, ATTN_NORM );
( (CFuncVehicle *)pTrain )->m_pDriver = this;
}
else
EMIT_SOUND( ENT( pev ), CHAN_ITEM, "plats/train_use1.wav", 0.8, ATTN_NORM );
return;
}
}
@ -1797,9 +1845,17 @@ void CBasePlayer::Jump()
// If you're standing on a conveyor, add it's velocity to yours (for momentum)
entvars_t *pevGround = VARS( pev->groundentity );
if( pevGround && ( pevGround->flags & FL_CONVEYOR ) )
if( pevGround )
{
pev->velocity = pev->velocity + pev->basevelocity;
if( pevGround->flags & FL_CONVEYOR )
{
pev->velocity = pev->velocity + pev->basevelocity;
}
if( FClassnameIs( pevGround, "func_vehicle" ))
{
pev->velocity = pevGround->velocity + pev->velocity;
}
}
}
@ -2067,30 +2123,62 @@ void CBasePlayer::PreThink( void )
//ALERT( at_error, "In train mode with no train!\n" );
m_afPhysicsFlags &= ~PFLAG_ONTRAIN;
m_iTrain = TRAIN_NEW|TRAIN_OFF;
if( pTrain )
( (CFuncVehicle *)pTrain )->m_pDriver = NULL;
return;
}
}
else if( !FBitSet( pev->flags, FL_ONGROUND ) || FBitSet( pTrain->pev->spawnflags, SF_TRACKTRAIN_NOCONTROL ) || ( pev->button & ( IN_MOVELEFT | IN_MOVERIGHT ) ) )
else if( !FBitSet( pev->flags, FL_ONGROUND ) || FBitSet( pTrain->pev->spawnflags, SF_TRACKTRAIN_NOCONTROL )
|| ( ( pev->button & ( IN_MOVELEFT | IN_MOVERIGHT )) && pTrain->Classify() != CLASS_VEHICLE ))
{
// Turn off the train if you jump, strafe, or the train controls go dead
m_afPhysicsFlags &= ~PFLAG_ONTRAIN;
m_iTrain = TRAIN_NEW | TRAIN_OFF;
( (CFuncVehicle *)pTrain )->m_pDriver = NULL;
return;
}
pev->velocity = g_vecZero;
vel = 0;
if( m_afButtonPressed & IN_FORWARD )
{
vel = 1;
pTrain->Use( this, this, USE_SET, (float)vel );
}
else if( m_afButtonPressed & IN_BACK )
{
vel = -1;
pTrain->Use( this, this, USE_SET, (float)vel );
}
if( pTrain->Classify() == CLASS_VEHICLE )
{
if( pev->button & IN_FORWARD )
{
vel = 1;
pTrain->Use( this, this, USE_SET, vel );
}
if( pev->button & IN_BACK )
{
vel = -1;
pTrain->Use( this, this, USE_SET, vel );
}
if( pev->button & IN_MOVELEFT )
{
vel = 20;
pTrain->Use( this, this, USE_SET, vel );
}
if( pev->button & IN_MOVERIGHT )
{
vel = 30;
pTrain->Use( this, this, USE_SET, vel );
}
}
else
{
if( m_afButtonPressed & IN_FORWARD )
{
vel = 1;
pTrain->Use( this, this, USE_SET, vel );
}
else if( m_afButtonPressed & IN_BACK )
{
vel = -1;
pTrain->Use( this, this, USE_SET, vel );
}
}
iGearId = TrainSpeed( pTrain->pev->speed, pTrain->pev->impulse );
if( iGearId != ( m_iTrain & 0x0F ) ) // Vit_amiN: speed changed
@ -2916,7 +3004,7 @@ edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer )
{
pSpot = g_pLastSpawn;
// Randomize the start spot
for( int i = RANDOM_LONG( 1, 5 ); i > 0; i-- )
for( int i = RANDOM_LONG( 1, 9 ); i > 0; i-- )
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" );
if( FNullEnt( pSpot ) ) // skip over the null point
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" );
@ -2985,6 +3073,7 @@ ReturnSpot:
void CBasePlayer::Spawn( void )
{
m_flStartCharge = gpGlobals->time;
pev->classname = MAKE_STRING( "player" );
pev->health = 100;
pev->armorvalue = 0;
@ -3009,6 +3098,8 @@ void CBasePlayer::Spawn( void )
g_engfuncs.pfnSetPhysicsKeyValue( edict(), "slj", "0" );
g_engfuncs.pfnSetPhysicsKeyValue( edict(), "hl", "1" );
g_engfuncs.pfnSetPhysicsKeyValue( edict(), "fr", "1" );
g_engfuncs.pfnSetPhysicsKeyValue( edict(), "bj", bhopcap.value ? "0" : "1" );
pev->fov = m_iFOV = 0;// init field of view.
m_iClientFOV = -1; // make sure fov reset is sent
@ -3205,6 +3296,9 @@ int CBasePlayer::Restore( CRestore &restore )
// Barring that, we clear it out here instead of using the incorrect restored time value.
m_flNextAttack = UTIL_WeaponTimeBase();
#endif
if( m_flFlashLightTime == 0.0f )
m_flFlashLightTime = 1.0f;
return status;
}
@ -3571,7 +3665,6 @@ void CBasePlayer::ForceClientDllUpdate( void )
m_fWeapon = FALSE; // Force weapon send
m_fKnownItem = FALSE; // Force weaponinit messages.
m_fInitHUD = TRUE; // Force HUD gmsgResetHUD message
m_bSentBhopcap = true; // a1ba: Update bhopcap state
memset( m_rgAmmoLast, 0, sizeof( m_rgAmmoLast )); // a1ba: Force update AmmoX
@ -4373,15 +4466,6 @@ void CBasePlayer::UpdateClientData( void )
UpdateStatusBar();
m_flNextSBarUpdateTime = gpGlobals->time + 0.2f;
}
// Send the current bhopcap state.
if( !m_bSentBhopcap )
{
m_bSentBhopcap = true;
MESSAGE_BEGIN( MSG_ONE, gmsgBhopcap, NULL, pev );
WRITE_BYTE( g_bhopcap );
MESSAGE_END();
}
}
//=========================================================
@ -4843,6 +4927,31 @@ BOOL CBasePlayer::HasNamedPlayerItem( const char *pszItemName )
return FALSE;
}
//=========================================================
// HasPlayerItemFromID
//=========================================================
BOOL CBasePlayer::HasPlayerItemFromID( int nID )
{
CBasePlayerItem *pItem;
int i;
for( i = 0; i < MAX_ITEM_TYPES; i++ )
{
pItem = m_rgpPlayerItems[i];
while( pItem )
{
if( nID == pItem->m_iId )
{
return TRUE;
}
pItem = pItem->m_pNext;
}
}
return FALSE;
}
//=========================================================
//
//=========================================================

View File

@ -205,7 +205,7 @@ public:
Vector m_vecAutoAim;
BOOL m_fOnTarget;
int m_iDeaths;
float m_iRespawnFrames; // used in PlayerDeathThink() to make sure players can always respawn
float m_flRespawnTimer; // used in PlayerDeathThink() to make sure players can always respawn
int m_lastx, m_lasty; // These are the previous update's crosshair angles, DON"T SAVE/RESTORE
@ -284,6 +284,7 @@ public:
void DropPlayerItem ( char *pszItemName );
BOOL HasPlayerItem( CBasePlayerItem *pCheckItem );
BOOL HasNamedPlayerItem( const char *pszItemName );
BOOL HasPlayerItemFromID( int nID );
BOOL HasWeapons( void );// do I have ANY weapons?
void SelectPrevItem( int iItem );
void SelectNextItem( int iItem );
@ -347,8 +348,6 @@ public:
int m_iAutoWepSwitch;
Vector m_vecLastViewAngles;
bool m_bSentBhopcap; // If false, the player just joined and needs a bhopcap message.
};
#define AUTOAIM_2DEGREES 0.0348994967025

File diff suppressed because it is too large Load Diff

View File

@ -133,6 +133,25 @@ CRpgRocket *CRpgRocket::CreateRpgRocket( Vector vecOrigin, Vector vecAngles, CBa
return pRocket;
}
void CRpgRocket::Explode( TraceResult *pTrace, int bitsDamageType )
{
if( CRpg *pLauncher = GetLauncher())
{
// my launcher is still around, tell it I'm dead.
pLauncher->m_cActiveRockets--;
m_hLauncher = 0;
}
STOP_SOUND( edict(), CHAN_VOICE, "weapons/rocket1.wav" );
CGrenade::Explode( pTrace, bitsDamageType );
}
CRpg *CRpgRocket::GetLauncher( void )
{
return (CRpg*)( (CBaseEntity*)m_hLauncher );
}
//=========================================================
//=========================================================
void CRpgRocket::Spawn( void )
@ -167,10 +186,11 @@ void CRpgRocket::Spawn( void )
//=========================================================
void CRpgRocket::RocketTouch( CBaseEntity *pOther )
{
if( CRpg* pLauncher = (CRpg*)( (CBaseEntity*)( m_hLauncher ) ) )
if( CRpg *pLauncher = GetLauncher())
{
// my launcher is still around, tell it I'm dead.
pLauncher->m_cActiveRockets--;
m_hLauncher = 0;
}
STOP_SOUND( edict(), CHAN_VOICE, "weapons/rocket1.wav" );
@ -281,17 +301,23 @@ void CRpgRocket::FollowThink( void )
}
pev->velocity = pev->velocity * 0.2f + vecTarget * flSpeed * 0.798f;
if( ( pev->waterlevel == 0 || pev->watertype == CONTENT_FOG ) && pev->velocity.Length() < 1500.0f )
{
if( CRpg *pLauncher = (CRpg*)( (CBaseEntity*)( m_hLauncher ) ) )
{
// my launcher is still around, tell it I'm dead.
pLauncher->m_cActiveRockets--;
}
Detonate();
}
}
// ALERT( at_console, "%.0f\n", flSpeed );
if( CRpg *pLauncher = GetLauncher())
{
if( ( pev->origin - pLauncher->pev->origin ).Length() > 8192 || gpGlobals->time - m_flIgniteTime > 6.0f )
{
// my launcher is still around, tell it I'm dead.
pLauncher->m_cActiveRockets--;
m_hLauncher = 0;
}
}
if( UTIL_PointContents( pev->origin ) == CONTENTS_SKY )
Detonate();
SetNextThink( 0.1f );
}
#endif
@ -391,7 +417,7 @@ int CRpg::GetItemInfo( ItemInfo *p )
p->iSlot = 3;
p->iPosition = 0;
p->iId = m_iId = WEAPON_RPG;
p->iFlags = 0;
p->iFlags = ITEM_FLAG_NOCHOICE;
p->iWeight = RPG_WEIGHT;
return 1;

View File

@ -22,6 +22,7 @@
#include "nodes.h"
#include "player.h"
#include "gamerules.h"
#include "game.h"
enum satchel_state
{
@ -190,23 +191,39 @@ LINK_ENTITY_TO_CLASS( weapon_satchel, CSatchel )
//=========================================================
int CSatchel::AddDuplicate( CBasePlayerItem *pOriginal )
{
#if !CLIENT_DLL
CSatchel *pSatchel;
int nNumSatchels, nSatchelsInPocket;
CBaseEntity *ent;
#if CLIENT_DLL
if( bIsMultiplayer() )
#else
if( g_pGameRules->IsMultiplayer() )
#endif
{
if( satchelfix.value )
{
if( !pOriginal->m_pPlayer )
return TRUE;
nNumSatchels = 0;
nSatchelsInPocket = pOriginal->m_pPlayer->m_rgAmmo[pOriginal->PrimaryAmmoIndex()];
ent = NULL;
while( ( ent = UTIL_FindEntityInSphere( ent, pOriginal->m_pPlayer->pev->origin, 4096 )) != NULL )
{
if( FClassnameIs( ent->pev, "monster_satchel" ))
nNumSatchels += ent->pev->owner == pOriginal->m_pPlayer->edict();
}
}
pSatchel = (CSatchel *)pOriginal;
if( pSatchel->m_chargeReady != SATCHEL_IDLE )
if( pSatchel->m_chargeReady != SATCHEL_IDLE
&& ( satchelfix.value && nSatchelsInPocket + nNumSatchels > SATCHEL_MAX_CARRY - 1 ))
{
// player has some satchels deployed. Refuse to add more.
return FALSE;
}
}
#endif
return CBasePlayerWeapon::AddDuplicate( pOriginal );
}
@ -330,8 +347,9 @@ void CSatchel::Holster( int skiplocal /* = 0 */ )
}
}
void CSatchel::PrimaryAttack()
void CSatchel::PrimaryAttack( void )
{
#if SATCHEL_OLD_BEHAVIOUR
switch( m_chargeReady )
{
case SATCHEL_IDLE:
@ -347,9 +365,9 @@ void CSatchel::PrimaryAttack()
CBaseEntity *pSatchel = NULL;
while( ( pSatchel = UTIL_FindEntityInSphere( pSatchel, m_pPlayer->pev->origin, 4096 ) ) != NULL )
while( ( pSatchel = UTIL_FindEntityInSphere( pSatchel, m_pPlayer->pev->origin, 4096 )) != NULL )
{
if( FClassnameIs( pSatchel->pev, "monster_satchel" ) )
if( FClassnameIs( pSatchel->pev, "monster_satchel" ))
{
if( pSatchel->pev->owner == pPlayer )
{
@ -368,14 +386,56 @@ void CSatchel::PrimaryAttack()
// we're reloading, don't allow fire
break;
}
}
void CSatchel::SecondaryAttack( void )
{
#else
if( m_chargeReady != SATCHEL_RELOAD )
{
Throw();
}
#endif
}
void CSatchel::SecondaryAttack( void )
{
#if SATCHEL_OLD_BEHAVIOUR
if( m_chargeReady != SATCHEL_RELOAD )
{
Throw();
}
#else
switch( m_chargeReady )
{
case SATCHEL_IDLE:
break;
case SATCHEL_READY:
{
SendWeaponAnim( SATCHEL_RADIO_FIRE );
edict_t *pPlayer = m_pPlayer->edict();
CBaseEntity *pSatchel = NULL;
while( ( pSatchel = UTIL_FindEntityInSphere( pSatchel, m_pPlayer->pev->origin, 4096 )) != NULL )
{
if( FClassnameIs( pSatchel->pev, "monster_satchel" ))
{
if( pSatchel->pev->owner == pPlayer )
{
pSatchel->Use( m_pPlayer, m_pPlayer, USE_ON, 0 );
}
}
}
m_chargeReady = SATCHEL_RELOAD;
m_flNextPrimaryAttack = GetNextAttackDelay( 0.5f );
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5f;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5f;
break;
}
case SATCHEL_RELOAD:
// we're reloading, don't allow fire
break;
}
#endif
}
void CSatchel::Throw( void )

View File

@ -29,6 +29,8 @@
#define NUM_SCIENTIST_HEADS 4 // four heads available for scientist model
static cvar_t *g_psv_override_scientist_mdl;
enum
{
HEAD_GLASSES = 0,
@ -113,6 +115,8 @@ public:
CUSTOM_SCHEDULES
private:
const char *GetScientistModel( void );
float m_painTime;
float m_healTime;
float m_fearTime;
@ -422,6 +426,20 @@ void CScientist::DeclineFollowing( void )
PlaySentence( m_szGrp[TLK_DECLINE], 2, VOL_NORM, ATTN_NORM ); //LRC
}
const char *CScientist::GetScientistModel( void )
{
if( !g_psv_override_scientist_mdl )
g_psv_override_scientist_mdl = CVAR_GET_POINTER( "_sv_override_scientist_mdl" );
if( !( g_psv_override_scientist_mdl && g_psv_override_scientist_mdl->string ))
return "models/scientist.mdl";
if( strlen( g_psv_override_scientist_mdl->string ) < sizeof( "01.mdl" ) - 1 )
return "models/scientist.mdl";
return g_psv_override_scientist_mdl->string;
}
void CScientist::Scream( void )
{
if( FOkToSpeak() )
@ -651,7 +669,7 @@ void CScientist::Spawn( void )
if (pev->model)
SET_MODEL(ENT(pev), STRING(pev->model)); //LRC
else
SET_MODEL( ENT( pev ), "models/scientist.mdl" );
SET_MODEL( ENT( pev ), GetScientistModel());
UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
pev->solid = SOLID_SLIDEBOX;
@ -686,7 +704,7 @@ void CScientist::Precache( void )
if (pev->model)
PRECACHE_MODEL(STRING(pev->model)); //LRC
else
PRECACHE_MODEL( "models/scientist.mdl" );
PRECACHE_MODEL( GetScientistModel());
PRECACHE_SOUND( "scientist/sci_pain1.wav" );
PRECACHE_SOUND( "scientist/sci_pain2.wav" );
PRECACHE_SOUND( "scientist/sci_pain3.wav" );
@ -1117,6 +1135,9 @@ public:
void KeyValue( KeyValueData *pkvd );
int m_iPose;// which sequence to display
static const char *m_szPoses[7];
private:
const char *GetScientistModel( void );
};
const char *CDeadScientist::m_szPoses[] =
@ -1147,8 +1168,10 @@ LINK_ENTITY_TO_CLASS( monster_scientist_dead, CDeadScientist )
//
void CDeadScientist::Spawn()
{
PRECACHE_MODEL( "models/scientist.mdl" );
SET_MODEL( ENT( pev ), "models/scientist.mdl" );
const char *pszModel = GetScientistModel();
PRECACHE_MODEL( pszModel );
SET_MODEL( ENT( pev ), pszModel );
pev->effects = 0;
pev->sequence = 0;
@ -1180,6 +1203,20 @@ void CDeadScientist::Spawn()
MonsterInitDead();
}
const char *CDeadScientist::GetScientistModel( void )
{
if( !g_psv_override_scientist_mdl )
g_psv_override_scientist_mdl = CVAR_GET_POINTER( "_sv_override_scientist_mdl" );
if( !( g_psv_override_scientist_mdl && g_psv_override_scientist_mdl->string ))
return "models/scientist.mdl";
if( strlen( g_psv_override_scientist_mdl->string ) < sizeof( "01.mdl" ) - 1 )
return "models/scientist.mdl";
return g_psv_override_scientist_mdl->string;
}
//=========================================================
// Sitting Scientist PROP
//=========================================================

View File

@ -889,9 +889,9 @@ public:
static TYPEDESCRIPTION m_SaveData[];
CBaseMonster *FindEntity( CBaseEntity *pActivator );
BOOL AcceptableSpeaker( CBaseMonster *pMonster );
BOOL StartSentence( CBaseMonster *pTarget );
CBaseToggle *FindEntity( CBaseEntity *pActivator );
BOOL AcceptableSpeaker( CBaseToggle *pTarget );
BOOL StartSentence( CBaseToggle *pTarget );
private:
int m_iszSentence; // string index for idle animation
@ -1048,21 +1048,21 @@ void CScriptedSentence::FindThink( void )
return;
}
CBaseMonster *pMonster = FindEntity( m_hActivator );
if( pMonster )
CBaseToggle *pTarget = FindEntity( m_hActivator );
if( pTarget )
{
m_playing = TRUE;
StartSentence( pMonster );
StartSentence( pTarget );
if( pev->spawnflags & SF_SENTENCE_ONCE )
UTIL_Remove( this );
SetThink(&CScriptedSentence :: DurationThink );
SetNextThink( m_flDuration );
m_active = FALSE;
//ALERT( at_console, "%s: found monster %s\n", STRING( m_iszSentence ), STRING( m_iszEntity ) );
//ALERT( at_console, "%s: found target %s\n", STRING( m_iszSentence ), STRING( m_iszEntity ) );
}
else
{
//ALERT( at_console, "%s: can't find monster %s\n", STRING( m_iszSentence ), STRING( m_iszEntity ) );
//ALERT( at_console, "%s: can't find target %s\n", STRING( m_iszSentence ), STRING( m_iszEntity ) );
SetNextThink( m_flRepeat + 0.5f );
}
}
@ -1083,46 +1083,58 @@ void CScriptedSentence::DelayThink( void )
SetThink( &CScriptedSentence::FindThink );
}
BOOL CScriptedSentence::AcceptableSpeaker( CBaseMonster *pMonster )
BOOL CScriptedSentence::AcceptableSpeaker( CBaseToggle *pTarget )
{
if( pMonster )
CBaseMonster *pMonster;
EHANDLE hTarget;
if( pTarget )
{
if( pev->spawnflags & SF_SENTENCE_FOLLOWERS )
hTarget = pTarget->MyMonsterPointer();
if( hTarget != 0 )
{
if( pMonster->m_hTargetEnt == 0 || !pMonster->m_hTargetEnt->IsPlayer() )
return FALSE;
CBaseMonster *pMonster = (CBaseMonster*)( (CBaseEntity*)hTarget );
if( pev->spawnflags & SF_SENTENCE_FOLLOWERS )
{
if( pMonster->m_hTargetEnt == 0 || !pMonster->m_hTargetEnt->IsPlayer() )
return FALSE;
}
BOOL override;
if( pev->spawnflags & SF_SENTENCE_INTERRUPT )
override = TRUE;
else
override = FALSE;
if( pMonster->CanPlaySentence( override ) )
return TRUE;
}
BOOL override;
if( pev->spawnflags & SF_SENTENCE_INTERRUPT )
override = TRUE;
else
override = FALSE;
if( pMonster->CanPlaySentence( override ) )
return TRUE;
return pTarget->IsAllowedToSpeak();
}
return FALSE;
}
CBaseMonster *CScriptedSentence :: FindEntity( CBaseEntity *pActivator )
CBaseToggle *CScriptedSentence :: FindEntity( CBaseEntity *pActivator )
{
CBaseEntity *pTarget;
CBaseMonster *pMonster;
CBaseToggle *peTarget;
pTarget = UTIL_FindEntityByTargetname(NULL, STRING(m_iszEntity), pActivator);
pMonster = NULL;
peTarget = NULL;
while ( pTarget )
{
pMonster = pTarget->MyMonsterPointer( );
if( pMonster != NULL )
peTarget = pTarget->MyTogglePointer( );
if( peTarget != NULL )
{
if( AcceptableSpeaker( pMonster ) )
return pMonster;
//ALERT( at_console, "%s (%s), not acceptable\n", STRING( pMonster->pev->classname ), STRING( pMonster->pev->targetname ) );
if( AcceptableSpeaker( peTarget ) )
return peTarget;
//ALERT( at_console, "%s (%s), not acceptable\n", STRING( pTarget->pev->classname ), STRING( pTarget->pev->targetname ) );
}
pTarget = UTIL_FindEntityByTargetname(pTarget, STRING(m_iszEntity), pActivator);
}
@ -1134,9 +1146,9 @@ CBaseMonster *CScriptedSentence :: FindEntity( CBaseEntity *pActivator )
{
if ( FBitSet( pTarget->pev->flags, FL_MONSTER ))
{
pMonster = pTarget->MyMonsterPointer( );
if( AcceptableSpeaker( pMonster ) )
return pMonster;
peTarget = pTarget->MyTogglePointer( );
if( AcceptableSpeaker( peTarget ) )
return peTarget;
}
}
}
@ -1144,7 +1156,7 @@ CBaseMonster *CScriptedSentence :: FindEntity( CBaseEntity *pActivator )
return NULL;
}
BOOL CScriptedSentence::StartSentence( CBaseMonster *pTarget )
BOOL CScriptedSentence::StartSentence( CBaseToggle *pTarget )
{
if( !pTarget )
{

View File

@ -35,6 +35,7 @@ extern int gmsgMOTD;
//=========================================================
CHalfLifeRules::CHalfLifeRules( void )
{
SERVER_COMMAND( "exec spserver.cfg\n" );
RefreshSkillData();
}
@ -94,10 +95,83 @@ BOOL CHalfLifeRules::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem
return TRUE;
}
//=========================================================
//=========================================================
BOOL HLGetNextBestWeapon(CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon )
{
CBasePlayerItem *pCheck;
CBasePlayerItem *pBest;// this will be used in the event that we don't find a weapon in the same category.
int iBestWeight;
int i;
iBestWeight = -1;// no weapon lower than -1 can be autoswitched to
pBest = NULL;
if( !pCurrentWeapon->CanHolster() )
{
// can't put this gun away right now, so can't switch.
return FALSE;
}
for( i = 0; i < MAX_ITEM_TYPES; i++ )
{
pCheck = pPlayer->m_rgpPlayerItems[i];
while( pCheck )
{
if( !FBitSet( pCheck->iFlags(), ITEM_FLAG_NOCHOICE ))
{
if( pCheck->iWeight() > -1 && pCheck->iWeight() == pCurrentWeapon->iWeight() && pCheck != pCurrentWeapon )
{
// this weapon is from the same category.
if ( pCheck->CanDeploy() )
{
if ( pPlayer->SwitchWeapon( pCheck ) )
{
return TRUE;
}
}
}
else if( pCheck->iWeight() > iBestWeight && pCheck != pCurrentWeapon )// don't reselect the weapon we're trying to get rid of
{
//ALERT ( at_console, "Considering %s\n", STRING( pCheck->pev->classname ) );
// we keep updating the 'best' weapon just in case we can't find a weapon of the same weight
// that the player was using. This will end up leaving the player with his heaviest-weighted
// weapon.
if( pCheck->CanDeploy() )
{
// if this weapon is useable, flag it as the best
iBestWeight = pCheck->iWeight();
pBest = pCheck;
}
}
}
pCheck = pCheck->m_pNext;
}
}
// if we make it here, we've checked all the weapons and found no useable
// weapon in the same catagory as the current weapon.
// if pBest is null, we didn't find ANYTHING. Shouldn't be possible- should always
// at least get the crowbar, but ya never know.
if( !pBest )
{
return FALSE;
}
pPlayer->SwitchWeapon( pBest );
return TRUE;
}
//=========================================================
//=========================================================
BOOL CHalfLifeRules::GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon )
{
if( pCurrentWeapon && FBitSet( pCurrentWeapon->iFlags(), ITEM_FLAG_EXHAUSTIBLE ))
return HLGetNextBestWeapon( pPlayer, pCurrentWeapon );
return FALSE;
}

View File

@ -1525,6 +1525,15 @@ void SENTENCEG_Init()
g_engfuncs.pfnFreeFile( pMemFile );
if( gcallsentences > CVOXFILESENTENCEMAX_GOLDSOURCE_ANNIVERSARY_25 )
{
ALERT( at_warning, "NOTE: this mod might not work properly under GoldSource (post-anniversary update) engine: more than %d sentences\n", CVOXFILESENTENCEMAX_GOLDSOURCE_ANNIVERSARY_25 );
}
else if( gcallsentences > CVOXFILESENTENCEMAX_GOLDSOURCE_LEGACY )
{
ALERT( at_warning, "NOTE: this mod might not work properly under GoldSource (pre-anniversary update) engine: more than %d sentences\n", CVOXFILESENTENCEMAX_GOLDSOURCE_LEGACY );
}
fSentencesInit = TRUE;
// init lru lists

View File

@ -342,7 +342,8 @@ void CSqueakGrenade::SuperBounceTouch( CBaseEntity *pOther )
// higher pitch as squeeker gets closer to detonation time
flpitch = 155.0f - 60.0f * ( ( m_flDie - gpGlobals->time ) / SQUEEK_DETONATE_DELAY );
if( pOther->pev->takedamage && m_flNextAttack < gpGlobals->time )
if( !FBitSet( pOther->pev->flags, FL_WORLDBRUSH )
&& pOther->pev->takedamage && m_flNextAttack < gpGlobals->time )
{
// attack!
@ -498,20 +499,35 @@ void CSqueak::PrimaryAttack()
{
if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] )
{
UTIL_MakeVectors( m_pPlayer->pev->v_angle );
TraceResult tr;
Vector trace_origin;
Vector trace_origin, forward;
float flVel;
UTIL_MakeVectors( Vector( 0, m_pPlayer->pev->v_angle.y, m_pPlayer->pev->v_angle.z ));
forward = gpGlobals->v_forward;
UTIL_MakeVectors( m_pPlayer->pev->v_angle );
if( m_pPlayer->pev->v_angle.x <= 0 )
{
flVel = 1;
}
else
{
flVel = m_pPlayer->pev->v_angle.x / 90.0f;
}
// HACK HACK: Ugly hacks to handle change in origin based on new physics code for players
// Move origin up if crouched and start trace a bit outside of body ( 20 units instead of 16 )
trace_origin = m_pPlayer->pev->origin;
if( m_pPlayer->pev->flags & FL_DUCKING )
{
trace_origin = trace_origin - ( VEC_HULL_MIN - VEC_DUCK_HULL_MIN );
trace_origin = trace_origin - Vector( 0, 0, 1 ) * ( flVel + 1.0f ) * -18;
}
forward = forward * flVel + gpGlobals->v_forward * ( 1 - flVel );
// find place to toss monster
UTIL_TraceLine( trace_origin + gpGlobals->v_forward * 20.0f, trace_origin + gpGlobals->v_forward * 64.0f, dont_ignore_monsters, NULL, &tr );
UTIL_TraceLine( trace_origin + forward * 24.0f, trace_origin + gpGlobals->v_forward * 60.0f, dont_ignore_monsters, NULL, &tr );
int flags;
#if CLIENT_WEAPONS
@ -521,13 +537,13 @@ void CSqueak::PrimaryAttack()
#endif
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usSnarkFire, 0.0f, g_vecZero, g_vecZero, 0.0f, 0.0f, 0, 0, 0, 0 );
if( tr.fAllSolid == 0 && tr.fStartSolid == 0 && tr.flFraction > 0.25f )
if( tr.fAllSolid == 0 && tr.fStartSolid == 0 && tr.flFraction > 0 )
{
// player "shoot" animation
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
#if !CLIENT_DLL
CBaseEntity *pSqueak = CBaseEntity::Create( "monster_snark", tr.vecEndPos, m_pPlayer->pev->v_angle, m_pPlayer->edict() );
pSqueak->pev->velocity = gpGlobals->v_forward * 200.0f + m_pPlayer->pev->velocity;
pSqueak->pev->velocity = forward * 200.0f + m_pPlayer->pev->velocity;
#endif
// play hunt sound
float flRndSound = RANDOM_FLOAT( 0.0f, 1.0f );

View File

@ -781,6 +781,27 @@ float CBaseToggle::AxisDelta( int flags, const Vector &angle1, const Vector &ang
return angle1.y - angle2.y;
}
void CBaseToggle::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation )
{
if( pszSentence && IsAllowedToSpeak())
{
if( pszSentence[0] == '!' )
EMIT_SOUND_DYN( edict(), CHAN_VOICE, pszSentence, volume, attenuation, 0, PITCH_NORM );
else
SENTENCEG_PlayRndSz( edict(), pszSentence, volume, attenuation, 0, PITCH_NORM );
}
}
void CBaseToggle::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener )
{
PlaySentence( pszSentence, duration, volume, attenuation );
}
void CBaseToggle::SentenceStop( void )
{
EMIT_SOUND( edict(), CHAN_VOICE, "common/null.wav", 1.0, ATTN_IDLE );
}
/*
=============
FEntIsVisible

View File

@ -850,7 +850,7 @@ CBaseEntity *CTalkMonster::FindNearestFriend( BOOL fPlayer )
// for each friend in this bsp...
while( ( pFriend = UTIL_FindEntityByClassname( pFriend, pszFriend ) ) )
{
if( pFriend == this || !pFriend->IsAlive() )
if( pFriend == this || !pFriend->IsAlive() || pFriend->pev->deadflag != DEAD_NO )
// don't talk to self or dead people
continue;
@ -1404,7 +1404,7 @@ void CTalkMonster::StartFollowing( CBaseEntity *pLeader )
//LRC- redefined, now returns true if following would be physically possible
BOOL CTalkMonster::CanFollow( void )
{
if( m_MonsterState == MONSTERSTATE_SCRIPT )
if( m_MonsterState == MONSTERSTATE_SCRIPT || m_IdealMonsterState == MONSTERSTATE_SCRIPT )
{
if( !m_pCine )
return FALSE;

View File

@ -158,4 +158,89 @@ public:
private:
unsigned short m_usAdjustPitch;
};
class CFuncVehicle: public CBaseEntity
{
public:
virtual void Spawn();
virtual void Precache();
virtual void Restart();
virtual void KeyValue( KeyValueData *pkvd );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
virtual int ObjectCaps() { return ( CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION ) | FCAP_DIRECTIONAL_USE; }
virtual int Classify();
virtual void OverrideReset();
virtual BOOL OnControls( entvars_t *pev );
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual void Blocked( CBaseEntity *pOther );
public:
void EXPORT Next();
void EXPORT Find();
void EXPORT NearestPath();
void EXPORT DeadEnd();
void NextThink( float thinkTime, BOOL alwaysThink );
void CollisionDetection();
void TerrainFollowing();
void CheckTurning();
void SetTrack( CPathTrack *track ) { m_ppath = track->Nearest( pev->origin ); }
void SetControls( entvars_t *pevControls );
void StopSound();
void UpdateSound();
public:
static CFuncVehicle *Instance( edict_t *pent );
static TYPEDESCRIPTION m_SaveData[12];
CPathTrack *m_ppath;
float m_length;
float m_width;
float m_height;
float m_speed;
float m_dir;
float m_startSpeed;
Vector m_controlMins;
Vector m_controlMaxs;
int m_soundPlaying;
int m_sounds;
int m_acceleration;
float m_flVolume;
float m_flBank;
float m_oldSpeed;
int m_iTurnAngle;
float m_flSteeringWheelDecay;
float m_flAcceleratorDecay;
float m_flTurnStartTime;
float m_flLaunchTime;
float m_flLastNormalZ;
float m_flCanTurnNow;
float m_flUpdateSound;
Vector m_vFrontLeft;
Vector m_vFront;
Vector m_vFrontRight;
Vector m_vBackLeft;
Vector m_vBack;
Vector m_vBackRight;
Vector m_vSurfaceNormal;
Vector m_vVehicleDirection;
CBaseEntity *m_pDriver;
private:
unsigned short m_usAdjustPitch;
};
class CFuncVehicleControls: public CBaseEntity
{
public:
virtual void Spawn();
virtual int ObjectCaps() { return CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
public:
void EXPORT Find();
};
#endif

View File

@ -2354,7 +2354,12 @@ void CTriggerHurt :: HurtTouch ( CBaseEntity *pOther )
#endif
if ( fldmg < 0 )
pOther->TakeHealth( -fldmg, m_bitsDamageInflict );
{
if( !( g_pGameRules->IsMultiplayer()
&& pOther->IsPlayer()
&& pOther->pev->deadflag ))
pOther->TakeHealth( -fldmg, m_bitsDamageInflict );
}
else
pOther->TakeDamage( pev, pev, fldmg, m_bitsDamageInflict );

View File

@ -2164,26 +2164,11 @@ void CSaveRestoreBuffer::BufferRewind( int size )
m_pdata->size -= size;
}
#if !_WIN32 && !__WATCOMC__
extern "C" {
unsigned _rotr( unsigned val, int shift )
#if !XASH_WIN32 && !__WATCOMC__
static unsigned _rotr( unsigned val, int shift )
{
unsigned lobit; /* non-zero means lo bit set */
unsigned num = val; /* number to rotate */
shift &= 0x1f; /* modulo 32 -- this will also make
negative shifts work */
while( shift-- )
{
lobit = num & 1; /* get high bit */
num >>= 1; /* shift right one bit */
if( lobit )
num |= 0x80000000; /* set hi bit if lo bit was set */
}
return num;
}
// Any modern compiler will generate one single ror instruction for x86, arm and mips here.
return ( val >> shift ) | ( val << ( 32 - shift ));
}
#endif
@ -2682,7 +2667,7 @@ int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCou
break;
case FIELD_EHANDLE:
// Input and Output sizes are different!
pOutputData = (char *)pOutputData + j * ( sizeof(EHANDLE) - gSizes[pTest->fieldType] );
pInputData = (char*)pData + j * gSizes[pTest->fieldType];
entityIndex = *(int *)pInputData;
pent = EntityFromIndex( entityIndex );
if( pent )

View File

@ -530,7 +530,11 @@ extern DLL_GLOBAL int g_Language;
// sentence groups
#define CBSENTENCENAME_MAX 16
#define CVOXFILESENTENCEMAX 1536 // max number of sentences in game. NOTE: this must match
#define CVOXFILESENTENCEMAX_GOLDSOURCE_LEGACY 1536
#define CVOXFILESENTENCEMAX_GOLDSOURCE_ANNIVERSARY_25 2048
#define CVOXFILESENTENCEMAX_XASH3D 4096
#define CVOXFILESENTENCEMAX CVOXFILESENTENCEMAX_XASH3D // max number of sentences in game. NOTE: this must match
// CVOXFILESENTENCEMAX in engine\sound.h!!!
extern char gszallsentencenames[CVOXFILESENTENCEMAX][CBSENTENCENAME_MAX];

996
dlls/vehicle.cpp Normal file
View File

@ -0,0 +1,996 @@
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "trains.h"
#include "saverestore.h"
#define VEHICLE_SPEED0_ACCELERATION 0.005000000000000000
#define VEHICLE_SPEED1_ACCELERATION 0.002142857142857143
#define VEHICLE_SPEED2_ACCELERATION 0.003333333333333334
#define VEHICLE_SPEED3_ACCELERATION 0.004166666666666667
#define VEHICLE_SPEED4_ACCELERATION 0.004000000000000000
#define VEHICLE_SPEED5_ACCELERATION 0.003800000000000000
#define VEHICLE_SPEED6_ACCELERATION 0.004500000000000000
#define VEHICLE_SPEED7_ACCELERATION 0.004250000000000000
#define VEHICLE_SPEED8_ACCELERATION 0.002666666666666667
#define VEHICLE_SPEED9_ACCELERATION 0.002285714285714286
#define VEHICLE_SPEED10_ACCELERATION 0.001875000000000000
#define VEHICLE_SPEED11_ACCELERATION 0.001444444444444444
#define VEHICLE_SPEED12_ACCELERATION 0.001200000000000000
#define VEHICLE_SPEED13_ACCELERATION 0.000916666666666666
#define VEHICLE_STARTPITCH 60
#define VEHICLE_MAXPITCH 200
#define VEHICLE_MAXSPEED 1500
TYPEDESCRIPTION CFuncVehicle::m_SaveData[] =
{
DEFINE_FIELD( CFuncVehicle, m_ppath, FIELD_CLASSPTR ),
DEFINE_FIELD( CFuncVehicle, m_length, FIELD_FLOAT ),
DEFINE_FIELD( CFuncVehicle, m_height, FIELD_FLOAT ),
DEFINE_FIELD( CFuncVehicle, m_speed, FIELD_FLOAT ),
DEFINE_FIELD( CFuncVehicle, m_dir, FIELD_FLOAT ),
DEFINE_FIELD( CFuncVehicle, m_startSpeed, FIELD_FLOAT ),
DEFINE_FIELD( CFuncVehicle, m_controlMins, FIELD_VECTOR ),
DEFINE_FIELD( CFuncVehicle, m_controlMaxs, FIELD_VECTOR ),
DEFINE_FIELD( CFuncVehicle, m_sounds, FIELD_INTEGER ),
DEFINE_FIELD( CFuncVehicle, m_flVolume, FIELD_FLOAT ),
DEFINE_FIELD( CFuncVehicle, m_flBank, FIELD_FLOAT ),
DEFINE_FIELD( CFuncVehicle, m_oldSpeed, FIELD_FLOAT ),
};
static float Fix2( float angle )
{
while( angle < 0 )
angle += 360;
while( angle > 360 )
angle -= 360;
return angle;
}
static void FixupAngles2( Vector &v )
{
v.x = Fix2( v.x );
v.y = Fix2( v.y );
v.z = Fix2( v.z );
}
IMPLEMENT_SAVERESTORE( CFuncVehicle, CBaseEntity )
LINK_ENTITY_TO_CLASS( func_vehicle, CFuncVehicle )
void CFuncVehicle::KeyValue( KeyValueData *pkvd )
{
if( FStrEq( pkvd->szKeyName, "length" ))
{
m_length = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "width" ))
{
m_width = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "height" ))
{
m_height = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "startspeed" ))
{
m_startSpeed = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "sounds" ))
{
m_sounds = atoi( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "volume" ))
{
m_flVolume = (float)atoi( pkvd->szValue );
m_flVolume *= 0.1f;
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "bank" ))
{
m_flBank = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if( FStrEq( pkvd->szKeyName, "acceleration" ))
{
m_acceleration = atoi( pkvd->szValue );
if( m_acceleration < 1 )
m_acceleration = 1;
else if( m_acceleration > 10 )
m_acceleration = 10;
pkvd->fHandled = TRUE;
}
else
CBaseEntity::KeyValue( pkvd );
}
void CFuncVehicle::NextThink( float thinkTime, BOOL alwaysThink )
{
if( alwaysThink )
pev->flags |= FL_ALWAYSTHINK;
else
pev->flags &= ~FL_ALWAYSTHINK;
pev->nextthink = thinkTime;
}
void CFuncVehicle::Blocked( CBaseEntity *pOther )
{
entvars_t *pevOther = pOther->pev;
if( ( pevOther->flags & FL_ONGROUND ) && VARS( pevOther->groundentity ) == pev )
{
pevOther->velocity = pev->velocity;
return;
}
pevOther->velocity = ( pevOther->origin - pev->origin ).Normalize() * pev->dmg;
pevOther->velocity.z += 300;
pev->velocity = pev->velocity * 0.85f;
ALERT( at_aiconsole, "TRAIN(%s): Blocked by %s (dmg:%.2f)\n", STRING( pev->targetname ), STRING( pOther->pev->classname ), pev->dmg );
UTIL_MakeVectors( pev->angles );
Vector forward, right, vOrigin;
Vector vFrontLeft = ( gpGlobals->v_forward * -1 ) * ( m_length * 0.5f );
Vector vFrontRight = ( gpGlobals->v_right * -1 ) * ( m_width * 0.5f );
Vector vBackLeft = pev->origin + vFrontLeft - vFrontRight;
Vector vBackRight = pev->origin - vFrontLeft + vFrontRight;
float minx = Q_min( vBackLeft.x, vBackRight.x );
float miny = Q_min( vBackLeft.y, vBackRight.y );
float maxx = Q_max( vBackLeft.x, vBackRight.x );
float maxy = Q_max( vBackLeft.y, vBackRight.y );
float minz = pev->origin.z;
float maxz = pev->origin.z + ( 2 * abs( (int)( pev->mins.z - pev->maxs.z )));
if ( pOther->pev->origin.x < minx
|| pOther->pev->origin.x > maxx
|| pOther->pev->origin.y < miny
|| pOther->pev->origin.y > maxy
|| pOther->pev->origin.z < pev->origin.z
|| pOther->pev->origin.z > maxz )
{
pOther->TakeDamage( pev, pev, 150, DMG_CRUSH );
}
}
void CFuncVehicle::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
float delta = value;
if( useType != USE_SET )
{
if( ShouldToggle( useType, pev->speed != 0 ))
{
if( pev->speed == 0 )
{
pev->speed = m_dir * m_speed;
Next();
}
else
{
pev->speed = 0;
pev->velocity = g_vecZero;
pev->avelocity = g_vecZero;
StopSound();
SetThink( NULL );
}
}
return;
}
if( delta < 10 )
{
if( delta < 0 )
{
if( pev->speed > 145 )
{
StopSound();
}
}
float flSpeedRatio = delta;
if( delta > 0 )
{
flSpeedRatio = (float)( pev->speed / m_speed );
if( pev->speed < 0 ) flSpeedRatio = m_acceleration * 0.0005 + flSpeedRatio + VEHICLE_SPEED0_ACCELERATION;
else if( pev->speed < 10 ) flSpeedRatio = m_acceleration * 0.0006 + flSpeedRatio + VEHICLE_SPEED1_ACCELERATION;
else if( pev->speed < 20 ) flSpeedRatio = m_acceleration * 0.0007 + flSpeedRatio + VEHICLE_SPEED2_ACCELERATION;
else if( pev->speed < 30 ) flSpeedRatio = m_acceleration * 0.0007 + flSpeedRatio + VEHICLE_SPEED3_ACCELERATION;
else if( pev->speed < 45 ) flSpeedRatio = m_acceleration * 0.0007 + flSpeedRatio + VEHICLE_SPEED4_ACCELERATION;
else if( pev->speed < 60 ) flSpeedRatio = m_acceleration * 0.0008 + flSpeedRatio + VEHICLE_SPEED5_ACCELERATION;
else if( pev->speed < 80 ) flSpeedRatio = m_acceleration * 0.0008 + flSpeedRatio + VEHICLE_SPEED6_ACCELERATION;
else if( pev->speed < 100 ) flSpeedRatio = m_acceleration * 0.0009 + flSpeedRatio + VEHICLE_SPEED7_ACCELERATION;
else if( pev->speed < 150 ) flSpeedRatio = m_acceleration * 0.0008 + flSpeedRatio + VEHICLE_SPEED8_ACCELERATION;
else if( pev->speed < 225 ) flSpeedRatio = m_acceleration * 0.0007 + flSpeedRatio + VEHICLE_SPEED9_ACCELERATION;
else if( pev->speed < 300 ) flSpeedRatio = m_acceleration * 0.0006 + flSpeedRatio + VEHICLE_SPEED10_ACCELERATION;
else if( pev->speed < 400 ) flSpeedRatio = m_acceleration * 0.0005 + flSpeedRatio + VEHICLE_SPEED11_ACCELERATION;
else if( pev->speed < 550 ) flSpeedRatio = m_acceleration * 0.0005 + flSpeedRatio + VEHICLE_SPEED12_ACCELERATION;
else if( pev->speed < 800 ) flSpeedRatio = m_acceleration * 0.0005 + flSpeedRatio + VEHICLE_SPEED13_ACCELERATION;
}
else if( delta < 0 )
{
flSpeedRatio = pev->speed / m_speed;
// TODO: fix float for test demo
if( flSpeedRatio > 0 ) flSpeedRatio = (float)flSpeedRatio - 0.0125f;
else if( flSpeedRatio <= 0 && flSpeedRatio > -0.05f ) flSpeedRatio = (float)flSpeedRatio - 0.0075f;
else if( flSpeedRatio <= 0.05f && flSpeedRatio > -0.1f ) flSpeedRatio = (float)flSpeedRatio - 0.01f;
else if( flSpeedRatio <= 0.15f && flSpeedRatio > -0.15f ) flSpeedRatio = (float)flSpeedRatio - 0.0125f;
else if( flSpeedRatio <= 0.15f && flSpeedRatio > -0.22f ) flSpeedRatio = (float)flSpeedRatio - 0.01375f;
else if( flSpeedRatio <= 0.22f && flSpeedRatio > -0.3f ) flSpeedRatio = (float)flSpeedRatio - 0.0175f;
else if( flSpeedRatio <= 0.3f ) flSpeedRatio = (float)flSpeedRatio - 0.0125f;
}
if( flSpeedRatio > 1 )
{
flSpeedRatio = 1;
}
else if( flSpeedRatio < -0.35f )
{
flSpeedRatio = -0.35f;
}
pev->speed = flSpeedRatio * m_speed;
Next();
m_flAcceleratorDecay = gpGlobals->time + 0.25f;
}
else if( m_flCanTurnNow < gpGlobals->time )
{
if( delta == 20 )
{
m_iTurnAngle++;
m_flSteeringWheelDecay = gpGlobals->time + 0.075f;
if (m_iTurnAngle > 8)
{
m_iTurnAngle = 8;
}
}
else if( delta == 30 )
{
m_iTurnAngle--;
m_flSteeringWheelDecay = gpGlobals->time + 0.075f;
if( m_iTurnAngle < -8 )
{
m_iTurnAngle = -8;
}
}
m_flCanTurnNow = gpGlobals->time + 0.05f;
}
}
void CFuncVehicle::StopSound()
{
if( m_soundPlaying && pev->noise )
{
unsigned short us_sound = ( (unsigned short)m_sounds & 0x0007 ) << 12;
unsigned short us_encode = us_sound;
PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0, g_vecZero, g_vecZero, 0, 0, us_encode, 0, 1, 0 );
}
m_soundPlaying = 0;
}
void CFuncVehicle::UpdateSound()
{
if( !pev->noise )
return;
float flpitch = VEHICLE_STARTPITCH + ( abs( (int)pev->speed ) * ( VEHICLE_MAXPITCH - VEHICLE_STARTPITCH ) / VEHICLE_MAXSPEED );
if( flpitch > 200 )
flpitch = 200;
if( !m_soundPlaying )
{
if( m_sounds < 5 )
{
EMIT_SOUND_DYN( ENT(pev), CHAN_ITEM, "plats/vehicle_brake1.wav", m_flVolume, ATTN_NORM, 0, PITCH_NORM );
}
EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, STRING( pev->noise ), m_flVolume, ATTN_NORM, 0, (int)flpitch );
m_soundPlaying = 1;
}
else
{
unsigned short us_sound = ( (unsigned short)( m_sounds ) & 0x0007 ) << 12;
unsigned short us_pitch = ( (unsigned short)( flpitch / 10.0 ) & 0x003F ) << 6;
unsigned short us_volume = ( (unsigned short)( m_flVolume * 40 ) & 0x003F );
unsigned short us_encode = us_sound | us_pitch | us_volume;
PLAYBACK_EVENT_FULL( FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, g_vecZero, g_vecZero, 0.0, 0.0, us_encode, 0, 0, 0 );
}
}
void CFuncVehicle::CheckTurning()
{
float maxspeed;
TraceResult tr;
bool bTurnIntoWall = false;
if( m_iTurnAngle < 0 )
{
if( pev->speed > 0 )
{
UTIL_TraceLine( m_vFrontRight, m_vFrontRight - ( gpGlobals->v_right * 16.0f ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
}
else if( pev->speed < 0 )
{
UTIL_TraceLine( m_vBackLeft, m_vBackLeft + ( gpGlobals->v_right * 16.0f ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
}
if( tr.flFraction != 1.0f )
{
m_iTurnAngle = 1;
}
}
else if( m_iTurnAngle > 0 )
{
if( pev->speed > 0 )
{
UTIL_TraceLine( m_vFrontLeft, m_vFrontLeft + ( gpGlobals->v_right * 16.0f ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
}
else if( pev->speed < 0 )
{
UTIL_TraceLine( m_vBackRight, m_vBackRight - ( gpGlobals->v_right * 16.0f ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
}
if( tr.flFraction != 1.0f )
{
m_iTurnAngle = -1;
}
}
if( pev->speed > 0 )
{
int iCountTurn = abs( m_iTurnAngle );
if( iCountTurn > 4 )
{
if ( m_flTurnStartTime != -1 )
{
float flTurnTime = gpGlobals->time - m_flTurnStartTime;
if( flTurnTime >= 0 ) maxspeed = m_speed * 0.98f;
else if( flTurnTime > 0.3f ) maxspeed = m_speed * 0.95f;
else if( flTurnTime > 0.6f ) maxspeed = m_speed * 0.9f;
else if( flTurnTime > 0.8f ) maxspeed = m_speed * 0.8f;
else if( flTurnTime > 1 ) maxspeed = m_speed * 0.7f;
else if( flTurnTime > 1.2f ) maxspeed = m_speed * 0.5f;
else maxspeed = flTurnTime;
}
else
{
m_flTurnStartTime = gpGlobals->time;
maxspeed = m_speed;
}
}
else
{
m_flTurnStartTime = -1;
if( iCountTurn > 2 )
maxspeed = m_speed * 0.9f;
else
maxspeed = m_speed;
}
if( maxspeed < pev->speed )
{
pev->speed -= m_speed * 0.1f;
}
}
}
void CFuncVehicle::CollisionDetection()
{
TraceResult tr;
bool bHitSomething = false;
if( pev->speed < 0 )
{
UTIL_TraceLine( m_vBackLeft, m_vBackLeft + ( gpGlobals->v_forward * 16.0f ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
if( tr.flFraction == 1.0f )
{
UTIL_TraceLine( m_vBackRight, m_vBackRight + ( gpGlobals->v_forward * 16.0f ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
if( tr.flFraction == 1.0f )
{
UTIL_TraceLine( m_vBack, m_vBack + ( gpGlobals->v_forward * 16.0f ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
if( tr.flFraction == 1.0f )
{
return;
}
}
if( DotProduct( gpGlobals->v_forward, tr.vecPlaneNormal * -1.0f ) < 0.7f && tr.vecPlaneNormal.z < 0.1f )
{
m_vSurfaceNormal = tr.vecPlaneNormal;
m_vSurfaceNormal.z = 0;
pev->speed *= 0.99f;
}
else if( tr.vecPlaneNormal.z < 0.65f || tr.fStartSolid )
{
pev->speed *= -1.0f;
}
else
{
m_vSurfaceNormal = tr.vecPlaneNormal;
}
}
else
{
if( DotProduct( gpGlobals->v_forward, tr.vecPlaneNormal * -1.0f ) < 0.7f && tr.vecPlaneNormal.z < 0.1f )
{
m_vSurfaceNormal = tr.vecPlaneNormal;
m_vSurfaceNormal.z = 0;
pev->speed *= 0.99f;
}
else if( tr.vecPlaneNormal[2] < 0.65f || tr.fStartSolid )
{
pev->speed *= -1.0f;
}
else
{
m_vSurfaceNormal = tr.vecPlaneNormal;
}
CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit );
if( pHit && pHit->Classify() == CLASS_VEHICLE )
{
bHitSomething = true;
ALERT( at_console, "I hit another vehicle\n" );
}
}
}
else if( pev->speed > 0 )
{
UTIL_TraceLine( m_vFrontLeft, m_vFrontLeft - ( gpGlobals->v_forward * 16.0f ), dont_ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
if( tr.flFraction == 1.0f )
{
UTIL_TraceLine( m_vFrontRight, m_vFrontRight - ( gpGlobals->v_forward * 16.0f ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
if( tr.flFraction == 1.0f )
{
UTIL_TraceLine( m_vFront, m_vFront - ( gpGlobals->v_forward * 16.0f ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
if( tr.flFraction == 1.0f )
{
return;
}
}
}
if( DotProduct( gpGlobals->v_forward, tr.vecPlaneNormal * -1.0f ) > -0.7f && tr.vecPlaneNormal.z < 0.1f )
{
m_vSurfaceNormal = tr.vecPlaneNormal;
m_vSurfaceNormal.z = 0;
pev->speed *= 0.99f;
}
else if( tr.vecPlaneNormal.z < 0.65f || tr.fStartSolid )
{
pev->speed *= -1.0f;
}
else
{
m_vSurfaceNormal = tr.vecPlaneNormal;
}
}
}
void CFuncVehicle::TerrainFollowing()
{
TraceResult tr;
UTIL_TraceLine( pev->origin, pev->origin + Vector( 0, 0, ( m_height + 48 ) * -1 ), ignore_monsters, dont_ignore_glass, ENT( pev ), &tr );
if( tr.flFraction != 1.0f )
{
m_vSurfaceNormal = tr.vecPlaneNormal;
}
else if( tr.fInWater )
{
m_vSurfaceNormal = Vector( 0, 0, 1 );
}
}
void CFuncVehicle::Next()
{
Vector vGravityVector, forward, right, up;
float time = 0.1f;
vGravityVector = g_vecZero;
UTIL_MakeVectors( pev->angles );
forward = ( gpGlobals->v_forward * -1 ) * ( m_length * 0.5f );
right = ( gpGlobals->v_right * -1 ) * ( m_width * 0.5f );
up = gpGlobals->v_up * 16;
m_vFrontLeft = pev->origin + forward - right + up;
m_vFrontRight = pev->origin + forward + right + up;
m_vFront = pev->origin + forward + up;
m_vBackLeft = pev->origin - forward - right + up;
m_vBackRight = pev->origin - forward + right + up;
m_vBack = pev->origin - forward + up;
m_vSurfaceNormal = g_vecZero;
CheckTurning();
if( m_flSteeringWheelDecay < gpGlobals->time )
{
m_flSteeringWheelDecay = gpGlobals->time + 0.1f;
if( m_iTurnAngle < 0 )
m_iTurnAngle++;
else if( m_iTurnAngle > 0 )
m_iTurnAngle--;
}
if( m_flAcceleratorDecay < gpGlobals->time )
{
m_flAcceleratorDecay = gpGlobals->time + 0.1f;
if( pev->speed < 0 )
{
pev->speed += 20;
if( pev->speed > 0 )
pev->speed = 0;
}
else if( pev->speed > 0 )
{
pev->speed -= 20;
if( pev->speed < 0 )
pev->speed = 0;
}
}
if( pev->speed == 0 )
{
m_iTurnAngle = 0;
pev->avelocity = g_vecZero;
pev->velocity = g_vecZero;
SetThink( &CFuncVehicle::Next );
NextThink( pev->ltime + time, TRUE );
return;
}
TerrainFollowing();
CollisionDetection();
Vector temp;
if( m_vSurfaceNormal != g_vecZero )
{
Vector vTargetAngle, vAngle;
float vx;
float vy;
m_vVehicleDirection = CrossProduct( m_vSurfaceNormal, gpGlobals->v_forward );
m_vVehicleDirection = CrossProduct( m_vSurfaceNormal, m_vVehicleDirection );
vTargetAngle = UTIL_VecToAngles( m_vVehicleDirection );
vAngle = pev->angles;
vTargetAngle.y += 180;
if( m_iTurnAngle != 0 )
{
vTargetAngle.y += m_iTurnAngle;
}
FixupAngles2( vTargetAngle );
FixupAngles2( vAngle );
vx = UTIL_AngleDistance( vTargetAngle.x, vAngle.x );
vy = UTIL_AngleDistance( vTargetAngle.y, vAngle.y );
if( vx > 10 )
vx = 10;
else if( vx < -10 )
vx = -10;
if( vy > 10 )
vy = 10;
else if( vy < -10 )
vy = -10;
pev->avelocity.y = (int)( vy * 10 );
pev->avelocity.x = (int)( vx * 10 );
m_flLaunchTime = -1;
m_flLastNormalZ = m_vSurfaceNormal.z;
}
else
{
if( m_flLaunchTime != -1 )
{
vGravityVector.x = 0;
vGravityVector.y = 0;
vGravityVector.z = ( gpGlobals->time - m_flLaunchTime ) * -35;
if( vGravityVector.z < -400 )
{
vGravityVector.z = -400;
}
}
else
{
m_flLaunchTime = gpGlobals->time;
vGravityVector = Vector( 0, 0, 0 );
pev->velocity = pev->velocity * 1.5f;
}
m_vVehicleDirection = gpGlobals->v_forward * -1;
}
UTIL_VecToAngles( m_vVehicleDirection );
if( m_flUpdateSound < gpGlobals->time )
{
UpdateSound();
m_flUpdateSound = gpGlobals->time + 1.0f;
}
if( m_vSurfaceNormal != g_vecZero )
{
pev->velocity = m_vVehicleDirection.Normalize() * pev->speed;
}
else
{
pev->velocity = pev->velocity + vGravityVector;
}
SetThink( &CFuncVehicle::Next );
NextThink( pev->ltime + time, TRUE );
}
void CFuncVehicle::DeadEnd()
{
CPathTrack *pTrack = m_ppath;
ALERT( at_aiconsole, "TRAIN(%s): Dead end ", STRING( pev->targetname ));
if( pTrack != NULL )
{
CPathTrack *pNext;
if( m_oldSpeed < 0 )
{
do
{
pNext = pTrack->ValidPath( pTrack->GetPrevious(), TRUE );
if( pNext != NULL )
{
pTrack = pNext;
}
}
while( pNext != NULL );
}
else
{
do
{
pNext = pTrack->ValidPath( pTrack->GetNext(), TRUE );
if( pNext != NULL )
{
pTrack = pNext;
}
}
while( pNext != NULL );
}
}
pev->velocity = g_vecZero;
pev->avelocity = g_vecZero;
if( pTrack != NULL )
{
ALERT( at_aiconsole, "at %s\n", STRING( pTrack->pev->targetname ));
if( !FStringNull( pTrack->pev->netname ))
{
FireTargets( STRING( pTrack->pev->netname ), this, this, USE_TOGGLE, 0 );
}
}
else
ALERT( at_aiconsole, "\n" );
}
void CFuncVehicle::SetControls(entvars_t *pevControls)
{
Vector offset = pevControls->origin - pev->oldorigin;
m_controlMins = pevControls->mins + offset;
m_controlMaxs = pevControls->maxs + offset;
}
BOOL CFuncVehicle::OnControls(entvars_t *pevTest)
{
if( pev->spawnflags & SF_TRACKTRAIN_NOCONTROL )
return FALSE;
Vector offset = pevTest->origin - pev->origin;
UTIL_MakeVectors( pev->angles );
Vector local;
local.x = DotProduct( offset, gpGlobals->v_forward );
local.y = -DotProduct( offset, gpGlobals->v_right );
local.z = DotProduct( offset, gpGlobals->v_up );
return ( local.x >= m_controlMins.x && local.y >= m_controlMins.y && local.z >= m_controlMins.z
&& local.x <= m_controlMaxs.x && local.y <= m_controlMaxs.y && local.z <= m_controlMaxs.z );
}
void CFuncVehicle::Find()
{
m_ppath = CPathTrack::Instance( FIND_ENTITY_BY_TARGETNAME( NULL, STRING( pev->target )));
if( !m_ppath )
return;
entvars_t *pevTarget = m_ppath->pev;
if( !FClassnameIs( pevTarget, "path_track" ))
{
ALERT( at_error, "func_track_train must be on a path of path_track\n" );
m_ppath = NULL;
return;
}
Vector nextPos = pevTarget->origin;
nextPos.z += m_height;
Vector look = nextPos;
look.z -= m_height;
m_ppath->LookAhead( &look, m_length, 0 );
look.z += m_height;
pev->angles = UTIL_VecToAngles( look - nextPos );
pev->angles.y += 180;
if( pev->spawnflags & SF_TRACKTRAIN_NOPITCH )
{
pev->angles.x = 0;
}
UTIL_SetOrigin( this, nextPos );
NextThink( pev->ltime + 0.1f, FALSE );
SetThink( &CFuncVehicle::Next );
pev->speed = m_startSpeed;
UpdateSound();
}
void CFuncVehicle::NearestPath()
{
CBaseEntity *pTrack = NULL;
CBaseEntity *pNearest = NULL;
float dist;
float closest = 1024;
while( ( pTrack = UTIL_FindEntityInSphere( pTrack, pev->origin, 1024 )) != NULL )
{
if( !( pTrack->pev->flags & ( FL_CLIENT | FL_MONSTER )) && FClassnameIs( pTrack->pev, "path_track" ))
{
dist = ( pev->origin - pTrack->pev->origin ).Length();
if( dist < closest )
{
closest = dist;
pNearest = pTrack;
}
}
}
if( !pNearest )
{
ALERT( at_console, "Can't find a nearby track !!!\n" );
SetThink( NULL );
return;
}
ALERT( at_aiconsole, "TRAIN: %s, Nearest track is %s\n", STRING( pev->targetname ), STRING( pNearest->pev->targetname ));
pTrack = ( (CPathTrack *)pNearest )->GetNext();
if( pTrack != NULL )
{
if( ( pev->origin - pTrack->pev->origin ).Length() < ( pev->origin - pNearest->pev->origin ).Length())
{
pNearest = pTrack;
}
}
m_ppath = (CPathTrack *)pNearest;
if( pev->speed != 0 )
{
NextThink( pev->ltime + 0.1f, FALSE );
SetThink( &CFuncVehicle::Next );
}
}
void CFuncVehicle::OverrideReset()
{
NextThink( pev->ltime + 0.1f, FALSE );
SetThink( &CFuncVehicle::NearestPath );
}
CFuncVehicle *CFuncVehicle::Instance(edict_t *pent)
{
if( FClassnameIs( pent, "func_vehicle" ))
{
return (CFuncVehicle *)GET_PRIVATE( pent );
}
return NULL;
}
int CFuncVehicle::Classify()
{
return CLASS_VEHICLE;
}
void CFuncVehicle::Spawn()
{
if( pev->speed == 0 )
m_speed = 165;
else
m_speed = pev->speed;
if( !m_sounds )
m_sounds = 3;
ALERT( at_console, "M_speed = %f\n", m_speed );
pev->speed = 0;
pev->velocity = g_vecZero;
pev->avelocity = g_vecZero;
pev->impulse = (int)m_speed;
m_acceleration = 5;
m_dir = 1;
m_flTurnStartTime = -1;
if( FStringNull( pev->target ))
{
ALERT( at_console, "Vehicle with no target" );
}
if( pev->spawnflags & SF_TRACKTRAIN_PASSABLE )
pev->solid = SOLID_NOT;
else
pev->solid = SOLID_BSP;
pev->movetype = MOVETYPE_PUSH;
SET_MODEL( ENT( pev ), STRING(pev->model ));
UTIL_SetSize( pev, pev->mins, pev->maxs );
UTIL_SetOrigin( this, pev->origin );
pev->oldorigin = pev->origin;
m_controlMins = pev->mins;
m_controlMaxs = pev->maxs;
m_controlMaxs.z += 72;
NextThink( pev->ltime + 0.1f, FALSE );
SetThink( &CFuncVehicle::Find );
Precache();
}
void CFuncVehicle::Restart()
{
ALERT( at_console, "M_speed = %f\n", m_speed );
pev->speed = 0;
pev->velocity = g_vecZero;
pev->avelocity = g_vecZero;
pev->impulse = (int)m_speed;
m_flTurnStartTime = -1;
m_flUpdateSound = -1;
m_dir = 1;
m_pDriver = NULL;
if( FStringNull( pev->target ))
{
ALERT( at_console, "Vehicle with no target" );
}
UTIL_SetOrigin( this, pev->oldorigin );
STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noise ));
NextThink( pev->ltime + 0.1f, FALSE );
SetThink( &CFuncVehicle::Find );
}
void CFuncVehicle::Precache()
{
if( m_flVolume == 0.0f )
m_flVolume = 1.0f;
switch( m_sounds )
{
case 1: PRECACHE_SOUND( "plats/vehicle1.wav" );pev->noise = MAKE_STRING( "plats/vehicle1.wav" ); break;
case 2: PRECACHE_SOUND( "plats/vehicle2.wav" );pev->noise = MAKE_STRING( "plats/vehicle2.wav" ); break;
case 3: PRECACHE_SOUND( "plats/vehicle3.wav" );pev->noise = MAKE_STRING( "plats/vehicle3.wav" ); break;
case 4: PRECACHE_SOUND( "plats/vehicle4.wav" );pev->noise = MAKE_STRING( "plats/vehicle4.wav" ); break;
case 5: PRECACHE_SOUND( "plats/vehicle6.wav" );pev->noise = MAKE_STRING( "plats/vehicle6.wav" ); break;
case 6: PRECACHE_SOUND( "plats/vehicle7.wav" );pev->noise = MAKE_STRING( "plats/vehicle7.wav" ); break;
}
PRECACHE_SOUND( "plats/vehicle_brake1.wav" );
PRECACHE_SOUND( "plats/vehicle_start1.wav" );
m_usAdjustPitch = PRECACHE_EVENT( 1, "events/vehicle.sc" );
}
LINK_ENTITY_TO_CLASS( func_vehiclecontrols, CFuncVehicleControls );
void CFuncVehicleControls::Find()
{
edict_t *pTarget = NULL;
do
{
pTarget = FIND_ENTITY_BY_TARGETNAME( pTarget, STRING( pev->target ));
}
while( !FNullEnt( pTarget ) && !FClassnameIs( pTarget, "func_vehicle" ));
if( FNullEnt( pTarget ))
{
ALERT( at_console, "No vehicle %s\n", STRING( pev->target ));
return;
}
CFuncVehicle *pvehicle = CFuncVehicle::Instance( pTarget );
pvehicle->SetControls( pev );
UTIL_Remove( this );
}
void CFuncVehicleControls::Spawn()
{
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
SET_MODEL( ENT( pev ), STRING( pev->model ));
UTIL_SetSize( pev, pev->mins, pev->maxs );
UTIL_SetOrigin( this, pev->origin );
SetThink( &CFuncVehicleControls::Find );
pev->nextthink = gpGlobals->time;
}

View File

@ -469,6 +469,19 @@ void CBasePlayerItem::FallThink( void )
Materialize();
}
else if( m_pPlayer )
{
SetThink( NULL );
}
if( g_pGameRules->IsBustingGame())
{
if( !FNullEnt( pev->owner ))
return;
if( FClassnameIs( pev, "weapon_egon" ))
UTIL_Remove( this );
}
}
//=========================================================
@ -1082,7 +1095,7 @@ void CBasePlayerAmmo::Materialize( void )
void CBasePlayerAmmo::DefaultTouch( CBaseEntity *pOther )
{
if( !pOther->IsPlayer() )
if( !pOther->IsPlayer() || IsPlayerBusting( pOther ))
{
return;
}

View File

@ -37,7 +37,7 @@ public:
static void UseSatchelCharges( entvars_t *pevOwner, SATCHELCODE code );
void Explode( Vector vecSrc, Vector vecAim );
void Explode( TraceResult *pTrace, int bitsDamageType );
virtual void Explode( TraceResult *pTrace, int bitsDamageType );
void EXPORT Smoke( void );
void EXPORT BounceTouch( CBaseEntity *pOther );
@ -95,7 +95,7 @@ public:
#define RPG_WEIGHT 20
#define GAUSS_WEIGHT 20
#define EGON_WEIGHT 20
#define HORNETGUN_WEIGHT 10
#define HORNETGUN_WEIGHT 15
#define HANDGRENADE_WEIGHT 5
#define SNARK_WEIGHT 5
#define SATCHEL_WEIGHT -10
@ -137,6 +137,7 @@ public:
#define GLOCK_DEFAULT_GIVE 17
#define PYTHON_DEFAULT_GIVE 6
#define MP5_DEFAULT_GIVE 25
#define MP5_DEFAULT_GIVE_MP MP5_MAX_CLIP
#define MP5_M203_DEFAULT_GIVE 0
#define SHOTGUN_DEFAULT_GIVE 12
#define CROSSBOW_DEFAULT_GIVE 5
@ -182,6 +183,7 @@ typedef enum
#define ITEM_FLAG_NOAUTOSWITCHEMPTY 4
#define ITEM_FLAG_LIMITINWORLD 8
#define ITEM_FLAG_EXHAUSTIBLE 16 // A player can totally exhaust their ammo supply and lose this weapon
#define ITEM_FLAG_NOCHOICE 32
#define WEAPON_IS_ONTARGET 0x40
@ -728,6 +730,8 @@ public:
void EXPORT IgniteThink( void );
void EXPORT RocketTouch( CBaseEntity *pOther );
static CRpgRocket *CreateRpgRocket( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CRpg *pLauncher );
void Explode( TraceResult *pTrace, int bitsDamageType );
inline CRpg *GetLauncher( void );
int m_iTrail;
float m_flIgniteTime;
@ -796,13 +800,13 @@ public:
int AddToPlayer( CBasePlayer *pPlayer );
BOOL Deploy( void );
BOOL CanHolster( void );
void Holster( int skiplocal = 0 );
void UpdateEffect( const Vector &startPoint, const Vector &endPoint, float timeBlend );
void CreateEffect ( void );
void DestroyEffect ( void );
void EndAttack( void );
void Attack( void );
void PrimaryAttack( void );

View File

@ -227,7 +227,7 @@ static void InitBodyQue( void )
//
void CopyToBodyQue( entvars_t *pev )
{
if( pev->effects & EF_NODRAW )
if( ( pev->effects & EF_NODRAW ) || !pev->modelindex )
return;
entvars_t *pevHead = VARS( g_pBodyQueueHead );

View File

@ -6,7 +6,6 @@ from waflib import Utils
import os
def options(opt):
# stub
return
def configure(conf):
@ -16,119 +15,21 @@ def configure(conf):
hlDefNode = conf.path.find_resource("./hl.def")
if hlDefNode is not None:
conf.env.append_unique('LINKFLAGS', '/def:%s' % hlDefNode.abspath())
conf.env.append_value('LINKFLAGS', '/def:%s' % hlDefNode.abspath())
else:
conf.fatal("Could not find hl.def")
def build(bld):
source = bld.path.parent.ant_glob([
'pm_shared/*.c',
])
excluded_files = ['mpstubb.cpp', 'stats.cpp', 'Wxdebug.cpp']
source += [
'agrunt.cpp',
'airtank.cpp',
'aflock.cpp',
'alias.cpp',
'animating.cpp',
'animation.cpp',
'apache.cpp',
'barnacle.cpp',
'barney.cpp',
'bigmomma.cpp',
'bloater.cpp',
'bmodels.cpp',
'bullsquid.cpp',
'buttons.cpp',
'cbase.cpp',
'client.cpp',
'combat.cpp',
'controller.cpp',
'crossbow.cpp',
'crowbar.cpp',
'defaultai.cpp',
'doors.cpp',
'effects.cpp',
'egon.cpp',
'explode.cpp',
'flyingmonster.cpp',
'func_break.cpp',
'func_tank.cpp',
'game.cpp',
'gamerules.cpp',
'gargantua.cpp',
'gauss.cpp',
'genericmonster.cpp',
'ggrenade.cpp',
'globals.cpp',
'glock.cpp',
'gman.cpp',
'h_ai.cpp',
'h_battery.cpp',
'h_cine.cpp',
'h_cycler.cpp',
'h_export.cpp',
'handgrenade.cpp',
'hassassin.cpp',
'headcrab.cpp',
'healthkit.cpp',
'hgrunt.cpp',
'hornet.cpp',
'hornetgun.cpp',
'houndeye.cpp',
'ichthyosaur.cpp',
'islave_deamon.cpp',
'items.cpp',
'leech.cpp',
'lights.cpp',
'locus.cpp',
'maprules.cpp',
'monstermaker.cpp',
'monsters.cpp',
'monsterstate.cpp',
'mortar.cpp',
'movewith.cpp',
'mp5.cpp',
'multiplay_gamerules.cpp',
'nihilanth.cpp',
'nodes.cpp',
'observer.cpp',
'osprey.cpp',
'pathcorner.cpp',
'plane.cpp',
'plats.cpp',
'player.cpp',
'playermonster.cpp',
'python.cpp',
'rat.cpp',
'roach.cpp',
'rpg.cpp',
'satchel.cpp',
'schedule.cpp',
'scientist.cpp',
'scripted.cpp',
'shotgun.cpp',
'singleplay_gamerules.cpp',
'skill.cpp',
'sound.cpp',
'soundent.cpp',
'spectator.cpp',
'squadmonster.cpp',
'squeakgrenade.cpp',
'subs.cpp',
'talkmonster.cpp',
'teamplay_gamerules.cpp',
'tempmonster.cpp',
'tentacle.cpp',
'triggers.cpp',
'tripmine.cpp',
'turret.cpp',
'util.cpp',
'weapons.cpp',
'world.cpp',
'xen.cpp',
'zombie.cpp'
]
source = bld.path.ant_glob('**/*.cpp', excl=excluded_files)
source += bld.path.parent.ant_glob('pm_shared/*.c')
defines = []
if bld.env.USE_VOICEMGR:
source += bld.path.parent.ant_glob('game_shared/voice_gamemgr.cpp')
else:
defines += ['NO_VOICEGAMEMGR']
includes = [
'.',
@ -139,32 +40,20 @@ def build(bld):
'../public'
]
defines = []
if bld.env.VOICEMGR:
source += bld.path.parent.ant_glob([
'game_shared/voice_gamemgr.cpp',
])
else:
defines += ['NO_VOICEGAMEMGR']
libs = []
if bld.env.DEST_OS not in ['android', 'dos']:
install_path = os.path.join(bld.env.GAMEDIR, bld.env.SERVER_DIR)
install_path = os.path.join(bld.env.GAMEDIR, bld.env.SERVER_INSTALL_DIR)
else:
install_path = bld.env.PREFIX
bld.shlib(
source = source,
target = bld.env.SERVER_NAME + bld.env.POSTFIX,
target = bld.env.SERVER_LIBRARY_NAME + bld.env.POSTFIX,
name = 'server',
features = 'c cxx',
includes = includes,
defines = defines,
use = libs,
install_path = install_path,
subsystem = bld.env.MSVC_SUBSYSTEM,
idx = bld.get_taskgen_count()
idx = bld.get_taskgen_count()
)

View File

@ -28,11 +28,14 @@ SPRITE MODELS
#define IDSPRITEHEADER (('P'<<24)+('S'<<16)+('D'<<8)+'I') // little-endian "IDSP"
#define SPRITE_VERSION 2 // Half-Life sprites
#if !defined(SYNCTYPE_T)
#define SYNCTYPE_T
typedef enum
{
ST_SYNC = 0,
ST_RAND
} synctype_t;
#endif
typedef enum
{

View File

@ -1,4 +1,4 @@
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//

View File

@ -1,4 +1,4 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//

View File

@ -1,4 +1,4 @@
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//

View File

@ -1,4 +1,4 @@
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//

View File

@ -1,4 +1,4 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//

View File

@ -1,4 +1,4 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//

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