diff --git a/.gitignore b/.gitignore
index a0bc5604..a5ff9b35 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-# Binaries
+.vscode/
*.o
*.so
*/*.o
@@ -17,3 +17,4 @@ cmake_install.cmake
*.vsxproj
*.vsproj
*.sln
+*.cmd
\ No newline at end of file
diff --git a/android/.gitignore b/android/.gitignore
new file mode 100644
index 00000000..64bd4fc1
--- /dev/null
+++ b/android/.gitignore
@@ -0,0 +1,31 @@
+# Built application files
+*.apk
+*.ap_
+
+# Files for the Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+
+# Gradle files
+.gradle/
+build/
+/*/build/
+
+# Native files
+obj/
+libs/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
new file mode 100644
index 00000000..3005a92f
--- /dev/null
+++ b/android/AndroidManifest.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/HOWTO.txt b/android/HOWTO.txt
new file mode 100644
index 00000000..c21aed4d
--- /dev/null
+++ b/android/HOWTO.txt
@@ -0,0 +1,24 @@
+### Android/Java part
+ * AndroidManifest.xml:
+ * * Rename manifest package
+ * * Change appliction label
+ * * Uncomment icon and InstallReceiver if used
+ * src/in/celest/xash3d/LauncherActivity.java
+ * * Set mod gamedir
+ * * Set mod and launch button title
+ * * Set library loading options
+ * * Enable extras.pak extracting
+ * * Pass envieoment variables
+ * src/in/celest/xash3d/ExtractAssets.java
+ * * Add extra files to unpack
+
+### Native part
+ * Place folders with your mod project to jni/
+
+ * You may provide extras.pak for additional files
+ * You may use client from other package for server mods (read comments in LauncherActivity)
+ * You may use original server libraries for bots by loading it directly from native part
+ * Use getenv("XASH3D_GAMELIBDIR") and getenv("XASH3D_ENGLIBDIR") to get mod and half-life libraries path
+ * You may add options and pass it as enviroment variables (read comments in LauncherActivity)
+ * Place icon to res/drawable/ic_launcher.png and uncomment lines in AndroidManifest
+
\ No newline at end of file
diff --git a/android/build-manual.sh b/android/build-manual.sh
new file mode 100644
index 00000000..2c05b65a
--- /dev/null
+++ b/android/build-manual.sh
@@ -0,0 +1,13 @@
+ANDROID_JAR=../android-13.jar
+AAPT=./../aapt
+DX=./../dx
+APKBUILDER=./../apkbuilder
+NAME=mod
+mkdir bin
+mkdir bin/classes
+$AAPT package -M AndroidManifest.xml -m -S res -I $ANDROID_JAR
+$JAVA_HOME/bin/javac -d bin/classes -s bin/classes -cp $ANDROID_JAR src/in/celest/xash3d/LauncherActivity.java
+$DX --dex --output=bin/classes.dex bin/classes/
+/mnt/app/apktool/aapt package -f -M AndroidManifest.xml -S res -I $ANDROID_JAR -F bin/$NAME.apk.unaligned
+$APKBUILDER bin/$NAME.apk -u -nf libs/ -rj libs -f bin/classes.dex -z bin/$NAME.apk.unaligned
+java -jar /mnt/app/apktool/signapk.jar /mnt/app/apktool/testkey.x509.pem /mnt/app/apktool/testkey.pk8 bin/$NAME.apk bin/$NAME-signed.apk
diff --git a/android/build.sh b/android/build.sh
new file mode 100644
index 00000000..28b24e57
--- /dev/null
+++ b/android/build.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+ndk-build NDK_TOOLCHAIN_VERSION=4.8 NDK_DEBUG=1 V=1 -j5 APP_CFLAGS="-w"
+ant debug
+#jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ../myks.keystore bin/mod-unsigned.apk xashdroid -tsa https://timestamp.geotrust.com/tsa
+#zipalign 4 bin/cs16-client-unsigned.apk bin/mod.apk
diff --git a/android/build.xml b/android/build.xml
new file mode 100644
index 00000000..88f6fb88
--- /dev/null
+++ b/android/build.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
new file mode 100644
index 00000000..0b5a0be9
--- /dev/null
+++ b/android/jni/Android.mk
@@ -0,0 +1,6 @@
+override TARGET_arm_release_CFLAGS :=
+override TARGET_thumb_release_CFLAGS :=
+override TARGET_arm_debug_CFLAGS :=
+override TARGET_thumb_debug_CFLAGS :=
+override TARGET_CFLAGS :=
+include $(call my-dir)/../../cl_dll/Android.mk
diff --git a/android/jni/Application.mk b/android/jni/Application.mk
new file mode 100644
index 00000000..ecbc0914
--- /dev/null
+++ b/android/jni/Application.mk
@@ -0,0 +1,11 @@
+CFLAGS_OPT := -O3 -fomit-frame-pointer -ggdb -funsafe-math-optimizations -ftree-vectorize -fgraphite-identity -floop-interchange -floop-block -funsafe-loop-optimizations -finline-limit=1024
+CFLAGS_OPT_ARM := -mthumb -mfpu=neon -mcpu=cortex-a9 -pipe -mvectorize-with-neon-quad -DVECTORIZE_SINCOS
+CFLAGS_OPT_ARMv5 :=-march=armv6 -mfpu=vfp -marm -pipe
+CFLAGS_OPT_X86 := -mtune=atom -march=atom -mssse3 -mfpmath=sse -funroll-loops -pipe -DVECTORIZE_SINCOS
+CFLAGS_HARDFP := -D_NDK_MATH_NO_SOFTFP=1 -mhard-float -mfloat-abi=hard -DLOAD_HARDFP -DSOFTFP_LINK
+APPLICATIONMK_PATH = $(call my-dir)
+
+XASH3D_CONFIG := $(APPLICATIONMK_PATH)/mod_config.mk
+
+APP_ABI := x86 armeabi-v7a-hard armeabi
+APP_MODULES := client
diff --git a/android/jni/mod_config.mk b/android/jni/mod_config.mk
new file mode 100644
index 00000000..5c0dc6bf
--- /dev/null
+++ b/android/jni/mod_config.mk
@@ -0,0 +1,14 @@
+LOCAL_CFLAGS += $(CFLAGS_OPT)
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a-hard)
+LOCAL_CFLAGS += $(CFLAGS_OPT_ARM) $(CFLAGS_HARDFP)
+endif
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+LOCAL_CFLAGS += $(CFLAGS_OPT_ARM) -mfloat-abi=softfp
+endif
+ifeq ($(TARGET_ARCH_ABI),armeabi)
+LOCAL_CFLAGS += $(CFLAGS_OPT_ARMv5)
+endif
+ifeq ($(TARGET_ARCH_ABI),x86)
+LOCAL_CFLAGS += $(CFLAGS_OPT_X86)
+endif
+
diff --git a/android/project.properties b/android/project.properties
new file mode 100644
index 00000000..0b9250e0
--- /dev/null
+++ b/android/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-8
diff --git a/android/res/drawable-hdpi/ic_launcher.png b/android/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 00000000..e11a9eab
Binary files /dev/null and b/android/res/drawable-hdpi/ic_launcher.png differ
diff --git a/android/res/drawable-mdpi/ic_launcher.png b/android/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 00000000..ef9a8d81
Binary files /dev/null and b/android/res/drawable-mdpi/ic_launcher.png differ
diff --git a/android/res/drawable-xhdpi/ic_launcher.png b/android/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..02be2b29
Binary files /dev/null and b/android/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/android/res/drawable-xxhdpi/ic_launcher.png b/android/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..34fd18fe
Binary files /dev/null and b/android/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/android/res/drawable-xxxhdpi/ic_launcher.png b/android/res/drawable-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000..1f156ae5
Binary files /dev/null and b/android/res/drawable-xxxhdpi/ic_launcher.png differ
diff --git a/android/src/in/celest/xash3d/ExtractAssets.java b/android/src/in/celest/xash3d/ExtractAssets.java
new file mode 100644
index 00000000..50b8864e
--- /dev/null
+++ b/android/src/in/celest/xash3d/ExtractAssets.java
@@ -0,0 +1,96 @@
+package in.celest.xash3d;
+import android.content.SharedPreferences;
+import java.io.FileOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import android.util.Log;
+import android.content.Context;
+
+public class ExtractAssets
+{
+ public static String TAG = "ExtractAssets";
+ static SharedPreferences mPref;
+ public static int PAK_VERSION = 0;
+
+ private static int chmod(String path, int mode) {
+ int ret = -1;
+ try
+ {
+ ret = Runtime.getRuntime().exec("chmod " + Integer.toOctalString(mode) + " " + path).waitFor();
+ Log.d(TAG, "chmod " + Integer.toOctalString(mode) + " " + path + ": " + ret );
+ }
+ catch(Exception e)
+ {
+ ret = -1;
+ Log.d(TAG, "chmod: Runtime not worked: " + e.toString() );
+ }
+ try
+ {
+ Class fileUtils = Class.forName("android.os.FileUtils");
+ Method setPermissions = fileUtils.getMethod("setPermissions",
+ String.class, int.class, int.class, int.class);
+ ret = (Integer) setPermissions.invoke(null, path,
+ mode, -1, -1);
+ }
+ catch(Exception e)
+ {
+ ret = -1;
+ Log.d(TAG, "chmod: FileUtils not worked: " + e.toString() );
+ }
+ return ret;
+ }
+
+ private static void extractFile(Context context, String path)
+ {
+ try
+ {
+ InputStream is = null;
+ FileOutputStream os = null;
+ is = context.getAssets().open(path);
+ File out = new File(context.getFilesDir().getPath()+'/'+path);
+ out.getParentFile().mkdirs();
+ chmod( out.getParent(), 0777 );
+ os = new FileOutputStream(out);
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = is.read(buffer)) > 0)
+ {
+ os.write(buffer, 0, length);
+ }
+ os.close();
+ is.close();
+ chmod( context.getFilesDir().getPath()+'/'+path, 0777 );
+ }
+ catch( Exception e )
+ {
+ Log.e( TAG, "Failed to extract file:" + e.toString() );
+ e.printStackTrace();
+ }
+ }
+
+ public static synchronized void extractPAK(Context context, Boolean force)
+ {
+ InputStream is = null;
+ FileOutputStream os = null;
+ try
+ {
+ if( mPref == null )
+ mPref = context.getSharedPreferences("mod", 0);
+ synchronized( mPref )
+ {
+ if( mPref.getInt( "pakversion", 0 ) == PAK_VERSION && !force )
+ return;
+ extractFile(context, "extras.pak");
+ // add custom files here
+ SharedPreferences.Editor editor = mPref.edit();
+ editor.putInt( "pakversion", PAK_VERSION );
+ editor.commit();
+ }
+ }
+ catch( Exception e )
+ {
+ Log.e( TAG, "Failed to extract PAK:" + e.toString() );
+ }
+ }
+}
diff --git a/android/src/in/celest/xash3d/InstallReceiver.java b/android/src/in/celest/xash3d/InstallReceiver.java
new file mode 100644
index 00000000..c2137fa7
--- /dev/null
+++ b/android/src/in/celest/xash3d/InstallReceiver.java
@@ -0,0 +1,17 @@
+package in.celest.xash3d;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class InstallReceiver extends BroadcastReceiver
+{
+ private static final String TAG = "InstallReceiver";
+
+ @Override
+ public void onReceive( Context context, Intent arg1 )
+ {
+ Log.d( TAG, "Install received, extracting PAK" );
+ ExtractAssets.extractPAK( context, true );
+ }
+}
diff --git a/android/src/in/celest/xash3d/LauncherActivity.java b/android/src/in/celest/xash3d/LauncherActivity.java
new file mode 100644
index 00000000..95ae18d2
--- /dev/null
+++ b/android/src/in/celest/xash3d/LauncherActivity.java
@@ -0,0 +1,229 @@
+package in.celest.xash3d;
+
+import android.app.*;
+import android.content.*;
+import android.graphics.*;
+import android.os.*;
+import android.text.*;
+import android.text.style.*;
+import android.view.*;
+import android.widget.*;
+import android.widget.LinearLayout.*;
+
+public class LauncherActivity extends Activity {
+ static EditText cmdArgs;
+ static SharedPreferences mPref;
+ public static final int sdk = Integer.valueOf(Build.VERSION.SDK);
+
+ public SpannableString styleButtonString(String str)
+ {
+ if(sdk < 21)
+ str = str.toUpperCase();
+
+ SpannableString spanString = new SpannableString(str.toUpperCase());
+
+ if(sdk < 21)
+ spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, str.length(), 0);
+
+ return spanString;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ this.requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ // set theme
+ if ( sdk >= 21 )
+ super.setTheme( 0x01030224 );
+ else super.setTheme( 0x01030005 );
+
+ // Build layout
+ LinearLayout launcher = new LinearLayout(this);
+ launcher.setOrientation(LinearLayout.VERTICAL);
+ launcher.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+
+ launcher.setBackgroundColor(0xFF252525);
+ TextView launcherTitle = new TextView(this);
+ LayoutParams titleparams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ titleparams.setMargins(5,20,5,1);
+ LayoutParams buttonparams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ buttonparams.setMargins(10,20,10,20);
+ launcherTitle.setLayoutParams(titleparams);
+ launcherTitle.setText("TFC15-Client");
+ launcherTitle.setTextAppearance(this, android.R.attr.textAppearanceMedium);
+ launcherTitle.setTextSize(25);
+ launcherTitle.setBackgroundColor(0xFF555555);
+ launcherTitle.setCompoundDrawablePadding(10);
+ try
+ {
+ launcherTitle.setCompoundDrawablesWithIntrinsicBounds(getApplicationContext().getPackageManager().getApplicationIcon(getPackageName()),null,null,null);
+ launcherTitle.setPadding(6,9,6,0);
+ }
+ catch(Exception e)
+ {
+ launcherTitle.setPadding(6,6,6,6);
+ }
+ launcher.addView(launcherTitle);
+ LinearLayout launcherBody = new LinearLayout(this);
+ launcherBody.setOrientation(LinearLayout.VERTICAL);
+ launcherBody.setLayoutParams(titleparams);
+ launcherBody.setBackgroundColor(0xFF454545);
+ LinearLayout launcherBorder = new LinearLayout(this);
+ launcherBorder.setLayoutParams(titleparams);
+ launcherBorder.setBackgroundColor(0xFF555555);
+ launcherBorder.setOrientation(LinearLayout.VERTICAL);
+
+ LinearLayout launcherBorder2 = new LinearLayout(this);
+ launcherBorder2.setLayoutParams(titleparams);
+ launcherBorder2.setOrientation(LinearLayout.VERTICAL);
+ launcherBorder2.setBackgroundColor(0xFF353535);
+ launcherBorder2.addView(launcherBody);
+ launcherBorder2.setPadding(10,0,10,10);
+ launcherBorder.addView(launcherBorder2);
+ launcherBorder.setPadding(10,0,10,20);
+ launcher.addView(launcherBorder);
+
+ TextView titleView = new TextView(this);
+ titleView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
+ titleView.setText("Command-line arguments");
+ titleView.setTextAppearance(this, android.R.attr.textAppearanceLarge);
+
+ cmdArgs = new EditText(this);
+ cmdArgs.setLayoutParams(buttonparams);
+ cmdArgs.setSingleLine(true);
+ if(sdk < 21)
+ {
+ cmdArgs.setBackgroundColor(0xFF353535);
+ cmdArgs.setTextColor(0xFFFFFFFF);
+ cmdArgs.setPadding(5,5,5,5);
+ }
+ Button startButton = new Button(this);
+
+ // Set launch button title here
+ startButton.setText(styleButtonString("Launch " + "TFC15-Client" + "!"));
+ LayoutParams buttonParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
+ buttonParams.gravity = 5;
+ startButton.setLayoutParams(buttonParams);
+ if(sdk < 21)
+ {
+ startButton.getBackground().setAlpha(96);
+ startButton.getBackground().invalidateSelf();
+ startButton.setTextColor(0xFFFFFFFF);
+ startButton.setTextAppearance(this, android.R.attr.textAppearanceLarge);
+ startButton.setTextSize(20);
+ }
+ startButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startXash(v);
+ }
+ });
+ launcherBody.addView(titleView);
+ launcherBody.addView(cmdArgs);
+
+ // Add other options here
+
+ launcher.addView(startButton);
+ setContentView(launcher);
+ mPref = getSharedPreferences("mod", 0);
+ cmdArgs.setText(mPref.getString("argv","-dev 3 -log"));
+
+ // Uncomment this if you have pak file
+ // ExtractAssets.extractPAK(this, false);
+ }
+
+ private Intent prepareIntent(Intent i)
+ {
+ String argv = cmdArgs.getText().toString();
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ SharedPreferences.Editor editor = mPref.edit();
+
+ editor.putString("argv", argv);
+ editor.commit();
+
+ // Command-line arguments
+ // if not passed, uses arguments from xash3d package
+ // Uncoment this if you are using client from other package
+ /*
+ String libserver = getFilesDir().getAbsolutePath().replace("/files","/lib/libserver_hardfp.so");
+ if( !(new File(libserver).exists()) )
+ libserver = getFilesDir().getAbsolutePath().replace("/files","/lib/libserver.so");
+ argv = "-dll "+ libserver + " " + argv;
+ */
+ if(argv.length() != 0)
+ i.putExtra("argv", argv);
+
+ // default gamedir
+ // may be overriden by -game command-line option
+ // Uncomment to set gamedir here
+ i.putExtra("gamedir", "tfc" );
+
+ // default library package
+ // if you are using client from other package (not from half-life),
+ // replace following line by:
+ /*i.putExtra("gamelibdir", "/data/data//lib");*/
+ i.putExtra("gamelibdir", getFilesDir().getAbsolutePath().replace("/files","/lib"));
+
+ // if you are using pak file, uncomment this:
+ // i.putExtra("pakfile", getFilesDir().getAbsolutePath() + "/extras.pak");
+
+ // you may pass extra enviroment variables to game
+ // it is availiable from game code with getenv() function
+ /*
+ String envp[] =
+ {
+ "VAR1", "value1",
+ "VAR2", "value2"
+ };
+ i.putExtra("env", envp);
+ */
+
+ return i;
+ }
+
+ public void startXash(View view)
+ {
+ try
+ {
+ Intent intent = new Intent();
+ intent.setAction("in.celest.xash3d.START");
+ intent = prepareIntent(intent);
+ startActivity(intent);
+ return;
+ }
+ catch(Exception e){}
+ // some samsung devices have
+ // completely broken intent resolver
+ // so try specify exact component here
+ try
+ {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName("in.celest.xash3d.hl.test", "in.celest.xash3d.XashActivity"));
+ intent = prepareIntent(intent);
+ startActivity(intent);
+ return;
+ }
+ catch(Exception e){}
+ try
+ {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName("in.celest.xash3d.hl", "in.celest.xash3d.XashActivity"));
+ intent = prepareIntent(intent);
+ startActivity(intent);
+ return;
+ }
+ catch(Exception e){}
+ new AlertDialog.Builder(this)
+ .setTitle("Error")
+ .setMessage("Failed to start Xash3D FWGS engine\nIs it installed?")
+ .setCancelable(false)
+ .setPositiveButton("Ok", new DialogInterface.OnClickListener()
+ {
+ public void onClick(DialogInterface i, int w){
+ LauncherActivity.this.finish();
+ }
+ }).show();
+ }
+}
diff --git a/cl_dll/Android.mk b/cl_dll/Android.mk
index df6130ed..3f1bf805 100755
--- a/cl_dll/Android.mk
+++ b/cl_dll/Android.mk
@@ -24,25 +24,26 @@ LOCAL_CFLAGS += -DCLIENT_DLL=1
SRCS=
SRCS_C=
-SRCS+=../dlls/crossbow.cpp
-SRCS+=../dlls/crowbar.cpp
-SRCS+=../dlls/egon.cpp
-SRCS+=./ev_hldm.cpp
-SRCS+=../dlls/gauss.cpp
-SRCS+=../dlls/handgrenade.cpp
+SRCS+=./tfc/ev_tfc.cpp
SRCS+=./hl/hl_baseentity.cpp
-SRCS+=./hl/hl_events.cpp
+SRCS+=./tfc/tfc_events.cpp
SRCS+=./hl/hl_objects.cpp
-SRCS+=./hl/hl_weapons.cpp
-SRCS+=../dlls/hornetgun.cpp
-SRCS+=../dlls/mp5.cpp
-SRCS+=../dlls/python.cpp
-SRCS+=../dlls/rpg.cpp
-SRCS+=../dlls/satchel.cpp
-SRCS+=../dlls/shotgun.cpp
-SRCS+=../dlls/squeakgrenade.cpp
-SRCS+=../dlls/tripmine.cpp
-SRCS+=../dlls/glock.cpp
+SRCS+=./tfc/tfc_weapons.cpp
+SRCS+=../dlls/crowbar.cpp
+SRCS+=../dlls/tfc/assaultcannon.cpp
+SRCS+=../dlls/tfc/axe.cpp
+SRCS+=../dlls/tfc/flamethrower.cpp
+SRCS+=../dlls/tfc/grenadelauncher.cpp
+SRCS+=../dlls/tfc/incendiarycannon.cpp
+SRCS+=../dlls/tfc/nailgun.cpp
+SRCS+=../dlls/tfc/pipebomblauncher.cpp
+SRCS+=../dlls/tfc/railgun.cpp
+SRCS+=../dlls/tfc/rpg.cpp
+SRCS+=../dlls/tfc/shotgun.cpp
+SRCS+=../dlls/tfc/sniperrifle.cpp
+SRCS+=../dlls/tfc/spanner.cpp
+SRCS+=../dlls/tfc/supernailgun.cpp
+SRCS+=../dlls/tfc/supershotgun.cpp
#SRCS+=../game_shared/voice_banmgr.cpp
#SRCS+=../game_shared/voice_status.cpp
SRCS+=./ammo.cpp
@@ -100,6 +101,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \
$(LOCAL_PATH)/../game_shared \
$(LOCAL_PATH)/../dlls \
$(LOCAL_PATH)/../pm_shared \
+ $(LOCAL_PATH)/../dlls/tfc \
$(LOCAL_PATH)/../utils/false_vgui/include
LOCAL_CFLAGS += $(DEFINES) $(INCLUDES)
diff --git a/cl_dll/hl/hl_objects.cpp b/cl_dll/hl/hl_objects.cpp
index 55822dcb..89bc2b8c 100644
--- a/cl_dll/hl/hl_objects.cpp
+++ b/cl_dll/hl/hl_objects.cpp
@@ -29,7 +29,7 @@
extern BEAM *pBeam;
extern BEAM *pBeam2;
-extern TEMPENTITY *pFlare; // Vit_amiN: egon's energy flare
+//extern TEMPENTITY *pFlare; // Vit_amiN: egon's energy flare
void HUD_GetLastOrg( float *org );
void UpdateBeams( void )
@@ -76,7 +76,7 @@ void UpdateBeams( void )
pBeam2->target = tr.endpos;
pBeam2->die = gEngfuncs.GetClientTime() + 0.1; // We keep it alive just a little bit forward in the future, just in case.
}
-
+/*
if( pFlare ) // Vit_amiN: beam flare
{
pFlare->entity.origin = tr.endpos;
@@ -98,6 +98,7 @@ void UpdateBeams( void )
}
}
}
+*/
}
/*
@@ -109,6 +110,8 @@ Add game specific, client-side objects here
*/
void Game_AddObjects( void )
{
+ /*
if( pBeam || pBeam2 || pFlare ) // Vit_amiN: egon flare added
UpdateBeams();
+ */
}
diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp
index 62c32b41..7af2b738 100644
--- a/cl_dll/hud.cpp
+++ b/cl_dll/hud.cpp
@@ -28,6 +28,9 @@
#include "demo.h"
#include "demo_api.h"
+#define MENU_TEAM 2
+#define MENU_CLASS 3
+
cvar_t *hud_textmode;
float g_hud_text_color[3];
@@ -123,7 +126,7 @@ int __MsgFunc_Detpack( const char *pszName, int iSize, void *pbuf )
int __MsgFunc_VGUIMenu( const char *pszName, int iSize, void *pbuf )
{
- return 0;
+ return gHUD.MsgFunc_VGUIMenu( pszName, iSize, pbuf );
}
int __MsgFunc_BuildSt( const char *pszName, int iSize, void *pbuf )
@@ -148,7 +151,7 @@ int __MsgFunc_Spectator( const char *pszName, int iSize, void *pbuf )
int __MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf )
{
- return 0;
+ return gHUD.MsgFunc_AllowSpec( pszName, iSize, pbuf );
}
// This is called every time the DLL is loaded
@@ -587,3 +590,42 @@ float CHud::GetSensitivity( void )
{
return m_flMouseSensitivity;
}
+
+int CHud::MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf )
+{
+ BEGIN_READ( pbuf, iSize );
+
+ m_bAllowSpec = (bool)READ_BYTE();
+
+ return 1;
+}
+
+int CHud::MsgFunc_VGUIMenu( const char *pszName, int iSize, void *pbuf )
+{
+ BEGIN_READ( pbuf, iSize );
+
+ int menuType = READ_BYTE();
+ //m_bitsValidSlots = READ_SHORT(); // is ignored
+
+ ShowVGUIMenu(menuType);
+ return 1;
+}
+
+void CHud::ShowVGUIMenu( int menuType )
+{
+ char *szCmd;
+
+ switch(menuType)
+ {
+ case MENU_TEAM:
+ szCmd = "exec touch/chooseteam.cfg";
+ break;
+ default:
+ szCmd = "touch_removebutton _menu_*"; // back to the default touch page
+ //m_fMenuDisplayed = 0;
+ break;
+ }
+ //Velaron: Touch Menus
+ //m_fMenuDisplayed = 1;
+ ClientCmd(szCmd);
+}
diff --git a/cl_dll/hud.h b/cl_dll/hud.h
index f3e1ed85..8ad0f98a 100644
--- a/cl_dll/hud.h
+++ b/cl_dll/hud.h
@@ -420,6 +420,7 @@ private:
wrect_t *m_prc1;
wrect_t *m_prc2;
int m_iBat;
+ int m_iBatMax;
float m_fFade;
int m_iHeight; // width of the battery innards
};
@@ -597,6 +598,8 @@ public:
int DrawHudStringLen( const char *szIt );
void DrawDarkRectangle( int x, int y, int wide, int tall );
+ bool m_bAllowSpec;
+
private:
// the memory for these arrays are allocated in the first call to CHud::VidInit(), when the hud.txt and associated sprites are loaded.
// freed in ~CHud()
@@ -655,6 +658,9 @@ public:
int _cdecl MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf );
int _cdecl MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf );
+ int _cdecl MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf );
+ int _cdecl MsgFunc_VGUIMenu( const char *pszName, int iSize, void *pbuf );
+
// Screen information
SCREENINFO m_scrinfo;
@@ -670,6 +676,8 @@ public:
void AddHudElem( CHudBase *p );
float GetSensitivity();
+
+ void ShowVGUIMenu( int menuType );
};
extern CHud gHUD;
diff --git a/cl_dll/hud_msg.cpp b/cl_dll/hud_msg.cpp
index 7cc2fbad..930f3dc6 100644
--- a/cl_dll/hud_msg.cpp
+++ b/cl_dll/hud_msg.cpp
@@ -25,7 +25,7 @@
extern BEAM *pBeam;
extern BEAM *pBeam2;
-extern TEMPENTITY *pFlare; // Vit_amiN
+//extern TEMPENTITY *pFlare; // Vit_amiN
extern float g_lastFOV; // Vit_amiN
@@ -79,7 +79,7 @@ void CHud::MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf )
//Probably not a good place to put this.
pBeam = pBeam2 = NULL;
- pFlare = NULL; // Vit_amiN: clear egon's beam flare
+ //pFlare = NULL; // Vit_amiN: clear egon's beam flare
}
int CHud::MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf )
diff --git a/cl_dll/tfc/ev_tfc.cpp b/cl_dll/tfc/ev_tfc.cpp
new file mode 100644
index 00000000..161b2fae
--- /dev/null
+++ b/cl_dll/tfc/ev_tfc.cpp
@@ -0,0 +1,2225 @@
+/***
+*
+* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
+*
+* This product contains software technology licensed from Id
+* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
+* All Rights Reserved.
+*
+* Use, distribution, and modification of this source code and/or resulting
+* object code is restricted to non-commercial enhancements to products from
+* Valve LLC. All other use, distribution, or modification is prohibited
+* without written permission from Valve LLC.
+*
+****/
+
+#include "hud.h"
+#include "cl_util.h"
+#include "const.h"
+#include "entity_state.h"
+#include "cl_entity.h"
+#include "entity_types.h"
+#include "usercmd.h"
+#include "pm_defs.h"
+#include "pm_materials.h"
+
+#include "eventscripts.h"
+#include "ev_tfc.h"
+
+#include "r_efx.h"
+#include "event_api.h"
+#include "event_args.h"
+#include "in_defs.h"
+
+#include
+
+#include "r_studioint.h"
+#include "com_model.h"
+
+extern engine_studio_api_t IEngineStudio;
+
+static int tracerCount[32];
+
+extern "C" char PM_FindTextureType( char *name );
+
+void V_PunchAxis( int axis, float punch );
+void VectorAngles( const float *forward, float *angles );
+
+extern cvar_t *cl_lw;
+
+
+BEAM *pBeam;
+BEAM *pBeam2;
+
+extern "C" float anglemod( float a );
+
+struct eventnode_s
+{
+ event_args_t *data;
+ eventnode_s *prev;
+ eventnode_s *next;
+};
+typedef eventnode_s eventnode_t;
+
+pmtrace_t *gp_tr_decal[32];
+float g_flSpinDownTime[32];
+int g_bACSpinning[32];
+float g_flSpinUpTime[32];
+
+extern "C"
+{
+void EV_TFC_Axe( struct event_args_s *args );
+void EV_FireTFCShotgun( struct event_args_s *args );
+void EV_FireTFCSuperShotgun( struct event_args_s *args );
+void EV_ReloadTFCShotgun( struct event_args_s *args );
+void EV_PumpTFCShotgun( struct event_args_s *args );
+void EV_FireTFCNailgun( struct event_args_s *args );
+void EV_FireTFCSuperNailgun( struct event_args_s *args );
+void EV_FireTFCAutoRifle( struct event_args_s *args );
+void EV_TFC_Gas( struct event_args_s *args );
+void EV_TFC_DoorGoUp( struct event_args_s *args );
+void EV_TFC_DoorGoDown( struct event_args_s *args );
+void EV_TFC_DoorHitTop( struct event_args_s *args );
+void EV_TFC_DoorHitBottom( struct event_args_s *args );
+void EV_TFC_Explosion( struct event_args_s *args );
+void EV_TFC_Grenade( struct event_args_s *args );
+void EV_TFC_NormalGrenade( struct event_args_s *args );
+void EV_TFC_FireRPG( struct event_args_s *args );
+void EV_FireTFCSniper( struct event_args_s *args );
+void EV_TFC_SniperHit( struct event_args_s *args );
+void EV_TFC_FireIC( struct event_args_s *args );
+void EV_TFC_NailgrenadeNail( struct event_args_s *args );
+void EV_TFC_GrenadeLauncher( struct event_args_s *args );
+void EV_TFC_PipeLauncher( struct event_args_s *args );
+void EV_TFC_NormalShot( struct event_args_s *args );
+void EV_TFC_SuperShot( struct event_args_s *args );
+void EV_TFC_SteamShot( struct event_args_s *args );
+void EV_TFC_EngineerGrenade( struct event_args_s *args );
+void EV_TFC_Concussion( struct event_args_s *args );
+void EV_TFC_Assault_WindUp( struct event_args_s *args );
+void EV_TFC_Assault_WindDown( struct event_args_s *args );
+void EV_TFC_Assault_Start( struct event_args_s *args );
+void EV_TFC_Assault_Fire( struct event_args_s *args );
+void EV_TFC_Assault_Spin( struct event_args_s *args );
+void EV_TFC_Assault_StartSpin( struct event_args_s *args );
+void EV_TFC_AxeDecal( struct event_args_s *args );
+void EV_TFC_NapalmFire( struct event_args_s *args );
+void EV_TFC_MirvGrenadeMain( struct event_args_s *args );
+void EV_TFC_MirvGrenade( struct event_args_s *args );
+void EV_TFC_NapalmBurn( struct event_args_s *args );
+void EV_TFC_EMP( struct event_args_s *args );
+void EV_TFC_Flame_Fire( struct event_args_s *args );
+void EV_TFC_Railgun( struct event_args_s *args );
+void EV_TFC_Tranquilizer( struct event_args_s *args );
+void EV_TFC_NailGrenade( struct event_args_s *args );
+
+void EV_TrainPitchAdjust( struct event_args_s *args );
+}
+
+#define VECTOR_CONE_1DEGREES Vector( 0.00873, 0.00873, 0.00873 )
+#define VECTOR_CONE_2DEGREES Vector( 0.01745, 0.01745, 0.01745 )
+#define VECTOR_CONE_3DEGREES Vector( 0.02618, 0.02618, 0.02618 )
+#define VECTOR_CONE_4DEGREES Vector( 0.03490, 0.03490, 0.03490 )
+#define VECTOR_CONE_5DEGREES Vector( 0.04362, 0.04362, 0.04362 )
+#define VECTOR_CONE_6DEGREES Vector( 0.05234, 0.05234, 0.05234 )
+#define VECTOR_CONE_7DEGREES Vector( 0.06105, 0.06105, 0.06105 )
+#define VECTOR_CONE_8DEGREES Vector( 0.06976, 0.06976, 0.06976 )
+#define VECTOR_CONE_9DEGREES Vector( 0.07846, 0.07846, 0.07846 )
+#define VECTOR_CONE_10DEGREES Vector( 0.08716, 0.08716, 0.08716 )
+#define VECTOR_CONE_15DEGREES Vector( 0.13053, 0.13053, 0.13053 )
+#define VECTOR_CONE_20DEGREES Vector( 0.17365, 0.17365, 0.17365 )
+
+// play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the
+// original traceline endpoints used by the attacker, iBulletType is the type of bullet that hit the texture.
+// returns volume of strike instrument (crowbar) to play
+float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *vecEnd, int iBulletType )
+{
+ // hit the world, try to play sound based on texture material type
+ char chTextureType = CHAR_TEX_CONCRETE;
+ float fvol;
+ float fvolbar;
+ char *rgsz[4];
+ int cnt;
+ float fattn = ATTN_NORM;
+ int entity;
+ char *pTextureName;
+ char texname[64];
+ char szbuffer[64];
+
+ entity = gEngfuncs.pEventAPI->EV_IndexFromTrace( ptr );
+
+ // FIXME check if playtexture sounds movevar is set
+ //
+ chTextureType = 0;
+
+ // Player
+ if( entity >= 1 && entity <= gEngfuncs.GetMaxClients() )
+ {
+ // hit body
+ chTextureType = CHAR_TEX_FLESH;
+ }
+ else if( entity == 0 )
+ {
+ // get texture from entity or world (world is ent(0))
+ pTextureName = (char *)gEngfuncs.pEventAPI->EV_TraceTexture( ptr->ent, vecSrc, vecEnd );
+
+ if ( pTextureName )
+ {
+ strcpy( texname, pTextureName );
+ pTextureName = texname;
+
+ // strip leading '-0' or '+0~' or '{' or '!'
+ if( *pTextureName == '-' || *pTextureName == '+' )
+ {
+ pTextureName += 2;
+ }
+
+ if( *pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ' )
+ {
+ pTextureName++;
+ }
+
+ // '}}'
+ strcpy( szbuffer, pTextureName );
+ szbuffer[CBTEXTURENAMEMAX - 1] = 0;
+
+ // get texture type
+ chTextureType = PM_FindTextureType( szbuffer );
+ }
+ }
+
+ switch (chTextureType)
+ {
+ default:
+ case CHAR_TEX_CONCRETE:
+ fvol = 0.9;
+ fvolbar = 0.6;
+ rgsz[0] = "player/pl_step1.wav";
+ rgsz[1] = "player/pl_step2.wav";
+ cnt = 2;
+ break;
+ case CHAR_TEX_METAL:
+ fvol = 0.9;
+ fvolbar = 0.3;
+ rgsz[0] = "player/pl_metal1.wav";
+ rgsz[1] = "player/pl_metal2.wav";
+ cnt = 2;
+ break;
+ case CHAR_TEX_DIRT:
+ fvol = 0.9;
+ fvolbar = 0.1;
+ rgsz[0] = "player/pl_dirt1.wav";
+ rgsz[1] = "player/pl_dirt2.wav";
+ rgsz[2] = "player/pl_dirt3.wav";
+ cnt = 3;
+ break;
+ case CHAR_TEX_VENT:
+ fvol = 0.5;
+ fvolbar = 0.3;
+ rgsz[0] = "player/pl_duct1.wav";
+ rgsz[1] = "player/pl_duct1.wav";
+ cnt = 2;
+ break;
+ case CHAR_TEX_GRATE:
+ fvol = 0.9;
+ fvolbar = 0.5;
+ rgsz[0] = "player/pl_grate1.wav";
+ rgsz[1] = "player/pl_grate4.wav";
+ cnt = 2;
+ break;
+ case CHAR_TEX_TILE:
+ fvol = 0.8;
+ fvolbar = 0.2;
+ rgsz[0] = "player/pl_tile1.wav";
+ rgsz[1] = "player/pl_tile3.wav";
+ rgsz[2] = "player/pl_tile2.wav";
+ rgsz[3] = "player/pl_tile4.wav";
+ cnt = 4;
+ break;
+ case CHAR_TEX_SLOSH:
+ fvol = 0.9;
+ fvolbar = 0.0;
+ rgsz[0] = "player/pl_slosh1.wav";
+ rgsz[1] = "player/pl_slosh3.wav";
+ rgsz[2] = "player/pl_slosh2.wav";
+ rgsz[3] = "player/pl_slosh4.wav";
+ cnt = 4;
+ break;
+ case CHAR_TEX_WOOD:
+ fvol = 0.9;
+ fvolbar = 0.2;
+ rgsz[0] = "debris/wood1.wav";
+ rgsz[1] = "debris/wood2.wav";
+ rgsz[2] = "debris/wood3.wav";
+ cnt = 3;
+ break;
+ case CHAR_TEX_GLASS:
+ case CHAR_TEX_COMPUTER:
+ fvol = 0.8;
+ fvolbar = 0.2;
+ rgsz[0] = "debris/glass1.wav";
+ rgsz[1] = "debris/glass2.wav";
+ rgsz[2] = "debris/glass3.wav";
+ cnt = 3;
+ break;
+ case CHAR_TEX_FLESH:
+ if( iBulletType == BULLET_PLAYER_CROWBAR )
+ return 0.0; // crowbar already makes this sound
+ fvol = 1.0;
+ fvolbar = 0.2;
+ rgsz[0] = "weapons/bullet_hit1.wav";
+ rgsz[1] = "weapons/bullet_hit2.wav";
+ fattn = 1.0;
+ cnt = 2;
+ break;
+ }
+
+ // play material hit sound
+ gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, rgsz[gEngfuncs.pfnRandomLong( 0, cnt - 1 )], fvol, fattn, 0, 96 + gEngfuncs.pfnRandomLong( 0, 0xf ) );
+ return fvolbar;
+}
+
+char *EV_HLDM_DamageDecal( physent_t *pe )
+{
+ static char decalname[32];
+ int idx;
+
+ if( pe->classnumber == 1 )
+ {
+ idx = gEngfuncs.pfnRandomLong( 0, 2 );
+ sprintf( decalname, "{break%i", idx + 1 );
+ }
+ else if( pe->rendermode != kRenderNormal )
+ {
+ sprintf( decalname, "{bproof1" );
+ }
+ else
+ {
+ idx = gEngfuncs.pfnRandomLong( 0, 4 );
+ sprintf( decalname, "{shot%i", idx + 1 );
+ }
+ return decalname;
+}
+
+void EV_HLDM_GunshotDecalTrace( pmtrace_t *pTrace, char *decalName )
+{
+ int iRand;
+ physent_t *pe;
+
+ gEngfuncs.pEfxAPI->R_BulletImpactParticles( pTrace->endpos );
+
+ iRand = gEngfuncs.pfnRandomLong( 0, 0x7FFF );
+ if( iRand < ( 0x7fff / 2 ) )// not every bullet makes a sound.
+ {
+ switch( iRand % 5 )
+ {
+ case 0:
+ gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM );
+ break;
+ case 1:
+ gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric2.wav", 1.0, ATTN_NORM, 0, PITCH_NORM );
+ break;
+ case 2:
+ gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric3.wav", 1.0, ATTN_NORM, 0, PITCH_NORM );
+ break;
+ case 3:
+ gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric4.wav", 1.0, ATTN_NORM, 0, PITCH_NORM );
+ break;
+ case 4:
+ gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric5.wav", 1.0, ATTN_NORM, 0, PITCH_NORM );
+ break;
+ }
+ }
+
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent( pTrace->ent );
+
+ // Only decal brush models such as the world etc.
+ if( decalName && decalName[0] && pe && ( pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP ) )
+ {
+ if( CVAR_GET_FLOAT( "r_decals" ) )
+ {
+ gEngfuncs.pEfxAPI->R_DecalShoot(
+ gEngfuncs.pEfxAPI->Draw_DecalIndex( gEngfuncs.pEfxAPI->Draw_DecalIndexFromName( decalName ) ),
+ gEngfuncs.pEventAPI->EV_IndexFromTrace( pTrace ), 0, pTrace->endpos, 0 );
+ }
+ }
+}
+
+void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType )
+{
+ physent_t *pe;
+
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent( pTrace->ent );
+
+ if( pe && ( pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP ) )
+ {
+ switch( iBulletType )
+ {
+ case BULLET_PLAYER_9MM:
+ case BULLET_MONSTER_9MM:
+ case BULLET_PLAYER_MP5:
+ case BULLET_MONSTER_MP5:
+ case BULLET_PLAYER_BUCKSHOT:
+ case BULLET_PLAYER_357:
+ default:
+ // smoke and decal
+ EV_HLDM_GunshotDecalTrace( pTrace, EV_HLDM_DamageDecal( pe ) );
+ break;
+ }
+ }
+}
+
+int EV_HLDM_CheckTracer( int idx, float *vecSrc, float *end, float *forward, float *right, int iBulletType, int iTracerFreq, int *tracerCount )
+{
+ int tracer = 0;
+ int i;
+ qboolean player = idx >= 1 && idx <= gEngfuncs.GetMaxClients() ? true : false;
+
+ if( iTracerFreq != 0 && ( (*tracerCount)++ % iTracerFreq ) == 0 )
+ {
+ vec3_t vecTracerSrc;
+
+ if( player )
+ {
+ vec3_t offset( 0, 0, -4 );
+
+ // adjust tracer position for player
+ for( i = 0; i < 3; i++ )
+ {
+ vecTracerSrc[i] = vecSrc[i] + offset[i] + right[i] * 2 + forward[i] * 16;
+ }
+ }
+ else
+ {
+ VectorCopy( vecSrc, vecTracerSrc );
+ }
+
+ if( iTracerFreq != 1 ) // guns that always trace also always decal
+ tracer = 1;
+
+ switch( iBulletType )
+ {
+ case BULLET_PLAYER_MP5:
+ case BULLET_MONSTER_MP5:
+ case BULLET_MONSTER_9MM:
+ case BULLET_MONSTER_12MM:
+ default:
+ EV_CreateTracer( vecTracerSrc, end );
+ break;
+ }
+ }
+
+ return tracer;
+}
+
+/*
+================
+FireBullets
+
+Go to the trouble of combining multiple pellets into a single damage call.
+================
+*/
+void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, float flDistance, int iBulletType, int iTracerFreq, int *tracerCount, float flSpreadX, float flSpreadY )
+{
+ int i;
+ pmtrace_t tr;
+ int iShot;
+ int tracer;
+
+ for( iShot = 1; iShot <= cShots; iShot++ )
+ {
+ vec3_t vecDir, vecEnd;
+ float x, y, z;
+
+ //We randomize for the Shotgun.
+ if( iBulletType == BULLET_PLAYER_BUCKSHOT )
+ {
+ do{
+ x = gEngfuncs.pfnRandomFloat( -0.5, 0.5 ) + gEngfuncs.pfnRandomFloat( -0.5, 0.5 );
+ y = gEngfuncs.pfnRandomFloat( -0.5, 0.5 ) + gEngfuncs.pfnRandomFloat( -0.5, 0.5 );
+ z = x * x + y * y;
+ }while( z > 1 );
+
+ for( i = 0 ; i < 3; i++ )
+ {
+ vecDir[i] = vecDirShooting[i] + x * flSpreadX * right[i] + y * flSpreadY * up [i];
+ vecEnd[i] = vecSrc[i] + flDistance * vecDir[i];
+ }
+ }//But other guns already have their spread randomized in the synched spread.
+ else
+ {
+ for( i = 0 ; i < 3; i++ )
+ {
+ vecDir[i] = vecDirShooting[i] + flSpreadX * right[i] + flSpreadY * up [i];
+ vecEnd[i] = vecSrc[i] + flDistance * vecDir[i];
+ }
+ }
+
+ gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true );
+
+ // Store off the old count
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+
+ // 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 );
+
+ tracer = EV_HLDM_CheckTracer( idx, vecSrc, tr.endpos, forward, right, iBulletType, iTracerFreq, tracerCount );
+
+ // do damage, paint decals
+ if( tr.fraction != 1.0 )
+ {
+ switch( iBulletType )
+ {
+ default:
+ case BULLET_PLAYER_9MM:
+ EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
+ EV_HLDM_DecalGunshot( &tr, iBulletType );
+ break;
+ case BULLET_PLAYER_MP5:
+ if( !tracer )
+ {
+ EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
+ EV_HLDM_DecalGunshot( &tr, iBulletType );
+ }
+ break;
+ case BULLET_PLAYER_BUCKSHOT:
+ EV_HLDM_DecalGunshot( &tr, iBulletType );
+ break;
+ case BULLET_PLAYER_357:
+ EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
+ EV_HLDM_DecalGunshot( &tr, iBulletType );
+ break;
+ }
+ }
+
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ }
+}
+
+#define SND_CHANGE_PITCH (1 << 7)
+
+void EV_TrainPitchAdjust( event_args_t *args )
+{
+ int idx;
+ vec3_t origin;
+
+ unsigned short us_params;
+ int noise;
+ float m_flVolume;
+ int pitch;
+ int stop;
+
+ char sz[256];
+
+ idx = args->entindex;
+
+ VectorCopy( args->origin, origin );
+
+ us_params = (unsigned short)args->iparam1;
+ stop = args->bparam1;
+
+ m_flVolume = (float)( us_params & 0x003f ) / 40.0;
+ noise = (int)( ( ( us_params ) >> 12 ) & 0x0007 );
+ pitch = (int)( 10.0 * (float)( ( us_params >> 6 ) & 0x003f ) );
+
+ switch( noise )
+ {
+ case 1:
+ strcpy( sz, "plats/ttrain1.wav" );
+ break;
+ case 2:
+ strcpy( sz, "plats/ttrain2.wav" );
+ break;
+ case 3:
+ strcpy( sz, "plats/ttrain3.wav" );
+ break;
+ case 4:
+ strcpy( sz, "plats/ttrain4.wav");
+ break;
+ case 5:
+ strcpy( sz, "plats/ttrain6.wav");
+ break;
+ case 6:
+ strcpy( sz, "plats/ttrain7.wav");
+ break;
+ default:
+ // no sound
+ strcpy( sz, "" );
+ return;
+ }
+
+ if( stop )
+ {
+ gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, sz );
+ }
+ else
+ {
+ gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, sz, m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, pitch );
+ }
+}
+
+int EV_TFC_IsAllyTeam( int iTeam1, int iTeam2 )
+{
+ return 0;
+}
+
+enum tfc_axe_e
+{
+ AXE_IDLE1 = 0,
+ AXE_DRAW,
+ AXE_HOLSTER,
+ AXE_ATTACK1,
+ AXE_ATTACK1MISS,
+ AXE_ATTACK2,
+ AXE_ATTACK2HIT,
+ AXE_ATTACK3,
+ AXE_ATTACK3HIT,
+ AXE_IDLE2,
+ AXE_IDLE3
+};
+
+int m_iSwing;
+
+void EV_TFC_Axe(event_args_t *args)
+{
+ int idx;
+ float fSoundData;
+ float *vecc;
+ signed int classid;
+ int ent;
+ pmtrace_t tr;
+ pmtrace_t tr2;
+ vec3_t vecSrc, vecEnd;
+ vec3_t right, forward, up;
+ vec3_t origin, angles;
+
+ idx = args->entindex;
+ classid = args->iparam1;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ AngleVectors(angles, forward, right, up);
+ EV_GetGunPosition(args, vecSrc, origin);
+ VectorMA(vecSrc, 32.0, forward, vecEnd);
+ gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction(0, 1);
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetSolidPlayers(idx - 1);
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ if (tr.fraction >= 1.0)
+ {
+ gEngfuncs.pEventAPI->EV_SetTraceHull(1);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr2);
+ if(tr2.fraction < 1.0)
+ tr = tr2;
+ }
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ if(tr.fraction >= 1.0)
+ {
+ switch(classid)
+ {
+ default:
+ {
+ switch((m_iSwing++) % 3)
+ {
+ case 1:
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation( AXE_ATTACK1, 2 );
+ break;
+ case 2:
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation( AXE_ATTACK2, 2 );
+ break;
+ default:
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation( AXE_ATTACK3, 2 );
+ break;
+ }
+ if (EV_IsLocal(idx))
+ EV_TFC_PlayAxeSound(idx, classid, origin, 0, 1.0);
+ }
+ break;
+ case 2:
+ case 0:
+ {
+ if (EV_IsLocal(idx))
+ {
+ gEngfuncs.pEventAPI->EV_WeaponAnimation( 2, 2 );
+ EV_TFC_PlayAxeSound(idx, classid, origin, 0, 1.0);
+ }
+ }
+ break;
+ case 1:
+ {
+ if (EV_IsLocal(idx))
+ {
+ gEngfuncs.pEventAPI->EV_WeaponAnimation( 1, 2 );
+ EV_TFC_PlayAxeSound(idx, classid, origin, 0, 1.0);
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ ent = gEngfuncs.pEventAPI->EV_IndexFromTrace(&tr);
+ switch(classid)
+ {
+ default:
+ {
+ if(!EV_TFC_IsAlly(idx, ent))
+ {
+ if(gEngfuncs.pfnGetCvarFloat("cl_localblood") != 0.0)
+ EV_TFC_TraceAttack(idx, forward, &tr, 20.0);
+ }
+ if(EV_IsPlayer(ent))
+ EV_TFC_PlayAxeSound(idx, classid, origin, 1, 1.0);
+ else
+ EV_TFC_PlayAxeSound(idx, classid, origin, 2, 1.0);
+ switch((m_iSwing++) % 2)
+ {
+ case 1:
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation( AXE_ATTACK2HIT, 2 );
+ break;
+ default:
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation( AXE_ATTACK3HIT, 2 );
+ break;
+ }
+ }
+ break;
+ case 0:
+ {
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(2, 2);
+ EV_TFC_AxeHit(idx, origin, forward, right, ent, forward, &tr);
+ if (EV_IsLocal(idx))
+ if(EV_IsPlayer(ent))
+ EV_TFC_PlayAxeSound(idx, classid, origin, 1, 1.0);
+ else
+ EV_TFC_PlayAxeSound(idx, classid, origin, 2, 1.0);
+ }
+ break;
+ case 2:
+ {
+ EV_TFC_Medkit(idx, origin, forward, right, ent, forward, &tr);
+ if (EV_IsLocal(idx))
+ {
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(3, 2);
+ if(EV_IsPlayer(ent))
+ EV_TFC_PlayAxeSound(idx, classid, origin, 1, 1.0);
+ else
+ EV_TFC_PlayAxeSound(idx, classid, origin, 2, 1.0);
+ }
+ }
+ break;
+ case 1:
+ {
+ EV_TFC_AxeHit(idx, origin, forward, right, ent, forward, &tr);
+ if (EV_IsLocal(idx))
+ {
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(3, 2);
+ if(EV_IsPlayer(ent))
+ EV_TFC_PlayAxeSound(idx, classid, origin, 1, 1.0);
+ else
+ EV_TFC_PlayAxeSound(idx, classid, origin, 2, 1.0);
+ }
+ }
+ break;
+ }
+ }
+}
+
+enum tfc_shotgun_e
+{
+ TFCSHOTGUN_IDLE = 0,
+ TFCSHOTGUN_SHOOT,
+ TFCSHOTGUN_SHOOT_BIG,
+ TFCSHOTGUN_RELOAD,
+ TFCSHOTGUN_PUMP,
+ TFCSHOTGUN_STARTRELOAD,
+ TFCSHOTGUN_DRAW,
+ TFCSHOTGUN_REHOLSTER,
+ TFCSHOTGUN_IDLE4,
+ TFCSHOTGUN_DEEPIDLE
+};
+
+void EV_FireTFCShotgun(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+ vec3_t angles;
+ vec3_t velocity;
+ vec3_t up, right, forward;
+
+ vec3_t ShellVelocity;
+ vec3_t ShellOrigin;
+ int shell;
+ vec3_t vecSrc, vecAiming;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ VectorCopy(args->velocity, velocity);
+
+ AngleVectors(angles, forward, right, up);
+
+ shell = gEngfuncs.pEventAPI->EV_FindModelIndex("models/shotgunshell.mdl");
+
+ EV_GetDefaultShellInfo(args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4);
+
+ if(EV_IsLocal(idx))
+ {
+ EV_MuzzleFlash();
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(TFCSHOTGUN_SHOOT, 2);
+ V_PunchAxis(0, -2.0);
+ }
+
+ EV_EjectBrass(ShellOrigin, ShellVelocity, angles.y, shell, TE_BOUNCE_SHELL);
+
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/sbarrel1.wav", gEngfuncs.pfnRandomFloat(0.95, 1.0), 0.8, 0, gEngfuncs.pfnRandomLong(0, 31) + 93);
+ EV_GetGunPosition(args, vecSrc, origin);
+ VectorCopy(forward, vecAiming);
+
+ EV_HLDM_FireBullets(idx, forward, right, up, 6, vecSrc, vecAiming, 2048.0, BULLET_PLAYER_BUCKSHOT, 0, tracerCount + idx, 0.04, 0.04);
+}
+
+void EV_ReloadTFCShotgun(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+ const char* sound;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(TFCSHOTGUN_RELOAD, 2);
+ if(gEngfuncs.pfnRandomLong(0, 1))
+ sound = "weapons/reload3.wav";
+
+ else
+ sound = "weapons/reload1.wav";
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, sound, 1.0, 0.8, 0, gEngfuncs.pfnRandomLong(0, 31) + 85);
+}
+
+void EV_PumpTFCShotgun(event_args_t *args)
+{
+ int full;
+ int idx;
+ vec3_t origin;
+
+ full = args->bparam1;
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ if(full && EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(TFCSHOTGUN_PUMP, 2);
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/scock1.wav", 1.0, 0.8, 0, gEngfuncs.pfnRandomLong(0, 31) + 95);
+}
+
+enum tfc_nailgun_e
+{
+ NAILGUN_LONGIDLE = 0,
+ NAILGUN_IDLE1,
+ NAILGUN_GRENADE,
+ NAILGUN_RELOAD,
+ NAILGUN_DEPLOY,
+ NAILGUN_SHOOT1,
+ NAILGUN_SHOOT2,
+ NAILGUN_SHOOT3
+};
+
+void EV_FireTFCNailgun(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+ vec3_t angles;
+ vec3_t velocity;
+ vec3_t up, right, forward;
+
+ vec3_t ShellVelocity;
+ vec3_t ShellOrigin;
+ int shell;
+ vec3_t vecSrc, vecAiming;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ VectorCopy(args->velocity, velocity);
+
+ AngleVectors(angles, forward, right, up);
+
+ shell = gEngfuncs.pEventAPI->EV_FindModelIndex("models/nail.mdl");
+
+ if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(NAILGUN_SHOOT1, 2);
+ EV_GetGunPosition(args, ShellOrigin, origin);
+ VectorMA(ShellOrigin, -4.0, up, ShellOrigin);
+ VectorMA(ShellOrigin, 2.0, right, ShellOrigin);
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/airgun_1.wav", gEngfuncs.pfnRandomFloat(0.95, 1.0), 0.8, 0, gEngfuncs.pfnRandomLong(0, 31) + 93);
+ VectorScale(forward, 1000.0, velocity);
+ gEngfuncs.pEfxAPI->R_Projectile(ShellOrigin, velocity, shell, 6, idx, EV_TFC_NailTouch);
+ if(EV_IsLocal(idx))
+ V_PunchAxis(0, -1.0);
+}
+
+void EV_TFC_NailTouch(struct tempent_s *ent, pmtrace_t *ptr)
+{
+ physent_t *pe;
+ char name;
+
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent(ptr->ent);
+ if(pe && (pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP))
+ {
+ sprintf(&name, "{shot%i", gEngfuncs.pfnRandomLong(0, 4) + 1);
+ if(name)
+ {
+ if (ptr->fraction != 1.0)
+ EV_HLDM_GunshotDecalTrace(ptr, &name);
+ }
+ }
+}
+
+void EV_FireTFCSuperNailgun(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+ vec3_t angles;
+ vec3_t velocity;
+ vec3_t up, right, forward;
+
+ vec3_t ShellVelocity;
+ vec3_t ShellOrigin;
+ int shell;
+ vec3_t vecSrc, vecAiming;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ VectorCopy(args->velocity, velocity);
+
+ AngleVectors(angles, forward, right, up);
+
+ shell = gEngfuncs.pEventAPI->EV_FindModelIndex("models/nail.mdl");
+
+ if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(NAILGUN_SHOOT1, 2);
+ EV_GetGunPosition(args, ShellOrigin, origin);
+ VectorMA(ShellOrigin, -4.0, up, ShellOrigin);
+ VectorMA(ShellOrigin, 2.0, right, ShellOrigin);
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/spike2.wav", 1.0, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ VectorScale(forward, 1000.0, velocity);
+ gEngfuncs.pEfxAPI->R_Projectile(ShellOrigin, velocity, shell, 6, idx, EV_TFC_NailTouch);
+ if(EV_IsLocal(idx))
+ V_PunchAxis(0, -1.0);
+}
+
+void EV_FireTFCSuperShotgun(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+ vec3_t angles;
+ vec3_t velocity;
+ vec3_t up, right, forward;
+
+ vec3_t ShellVelocity;
+ vec3_t ShellOrigin;
+ int shell;
+ vec3_t vecSrc, vecAiming;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ VectorCopy(args->velocity, velocity);
+
+ AngleVectors(angles, forward, right, up);
+
+ shell = gEngfuncs.pEventAPI->EV_FindModelIndex("models/shotgunshell.mdl");
+
+ EV_GetDefaultShellInfo(args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4);
+
+ if(EV_IsLocal(idx))
+ {
+ EV_MuzzleFlash();
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(TFCSHOTGUN_SHOOT, 2);
+ V_PunchAxis(0, -4.0);
+ }
+
+ EV_EjectBrass(ShellOrigin, ShellVelocity, angles.y, shell, TE_BOUNCE_SHELL);
+
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/shotgn2.wav", gEngfuncs.pfnRandomFloat(0.95, 1.0), 0.8, 0, gEngfuncs.pfnRandomLong(0, 31) + 93);
+ EV_GetGunPosition(args, vecSrc, origin);
+ VectorCopy(forward, vecAiming);
+
+ EV_HLDM_FireBullets(idx, forward, right, up, 14, vecSrc, vecAiming, 2048.0, BULLET_PLAYER_BUCKSHOT, 0, tracerCount + idx, 0.04, 0.04);
+}
+
+enum tfc_sniper_e
+{
+ SNIPER_IDLE = 0,
+ SNIPER_AIM,
+ SNIPER_FIRE,
+ SNIPER_DRAW,
+ SNIPER_HOLSTER,
+ SNIPER_AUTOIDLE,
+ SNIPER_AUTOFIRE,
+ SNIPER_AUTODRAW,
+ SBIPER_AUTOHOLSTER
+};
+
+void EV_FireTFCAutoRifle(event_args_t *args)
+{
+ int idx;
+ physent_s *pe;
+ pmtrace_t tr;
+
+ vec3_t origin;
+ vec3_t angles;
+ vec3_t up, right, forward;
+
+ vec3_t vecSrc, vecAiming, vecEnd;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ AngleVectors(angles, forward, right, up);
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(SNIPER_AUTOFIRE, 2);
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/sniper.wav", 0.9, 0.8, 0, 100);
+ EV_GetGunPosition(args, vecSrc, origin);
+ vecAiming = forward;
+ VectorMA(vecSrc, 8192.0, vecAiming, vecEnd);
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetSolidPlayers(idx - 1);
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr);
+
+ if ( tr.fraction != 1.0 )
+ {
+ if(gEngfuncs.pfnGetCvarFloat("cl_localblood") != 0.0)
+ EV_TFC_TraceAttack(idx, vecAiming, &tr, 8.0);
+ EV_HLDM_PlayTextureSound(idx, &tr, vecSrc, vecEnd, BULLET_PLAYER_357);
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent(tr.ent);
+ if(pe && (pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP))
+ EV_HLDM_DecalGunshot(&tr, BULLET_PLAYER_357);
+ }
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+}
+
+void EV_TFC_TraceAttack(int idx, float *vecDir, pmtrace_t *ptr, float flDamage)
+{
+ int index;
+ signed int iPlayer1;
+ signed int iPlayer2;
+ vec3_t dir;
+ vec3_t vecOrigin;
+
+ VectorScale(vecDir, -4.0, dir);
+ vecOrigin.x = (int)ptr + 20 - dir.x;
+ vecOrigin.y = (int)ptr + 24 - dir.y;
+ vecOrigin.z = (int)ptr + 28 - dir.z;
+ index = gEngfuncs.pEventAPI->EV_IndexFromTrace(ptr);
+ if(index > 0 && index <= gEngfuncs.GetMaxClients())
+ {
+ iPlayer2 = -1;
+ if(GetEntity(index))
+ iPlayer2 = GetEntity(index)->curstate.team;
+ }
+ if(idx > 0 && idx <= gEngfuncs.GetMaxClients())
+ {
+ iPlayer1 = -1;
+ if(GetEntity(idx))
+ iPlayer1 = GetEntity(idx)->curstate.team;
+ }
+ if ( iPlayer1 != iPlayer2 )
+ EV_TFC_BloodDrips(vecOrigin, (signed int)flDamage, vecOrigin.z);
+}
+
+void EV_TFC_BloodDrips(float *vecOrigin, signed int iDamage, long double height)
+{
+ int modelIndex;
+ int modelIndex2;
+ float scale;
+
+ if (gEngfuncs.pfnGetCvarFloat("violence_hblood") != 0.0 && iDamage > 0)
+ {
+ if (gEngfuncs.GetMaxClients() > 2)
+ iDamage *= 2;
+ if (iDamage > 255)
+ {
+ modelIndex = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/bloodspray.spr");
+ scale = 16.0;
+ modelIndex2 = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/blood.spr");
+ }
+ else
+ {
+ modelIndex = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/bloodspray.spr");
+ modelIndex2 = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/blood.spr");
+ if ( iDamage > 159 )
+ scale = 16.0;
+ else
+ {
+ scale = 3.0;
+ if ( iDamage > 29 )
+ scale = iDamage / 10;
+ }
+ }
+ gEngfuncs.pEfxAPI->R_BloodSprite(vecOrigin, 47, modelIndex, modelIndex2, scale);
+ }
+}
+
+enum tfc_assault_e
+{
+ ASSAULT_IDLE = 0,
+ ASSAULT_IDLE2,
+ ASSAULT_SPINUP,
+ ASSAULT_SPINDOWN,
+ ASSAULT_FIRE,
+ ASSAULT_DRAW,
+ ASSAULT_HOLSTER
+};
+
+void EV_TFC_Assault_WindUp(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ g_flSpinDownTime[idx - 1] = 0;
+ gEngfuncs.GetClientTime();
+ g_flSpinUpTime[idx - 1] = 0.0 + 3.5;
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(ASSAULT_SPINUP, 2);
+ g_bACSpinning[idx - 1] = 0;
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_STATIC, "weapons/asscan2.wav");
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_STATIC, "weapons/asscan4.wav");
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_WEAPON, "weapons/asscan3.wav");
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/asscan1.wav", 0.98, 0.8, 0, 125);
+}
+
+void EV_TFC_Assault_WindDown(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ if(g_flSpinUpTime[idx - 1] == 0.0)
+ {
+ gEngfuncs.GetClientTime();
+ g_flSpinDownTime[idx - 1] = 0.0 + 3.0;
+ if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(ASSAULT_SPINDOWN, 2);
+ }
+ else if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(ASSAULT_SPINDOWN, 2);
+
+ g_bACSpinning[idx - 1] = 0;
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_STATIC, "weapons/asscan2.wav");
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_STATIC, "weapons/asscan4.wav");
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_WEAPON, "weapons/asscan1.wav");
+ if(!args->bparam1)
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/asscan3.wav", 0.98, 0.8, 0, 125);
+}
+
+void EV_TFC_Assault_Start(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ g_flSpinDownTime[idx - 1] = 0;
+ g_flSpinUpTime[idx - 1] = 0;
+ g_bACSpinning[idx - 1] = 0;
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_STATIC, "weapons/asscan2.wav");
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_STATIC, "weapons/asscan4.wav");
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_STATIC, "weapons/asscan3.wav", 0.98, 0.8, 0, 125);
+}
+
+void EV_TFC_Assault_Fire(event_args_t *args)
+{
+ int idx;
+ int oddammo;
+ int shell;
+ vec3_t ShellOrigin, ShellVelocity;
+ vec3_t up, right, forward;
+ vec3_t vecSrc, vecAiming;
+ vec3_t origin, angles, velocity;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ VectorCopy(args->velocity, velocity);
+ oddammo = args->bparam1;
+ shell = gEngfuncs.pEventAPI->EV_FindModelIndex("models/shell.mdl");
+ gEngfuncs.pfnAngleVectors(angles, forward, right, up);
+ if(EV_IsLocal(idx))
+ {
+ EV_MuzzleFlash();
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(ASSAULT_FIRE, 2);
+ }
+ g_bACSpinning[idx - 1] = 0;
+ if(oddammo)
+ {
+ EV_GetDefaultShellInfo(args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 15.0, -25.0, 6.0);
+ EV_EjectBrass(ShellOrigin, ShellVelocity, angles.y, shell, TE_BOUNCE_SHELL);
+ }
+ EV_GetGunPosition(args, vecSrc, origin);
+ vecAiming = forward;
+ vecSrc.x = right.x + right.x + up.x * -4.0 + vecSrc.x;
+ vecSrc.y = right.y + right.y + up.y * -4.0 + vecSrc.y;
+ vecSrc.z = right.z + right.z + -4.0 * up.z + vecSrc.z;
+ EV_HLDM_FireBullets(idx, forward, right, up, 5, vecSrc, vecAiming, 0.1, 8192.0, BULLET_MONSTER_MP5, &tracerCount[idx - 1], 1.0, 8.0);
+}
+
+void EV_TFC_Assault_Spin(event_args_t *args)
+{
+ int idx;
+
+ idx = args->entindex;
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(ASSAULT_FIRE, 2);
+ g_bACSpinning[idx - 1] = 1;
+}
+
+void EV_TFC_Assault_StartSpin(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ g_bACSpinning[idx - 1] = 1;
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_STATIC, "weapons/asscan2.wav");
+ gEngfuncs.pEventAPI->EV_StopSound(idx, CHAN_STATIC, "weapons/asscan4.wav");
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_STATIC, "weapons/asscan4.wav", 0.98, 0.8, 0, 125);
+}
+
+void EV_TFC_Gas(event_args_t *args)
+{
+ vec3_t origin;
+ VectorCopy(args->origin, origin);
+ gEngfuncs.pEfxAPI->R_ParticleBurst(origin, 240, 195, 2.0);
+}
+
+void EV_TFC_DoorGoUp(event_args_t *args)
+{
+ int index;
+ char sound[255];
+ char num;
+
+ index = args->iparam1;
+ num = (char)index;
+
+ sprintf(sound,"doors/doormove%d.wav", num);
+ gEngfuncs.pEventAPI->EV_StopSound(-1, CHAN_STATIC, sound);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, args->origin, CHAN_STATIC, sound, 1.0, 1.0, 0, 100);
+}
+
+void EV_TFC_DoorGoDown(event_args_t *args)
+{
+ int index;
+ char sound[255];
+ char num;
+
+ index = args->iparam1;
+ num = (char)index;
+
+ sprintf(sound,"doors/doormove%d.wav", num);
+ gEngfuncs.pEventAPI->EV_StopSound(-1, CHAN_STATIC, sound);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, args->origin, CHAN_STATIC, sound, 1.0, 1.0, 0, 100);
+}
+
+void EV_TFC_DoorHitTop(event_args_t *args)
+{
+ int index;
+ char sound[255];
+ char num;
+
+ index = args->iparam1;
+ num = (char)index;
+
+ sprintf(sound,"doors/doormove%d.wav", num);
+ gEngfuncs.pEventAPI->EV_StopSound(-1, CHAN_STATIC, sound);
+ sound[255];
+ sprintf(sound,"doors/doorstop%d.wav", num);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, args->origin, CHAN_STATIC, sound, 1.0, 1.0, 0, 100);
+}
+
+void EV_TFC_DoorHitBottom(event_args_t *args)
+{
+ int index;
+ char sound[255];
+ char num;
+
+ index = args->iparam1;
+ num = (char)index;
+
+ sprintf(sound,"doors/doormove%d.wav", num);
+ gEngfuncs.pEventAPI->EV_StopSound(-1, CHAN_STATIC, sound);
+ sound[255];
+ sprintf(sound,"doors/doorstop%d.wav", num);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, args->origin, CHAN_STATIC, sound, 1.0, 1.0, 0, 100);
+}
+
+void EV_TFC_Explode(float *org, int dmg, pmtrace_t *pTrace, qboolean bDontSpark)
+{
+ int pc;
+ bool outside;
+ int explosion;
+ float exp_scale;
+ float veca, vecb;
+ int fireball;
+ int decalindex;
+ physent_s *pe;
+ const char *vecc;
+ int explosion_outside;
+ int damage;
+ vec3_t origin;
+ float fExplosionScale;
+
+ VectorCopy(org, origin);
+
+ if(pTrace->fraction != 1.0)
+ {
+ if(dmg <= 23)
+ damage = dmg;
+ else
+ damage = dmg - 24;
+ fireball = (float)damage * 0.6;
+ VectorMA(pTrace->endpos, fireball, pTrace->plane.normal, origin);
+ }
+ pc = gEngfuncs.PM_PointContents(origin, 0);
+ if (pc != CONTENTS_SOLID)
+ {
+ outside = pc != -3;
+ explosion_outside = 0;
+ }
+ else
+ {
+ outside = 1;
+ explosion_outside = 1;
+ }
+ fExplosionScale = (float)(dmg - 50) * 0.6;
+ explosion = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/explode01.spr");
+ exp_scale = 0.1 * fExplosionScale;
+ vecb = exp_scale;
+ gEngfuncs.pEfxAPI->R_Explosion(origin, explosion, vecb, 15, 3);
+ if ( !explosion_outside )
+ {
+ veca = pTrace->ent;
+ if(gEngfuncs.pfnRandomFloat(0, 1.0) >= 0.5)
+ {
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent((int)veca);
+ if(pe && (pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP))
+ if(gEngfuncs.pfnGetCvarFloat("r_decals") != 0.0)
+ decalindex = gEngfuncs.pEfxAPI->Draw_DecalIndexFromName("{scorch2");
+ }
+ else
+ {
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent((int)veca);
+ if(pe && (pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP))
+ if ( exp_scale != 0.0 )
+ decalindex = gEngfuncs.pEfxAPI->Draw_DecalIndexFromName("{scorch1");
+ }
+ gEngfuncs.pEfxAPI->R_DecalShoot(gEngfuncs.pEfxAPI->Draw_DecalIndex(decalindex), gEngfuncs.pEventAPI->EV_IndexFromTrace(pTrace), 0, pTrace->endpos, 0);
+ }
+ long rand = gEngfuncs.pfnRandomLong(0, 2);
+ if(rand == 1)
+ vecc = "weapons/debris2.wav";
+ if(rand == 2)
+ vecc = "weapons/debris3.wav";
+ if(!rand)
+ vecc = "weapons/debris1.wav";
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_VOICE, vecc, 0.55, 0.8, 0, 100);
+
+ if ( outside && !bDontSpark )
+ {
+ long rand2 = gEngfuncs.pfnRandomLong(0, 3);
+ if ( rand2 > 0 )
+ for(int x = 0; x < rand2; x++)
+ gEngfuncs.pEfxAPI->R_SparkShower(origin);
+ }
+}
+
+void EV_TFC_Explosion(event_args_t *args)
+{
+ pmtrace_t tr;
+ vec3_t vecEnd;
+ vec3_t vecSpot;
+ vec3_t origin;
+
+ VectorCopy(args->origin, origin);
+ vecSpot.x = origin.x;
+ vecSpot.y = origin.y;
+ vecSpot.z = origin.z + 8.0;
+ vecEnd.x = origin.x;
+ vecEnd.y = origin.y;
+ vecEnd.z = origin.z + 8.0 - 40.0;
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSpot, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ EV_TFC_Explode(origin, 120, &tr, 0.0);
+}
+
+void EV_TFC_Grenade(event_args_t *args)
+{
+ pmtrace_t tr;
+ vec3_t vecEnd;
+ vec3_t vecSpot;
+ vec3_t origin;
+
+ VectorCopy(args->origin, origin);
+ vecSpot.x = origin.x;
+ vecSpot.y = origin.y;
+ vecSpot.z = origin.z + 8.0;
+ vecEnd.x = origin.x;
+ vecEnd.y = origin.y;
+ vecEnd.z = origin.z + 8.0 - 40.0;
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSpot, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ EV_TFC_Explode(origin, 120, &tr, 0.0);
+}
+
+void EV_TFC_NormalGrenade(event_args_t *args)
+{
+ pmtrace_t tr;
+ vec3_t vecEnd;
+ vec3_t vecSpot;
+ vec3_t origin;
+
+ VectorCopy(args->origin, origin);
+ vecSpot.x = origin.x;
+ vecSpot.y = origin.y;
+ vecSpot.z = origin.z + 8.0;
+ vecEnd.x = origin.x;
+ vecEnd.y = origin.y;
+ vecEnd.z = origin.z + 8.0 - 40.0;
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSpot, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ EV_TFC_Explode(origin, 180, &tr, 0.0);
+}
+
+enum tfc_tfcrpg_e
+{
+ TFCRPG_IDLE = 0,
+ TFCRPG_FIDGET,
+ TFCRPG_FIRE,
+ TFCRPG_HOLSTER1,
+ TFCRPG_DRAW1,
+ TFCRPG_HOLSTER2,
+ TFCRPG_DRAW2,
+ TFCRPG_RELSTART,
+ TFCRPG_RELCYCLE,
+ TFCRPG_RELEND,
+ TFCRPG_IDLE2,
+ TFCRPG_FIDGET2
+};
+
+void EV_TFC_FireRPG(event_args_t *args)
+{
+ int idx;
+ vec_t v2;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+
+ if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(TFCRPG_FIRE, 2);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/rocketfire1.wav", 0.9, 0.8, 0, 100);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/glauncher.wav", 0.7, 0.8, 0, 100);
+ if(EV_IsLocal(idx))
+ V_PunchAxis(0, -5.0);
+}
+
+void EV_FireTFCSniper(event_args_t *args)
+{
+ int idx;
+ physent_s *pe;
+ pmtrace_t tr;
+ int iDamage;
+
+ vec3_t origin;
+ vec3_t angles;
+ vec3_t up, right, forward;
+
+ vec3_t vecSrc, vecDir, vecEnd;
+
+ idx = args->entindex;
+ iDamage = args->iparam1;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ AngleVectors(angles, forward, right, up);
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(SNIPER_FIRE, 2);
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "ambience/rifle1.wav", 0.9, 0.8, 0, 100);
+ EV_GetGunPosition(args, vecSrc, origin);
+ vecDir = forward;
+ VectorMA(vecSrc, 2.0, up, vecSrc);
+ VectorMA(vecSrc, 8192.0, vecDir, vecEnd);
+ gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction(false, true);
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetSolidPlayers(idx - 1);
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSrc, vecEnd, PM_STUDIO_BOX, -1, (pmtrace_s*)&up);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+
+ if ( tr.fraction != 1.0 )
+ {
+ if(gEngfuncs.pfnGetCvarFloat("cl_localblood") != 0.0)
+ EV_TFC_TraceAttack(idx, vecDir, &tr, iDamage);
+ EV_HLDM_PlayTextureSound(idx, &tr, vecSrc, vecEnd, BULLET_PLAYER_357);
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent(tr.ent);
+ if(pe && (pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP))
+ EV_HLDM_DecalGunshot(&tr, BULLET_PLAYER_357);
+ }
+}
+
+
+void EV_TFC_SniperHit(event_args_s *args)
+{
+ int idx;
+ float volume;
+ char *sound;
+ vec3_t origin;
+
+ VectorCopy(args->origin, origin);
+ idx = args->entindex;
+ volume = (float)args->iparam1 / 100.0;
+ if (args->bparam2)
+ {
+ sound = "common/bodysplat.wav";
+ volume = 1.0;
+ }
+ else if (args->bparam1)
+ sound = "weapons/bullet_hit2.wav";
+ else
+ sound = "weapons/bullet_hit1.wav";
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_STATIC, sound, volume, 0.8, 0, 100);
+}
+
+void EV_TFC_FireIC(event_args_t *args)
+{
+ int idx;
+ vec_t v2;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+
+ if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(3, 2);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/sgun1.wav", 0.9, 0.8, 0, 100);
+ if(EV_IsLocal(idx))
+ V_PunchAxis(0, -5.0);
+}
+
+void EV_TFC_NailgrenadeNail(event_args_t *args)
+{
+ int nail;
+ vec3_t origin, angles, forward, velocity, org;
+
+ angles.x = 0;
+ angles.z = 0;
+ angles.y = (float)(args->iparam1 & 2047) * 0.25;
+ VectorCopy(args->origin, org);
+ nail = gEngfuncs.pEventAPI->EV_FindModelIndex("models/nail.mdl");
+ angles.y = anglemod(args->fparam1 + angles.y);
+ gEngfuncs.pfnAngleVectors(angles, forward, 0, 0);
+ VectorMA(org, 12.0, forward, origin);
+ VectorScale(forward, 1000.0, velocity);
+ gEngfuncs.pEfxAPI->R_Projectile(origin, velocity, nail, 6, (args->iparam1 >> 11) & 31, EV_TFC_NailTouch);
+ if(!gEngfuncs.pfnRandomLong(0, 5))
+ {
+ if (gEngfuncs.pfnRandomLong(0, 1) == 0)
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/airgun_1.wav", 1, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ else
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/spike2.wav", 1, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ }
+ angles.y = anglemod(args->fparam1 + angles.y);
+ gEngfuncs.pfnAngleVectors(angles, forward, 0, 0);
+ VectorMA(org, 12.0, forward, origin);
+ VectorScale(forward, 1000.0, velocity);
+ gEngfuncs.pEfxAPI->R_Projectile(origin, velocity, nail, 6, (args->iparam1 >> 11) & 31, EV_TFC_NailTouch);
+ if(!gEngfuncs.pfnRandomLong(0, 5))
+ {
+ if (gEngfuncs.pfnRandomLong(0, 1) == 0)
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/airgun_1.wav", 1, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ else
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/spike2.wav", 1, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ }
+ angles.y = anglemod(args->fparam1 + angles.y);
+ gEngfuncs.pfnAngleVectors(angles, forward, 0, 0);
+ VectorMA(org, 12.0, forward, origin);
+ VectorScale(forward, 1000.0, velocity);
+ gEngfuncs.pEfxAPI->R_Projectile(origin, velocity, nail, 6, (args->iparam1 >> 11) & 31, EV_TFC_NailTouch);
+ if(!gEngfuncs.pfnRandomLong(0, 5))
+ {
+ if (gEngfuncs.pfnRandomLong(0, 1) == 0)
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/airgun_1.wav", 1, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ else
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/spike2.wav", 1, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ }
+ angles.y = anglemod(args->fparam1 + angles.y);
+ gEngfuncs.pfnAngleVectors(angles, forward, 0, 0);
+ VectorMA(org, 12.0, forward, origin);
+ VectorScale(forward, 1000.0, velocity);
+ gEngfuncs.pEfxAPI->R_Projectile(origin, velocity, nail, 6, (args->iparam1 >> 11) & 31, EV_TFC_NailTouch);
+ if(!gEngfuncs.pfnRandomLong(0, 5))
+ {
+ if (gEngfuncs.pfnRandomLong(0, 1) == 0)
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/airgun_1.wav", 1, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ else
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/spike2.wav", 1, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ }
+}
+
+enum tfc_grenadelauncher_e
+{
+ TFGL_IDLE = 0,
+ TFPL_IDLE,
+ TFGL_FIRE,
+ TFPL_FIRE,
+ TFGL_RELOAD1,
+ TFGL_RELOAD2,
+ TFPL_RELOAD1,
+ TFPL_RELOAD2,
+ TFGL_DRAW,
+ TFPL_DRAW,
+ TFGL_HOLSTER,
+ TFPL_HOLSTER
+};
+
+void EV_TFC_GrenadeLauncher(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(TFGL_FIRE, 2);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/glauncher.wav", 0.7, 0.8, 0, 100);
+ if(EV_IsLocal(idx))
+ V_PunchAxis(0, -2.0);
+}
+
+void EV_TFC_PipeLauncher(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(TFPL_FIRE, 2);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_WEAPON, "weapons/glauncher.wav", 0.7, 0.8, 0, 100);
+ if(EV_IsLocal(idx))
+ V_PunchAxis(0, -2.0);
+}
+
+void EV_TFC_NormalShot(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_ITEM, "items/medshot4.wav", 1, 0.8, 0, 100);
+}
+
+
+void EV_TFC_SuperShot(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_ITEM, "items/medshot5.wav", 1, 0.8, 0, 100);
+}
+
+void EV_TFC_SteamShot(event_args_t *args)
+{
+ int idx;
+ vec3_t origin;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_ITEM, "ambience/steamburst1.wav", 1, 0.8, 0, 100);
+}
+
+void EV_TFC_AxeDecal(event_args_t *args)
+{
+ int idx;
+ pmtrace_t *tr;
+ physent_s *pe;
+
+ idx = args->entindex;
+ tr = gp_tr_decal[idx-1];
+ if (tr)
+ {
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent(tr->ent);
+ if ( pe && (pe->solid == 4 || pe->movetype == 13) )
+ EV_HLDM_DecalGunshot(tr, BULLET_PLAYER_CROWBAR);
+ tr = 0;
+ }
+}
+
+void EV_TFC_EngineerGrenade(event_args_t *args)
+{
+ pmtrace_t tr;
+ vec3_t vecEnd;
+ vec3_t vecSpot;
+ vec3_t origin;
+
+ VectorCopy(args->origin, origin);
+ vecSpot.x = origin.x;
+ vecSpot.y = origin.y;
+ vecSpot.z = origin.z + 8.0;
+ vecEnd.x = origin.x;
+ vecEnd.y = origin.y;
+ vecEnd.z = origin.z + 8.0 - 40.0;
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSpot, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ EV_TFC_Explode(origin, 180, &tr, 1.0);
+}
+
+void EV_TFC_Concussion(event_args_t *args)
+{
+ int wave;
+ long rand;
+ const char *sound;
+ pmtrace_t tr;
+ vec3_t vecEnd, vecSpot, origin;
+
+ VectorCopy(args->origin, origin)
+ wave = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/shockwave.spr");
+ vecSpot.x = origin.x;
+ vecSpot.y = origin.y;
+ vecSpot.z = origin.z + 8.0;
+ vecEnd.x = origin.x;
+ vecEnd.y = origin.y;
+ vecEnd.z = origin.z + 8.0 - 40.0;
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSpot, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ rand = gEngfuncs.pfnRandomLong(0, 2);
+ if(rand == 1)
+ sound = "weapons/concgren_blast2.wav";
+ if(rand == 2)
+ sound = "weapons/concgren_blast3.wav";
+ if (rand = 0)
+ sound = "weapons/concgren_blast1.wav";
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_VOICE, sound, 1, 0.8, 0, 100);
+ vecSpot.z = origin.z + 16.0;
+ vecEnd.z = origin.z + 16.0 + 600.0;
+ gEngfuncs.pEfxAPI->R_BeamCirclePoints(21, vecSpot, vecEnd, wave, 0.2, 70, 0, 1.0, 0, 0, 0, 1.0, 1.0, 1.0);
+}
+
+void EV_TFC_MirvGrenadeMain(event_args_t *args)
+{
+ EV_TFC_NormalGrenade(args);
+}
+
+void EV_TFC_MirvGrenade(event_args_t *args)
+{
+ EV_TFC_NormalGrenade(args);
+}
+
+void EV_TFC_NapalmFire(event_args_t *args)
+{
+ int explosion;
+ physent_s *pe;
+ int decalindex;
+ int decal;
+ const char *sound;
+ pmtrace_t tr;
+ vec3_t origin, vecSpot, vecEnd;
+ vec3_t org;
+
+ VectorCopy(args->origin, origin)
+ vecSpot.x = origin.x;
+ vecSpot.y = origin.y;
+ vecSpot.z = origin.z + 8.0;
+ vecEnd.x = origin.x;
+ vecEnd.y = origin.y;
+ vecEnd.z = origin.z + 8.0 - 40.0;
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSpot, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ if(tr.fraction != 1.0)
+ VectorMA(tr.endpos, 12.0, tr.plane.normal, org);
+ if(gEngfuncs.PM_PointContents(org, 0) == CONTENTS_SOLID && gEngfuncs.PM_PointContents(origin, 0) == CONTENTS_SOLID)
+ return;
+ explosion = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/explode01.spr");
+ gEngfuncs.pEfxAPI->R_Explosion(org, explosion, 3, 15, 3);
+ if(gEngfuncs.pfnRandomFloat(0, 1.0) < 0.5)
+ {
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent(tr.ent);
+ if(pe && (pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP))
+ if(gEngfuncs.pfnGetCvarFloat("r_decals") != 0.0)
+ decalindex = gEngfuncs.pEfxAPI->Draw_DecalIndexFromName("{scorch1");
+ }
+ else
+ {
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent(tr.ent);
+ if(pe && (pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP))
+ if(gEngfuncs.pfnGetCvarFloat("r_decals") != 0.0)
+ decalindex = gEngfuncs.pEfxAPI->Draw_DecalIndexFromName("{scorch2");
+ }
+ if(decalindex != 0)
+ {
+ decal = gEngfuncs.pEfxAPI->Draw_DecalIndex(decalindex);
+ gEngfuncs.pEfxAPI->R_DecalShoot(decal, gEngfuncs.pEventAPI->EV_IndexFromTrace(&tr), 0, tr.endpos, 0);
+ }
+
+ switch(gEngfuncs.pfnRandomLong(0, 2))
+ {
+ case 0:
+ sound = "weapons/debris1.wav";
+ break;
+ case 1:
+ sound = "weapons/debris2.wav";
+ break;
+ case 2:
+ sound = "weapons/debris3.wav";
+ break;
+ }
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_VOICE, sound, 0.55, 0.8, 0, 100);
+}
+
+void EV_TFC_NapalmBurn(event_args_t *args)
+{
+ int sprite;
+ vec3_t origin;
+
+ VectorCopy(args->origin, origin);
+ sprite = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/playerflame.spr");
+ gEngfuncs.pEfxAPI->R_FireField(origin, 100, sprite, 12, 18, 0.8);
+}
+
+void EV_TFC_EMP(event_args_t *args)
+{
+ int sprite;
+ pmtrace_t tr;
+ vec3_t origin, vecSpot, vecEnd;
+
+ sprite = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/shockwave.spr");
+ VectorCopy(args->origin, origin)
+ vecSpot.x = origin.x;
+ vecSpot.y = origin.y;
+ vecSpot.z = origin.z + 8.0;
+ vecEnd.x = origin.x;
+ vecEnd.y = origin.y;
+ vecEnd.z = origin.z + 8.0 - 40.0;
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSpot, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ gEngfuncs.pEventAPI->EV_PlaySound(-1, origin, CHAN_VOICE, "weapons/emp_1.wav", 1.0, 0.8, 0, 100);
+ vecSpot.z = origin.z + 16.0;
+ vecEnd.z = origin.z + 16.0 + 600.0;
+ gEngfuncs.pEfxAPI->R_BeamCirclePoints(21, vecSpot, vecEnd, sprite, 0.2, 70, 0, 1.0, 0, 0, 0, 1.0, 1.0, 0.0);
+}
+
+void EV_TFC_Flame_Fire(event_args_t *args)
+{
+ int idx;
+ float height;
+ long double height2;
+ int underwater;
+ int shell;
+ int bubble;
+ vec3_t ShellOrigin, BubbleSpot, up, right, forward, vecVelocity, origin, angles;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ underwater = args->bparam1;
+ shell = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/fthrow.spr");
+ bubble = gEngfuncs.pEventAPI->EV_FindModelIndex("sprites/bubble.spr");
+ gEngfuncs.pfnAngleVectors(angles, forward, right, up);
+ if(EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(5, 2);
+ EV_GetGunPosition(args, ShellOrigin, origin);
+ VectorMA(ShellOrigin, -8.0, up, ShellOrigin);
+ VectorMA(ShellOrigin, 8.0, right, ShellOrigin);
+ VectorMA(ShellOrigin, 16.0, forward, ShellOrigin);
+ if (!underwater)
+ {
+ VectorScale(forward, 600.0, vecVelocity);
+ gEngfuncs.pEfxAPI->R_Projectile(ShellOrigin, vecVelocity, shell, 1, idx, 0);
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/flmfire2.wav", 0.9, 0.8, 0, 100);
+ return;
+ }
+ VectorMA(ShellOrigin, 128.0, forward, BubbleSpot);
+ height = EV_TFC_WaterLevel(ShellOrigin, ShellOrigin.z, ShellOrigin.z + 256.0);
+ if(height >= 8.0)
+ {
+ gEngfuncs.pEfxAPI->R_BubbleTrail(ShellOrigin, BubbleSpot, EV_TFC_WaterLevel(ShellOrigin, ShellOrigin.z, ShellOrigin.z + 256.0) - ShellOrigin.z, bubble, 4, 8.0);
+ return;
+ }
+ height2 = EV_TFC_WaterLevel(BubbleSpot, BubbleSpot.z, BubbleSpot.z + 256.0) - BubbleSpot.z;
+ if (height2 >= 8.0)
+ {
+ height = height2 + BubbleSpot.z - ShellOrigin.z;
+ gEngfuncs.pEfxAPI->R_BubbleTrail(ShellOrigin, BubbleSpot, EV_TFC_WaterLevel(ShellOrigin, ShellOrigin.z, ShellOrigin.z + 256.0) - ShellOrigin.z, bubble, 4, 8.0);
+ return;
+ }
+}
+
+long double EV_TFC_WaterLevel(float *position, float minz, float maxz)
+{
+ long double result;
+ long double dif;
+ long double dif2;
+ float diff;
+ float minz_1;
+
+ minz_1 = minz;
+ result = minz;
+ if(gEngfuncs.PM_PointContents(position, 0) == -3 )
+ {
+ minz_1 = maxz;
+ if(gEngfuncs.PM_PointContents(position, 0) == -3 )
+ result = maxz;
+ }
+ else
+ {
+ diff = minz;
+ dif = maxz - minz;
+ if(dif > 1.0)
+ {
+ while(1)
+ {
+ minz_1 = dif * 0.5 + diff;
+ if(gEngfuncs.PM_PointContents(position, 0) == -3)
+ {
+ result = minz_1;
+ diff = minz_1;
+ }
+ else
+ {
+ result = minz_1;
+ maxz = minz_1;
+ }
+ dif2 = maxz - diff;
+ if (dif2 <= 1.0)
+ break;
+ dif = dif2;
+ }
+ }
+ else
+ result = minz_1;
+ }
+ return result;
+}
+
+void EV_TFC_Railgun(event_args_t *args)
+{
+ int idx;
+ pmtrace_t tr;
+ vec3_t ShellOrigin, vecSrc, vecEnd, tracerVelocity, right, up, forward, delta, origin, angles;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ gEngfuncs.pfnAngleVectors(angles, forward, right, up);
+ gEngfuncs.pEventAPI->EV_FindModelIndex("models/nail.mdl");
+ if(EV_IsLocal(idx))
+ {
+ EV_MuzzleFlash();
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(1, 2);
+ }
+ EV_GetGunPosition(args, ShellOrigin, origin);
+ VectorMA(ShellOrigin, -4.0, up, ShellOrigin);
+ VectorMA(ShellOrigin, 2.0, right, ShellOrigin);
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/railgun.wav", 0.9, 0.8, 0, 100);
+ vecSrc = ShellOrigin;
+ VectorMA(vecSrc, 4096.0, forward, vecEnd);
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetSolidPlayers(idx - 1);
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ delta.x = tr.endpos.x - vecSrc.x;
+ delta.y = tr.endpos.y - vecSrc.y;
+ delta.z = tr.endpos.z - vecSrc.z;
+ VectorScale(forward, 1500.0, tracerVelocity);
+ gEngfuncs.pEfxAPI->R_UserTracerParticle(ShellOrigin, tracerVelocity, Length(delta) / 1500.0, 2, 1.0, idx, EV_TFC_RailDie);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ if(EV_IsLocal(idx))
+ V_PunchAxis(0, -2.0);
+}
+
+void EV_TFC_RailDie(particle_s *particle)
+{
+ physent_s *pe;
+ int idx2;
+ pmtrace_t tr;
+ char decalname[32];
+ vec3_t forward, back, vecSrc, vecEnd;
+
+ if (particle)
+ {
+ forward.x = particle->vel.x;
+ forward.y = particle->vel.y;
+ forward.z = particle->vel.z;
+ VectorNormalize(forward);
+ back = forward;
+ VectorInverse(back);
+ VectorMA(particle->org, 128.0, back, vecSrc);
+ VectorMA(vecSrc, 256.0, forward, vecEnd);
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetSolidPlayers(particle->context - 1);
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ if(tr.ent != -1)
+ {
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent(tr.ent);
+ idx2 = gEngfuncs.pEventAPI->EV_IndexFromTrace(&tr);
+ if(!EV_IsPlayer(idx2) || EV_TFC_IsAlly(gEngfuncs.pEventAPI->EV_IndexFromTrace(&tr), particle->context))
+ {
+ if(pe && (pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP))
+ {
+ decalname[0] = 0;
+ sprintf(decalname, "{shot%i", gEngfuncs.pfnRandomLong(0, 4) + 1);
+ if(decalname[0])
+ {
+ if(tr.fraction != 1.0)
+ EV_HLDM_GunshotDecalTrace(&tr, decalname);
+ }
+ }
+ }
+ else if (gEngfuncs.pfnGetCvarFloat("cl_localblood") != 0.0)
+ {
+ EV_TFC_BloodDrips(tr.endpos, 25, 0.0);
+ }
+ }
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ }
+}
+
+int EV_TFC_IsAlly(int idx1, int idx2)
+{
+ bool err;
+ signed int iPlayer1;
+ signed int iPlayer2;
+ int result;
+ long v10;
+ if (idx1 > 0 && idx1 <= gEngfuncs.GetMaxClients() && GetEntity(idx1) != 0 )
+ {
+ iPlayer1 = GetEntity(idx1)->curstate.team;
+ err = iPlayer1 == -1;
+ }
+ else
+ {
+ err = 1;
+ iPlayer1 = -1;
+ }
+ if (idx1 < 0 || idx1 > gEngfuncs.GetMaxClients() || GetEntity(idx1) == 0 )
+ return 0;
+ iPlayer2 = GetEntity(idx2)->curstate.team;
+ if(iPlayer2 == -1 || err || !iPlayer2 || !iPlayer1)
+ return 0;
+ result = 0;
+ if (!gEngfuncs.GetLocalPlayer())
+ return result;
+ if(iPlayer2 > 4 || iPlayer2 > 4)
+ return 0;
+ v10 = strtol(gEngfuncs.PhysInfo_ValueForKey("ta"), 0, 10);
+ result = 1;
+ if (!(((v10 & 0x1F) + iPlayer1) >> (iPlayer2 - 1) & 1));
+ result = iPlayer1 == iPlayer2;
+ return result;
+}
+
+void EV_TFC_Tranquilizer(event_args_t *args)
+{
+ int idx;
+ int shell;
+ vec3_t ShellOrigin, vecVelocity, right, up, forward, origin, angles;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin);
+ VectorCopy(args->angles, angles);
+ gEngfuncs.pfnAngleVectors(angles, forward, right, up);
+ shell = gEngfuncs.pEventAPI->EV_FindModelIndex("models/nail.mdl");
+ if(EV_IsLocal(idx))
+ {
+ EV_MuzzleFlash();
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(3, 1);
+ }
+ EV_GetGunPosition(args, ShellOrigin, origin);
+ VectorMA(ShellOrigin, -4.0, up, ShellOrigin);
+ VectorMA(ShellOrigin, 2.0, right, ShellOrigin);
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/dartgun.wav", 0.9, 0.8, 0, 100);
+ VectorScale(forward, 1500.0, vecVelocity);
+ gEngfuncs.pEfxAPI->R_Projectile(ShellOrigin, vecVelocity, shell, 6, idx, EV_TFC_TranqNailTouch);
+ if(EV_IsLocal(idx))
+ V_PunchAxis(0, -2.0);
+}
+
+void EV_TFC_TranqNailTouch(tempent_s *ent, pmtrace_t *ptr)
+{
+ physent_s *pe;
+ char decalname[32];
+
+ if(gEngfuncs.pEventAPI->EV_IndexFromTrace(ptr) > 0 && gEngfuncs.pEventAPI->EV_IndexFromTrace(ptr) <= gEngfuncs.GetMaxClients() )
+ {
+ decalname[0] = 0;
+ sprintf(decalname, "{shot%i", gEngfuncs.pfnRandomLong(0, 4) + 1);
+ }
+ else
+ {
+ decalname[0] = 0;
+ sprintf(decalname, "{shot%i", gEngfuncs.pfnRandomLong(0, 4) + 1);
+ pe = gEngfuncs.pEventAPI->EV_GetPhysent(ptr->ent);
+ if(pe && (pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP))
+ {
+ if (decalname[0])
+ {
+ if(ptr->fraction != 1.0)
+ EV_HLDM_GunshotDecalTrace(ptr, decalname);
+ }
+ }
+ }
+}
+
+
+void EV_TFC_NailGrenade(event_args_t *args)
+{
+ pmtrace_t tr;
+ vec3_t vecEnd, vecSpot, origin;
+
+ VectorCopy(args->origin, origin)
+ vecSpot.x = origin.x;
+ vecSpot.y = origin.y;
+ vecSpot.z = origin.z + 8.0;
+ vecEnd.x = origin.x;
+ vecEnd.y = origin.y;
+ vecEnd.z = origin.z + 8.0 - 40.0;
+ gEngfuncs.pEventAPI->EV_PushPMStates();
+ gEngfuncs.pEventAPI->EV_SetTraceHull(2);
+ gEngfuncs.pEventAPI->EV_PlayerTrace(vecSpot, vecEnd, PM_STUDIO_BOX, -1, &tr);
+ gEngfuncs.pEventAPI->EV_PopPMStates();
+ EV_TFC_Explode(origin, 180, &tr, 78);
+}
+
+void EV_TFC_Gibs(event_args_t *args)
+{
+ int idx;
+ int multiplier;
+ vec3_t origin, attackdir;
+
+ idx = args->entindex;
+ VectorCopy(args->origin, origin)
+ VectorCopy(args->angles, attackdir)
+ multiplier = args->iparam1;
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "common/bodysplat.wav", 1.0, 0.8, 0, 100);
+// for(int x = 0; x < 6; x++)
+// EV_TFC_CreateGib(origin, attackdir, multiplier, 0);
+// EV_TFC_CreateGib(origin, attackdir, multiplier, 1);
+}
+
+void EV_TFC_PlayAxeSound(int idx, int classid, float *origin, int iSoundType, float fSoundData)
+{
+ if(classid == 2)
+ return;
+
+ switch(iSoundType)
+ {
+ case 1:
+ {
+ switch(gEngfuncs.pfnRandomLong(0, 2))
+ {
+ case 1:
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/cbar_hitbod2.wav", 1.0, 0.8, 0, 100);
+ case 2:
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/cbar_hitbod3.wav", 1.0, 0.8, 0, 100);
+ default:
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/cbar_hitbod1.wav", 1.0, 0.8, 0, 100);
+ }
+ }
+ break;
+ case 2:
+ {
+ switch(gEngfuncs.pfnRandomLong(0, 1))
+ {
+ case 1:
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/cbar_hit2", fSoundData, 0.8, 0, gEngfuncs.pfnRandomLong(0, 3) + 98);
+ default:
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/cbar_hit1", fSoundData, 0.8, 0, gEngfuncs.pfnRandomLong(0, 3) + 98);
+ }
+ }
+ break;
+ default:
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, CHAN_WEAPON, "weapons/cbar_miss1.wav", 1.0, 0.8, 0, gEngfuncs.pfnRandomLong(0, 15) + 94);
+ break;
+ }
+}
+
+int EV_TFC_AxeHit(int idx, float *origin, float *forward, float *right, int entity, float *vecDir, pmtrace_t *ptr)
+{
+ cl_entity_s *ent;
+ Vector tf_0, tu, tr;
+
+ if(entity > 0 && entity <= gEngfuncs.GetMaxClients())
+ ent = GetEntity(entity - 1);
+
+ if (entity > 0
+ && entity <= gEngfuncs.GetMaxClients()
+ && ent != 0)
+ {
+ AngleVectors(ent->curstate.angles, tf_0, tu, tr);
+ if (tr.x * forward[1] - *forward * tr.y <= 0.0)
+ {
+ if (gEngfuncs.pfnGetCvarFloat("cl_localblood") != 0.0)
+ EV_TFC_TraceAttack(idx, vecDir, ptr, 40.0);
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(2, 2);
+ }
+ else
+ {
+ if (gEngfuncs.pfnGetCvarFloat("cl_localblood") != 0.0)
+ EV_TFC_TraceAttack(idx, vecDir, ptr, 120.0);
+ if (EV_IsLocal(idx))
+ gEngfuncs.pEventAPI->EV_WeaponAnimation(3, 2);
+ }
+ }
+ else if (gEngfuncs.pfnGetCvarFloat("cl_localblood") != 0.0)
+ EV_TFC_TraceAttack(idx, vecDir, ptr, 20.0);
+ return 1;
+}
+
+int EV_TFC_Medkit(int idx, float *origin, float *forward, float *right, int entity, float *vecDir, pmtrace_t *ptr)
+{
+ cl_entity_s *ent;
+
+ if (entity > 0 && entity <= gEngfuncs.GetMaxClients())
+ {
+ ent = GetEntity(entity - 1);
+ if (!EV_TFC_IsAlly(idx, entity))
+ {
+ if (gEngfuncs.pfnGetCvarFloat("cl_localblood") != 0.0)
+ EV_TFC_TraceAttack(idx, vecDir, ptr, 10.0);
+ if (ent->curstate.playerclass != 5)
+ gEngfuncs.pEventAPI->EV_PlaySound(idx, origin, 2, "player/death2.wav", 1.0, 0.8, 0, 100);
+ }
+ }
+ return 1;
+}
diff --git a/cl_dll/tfc/ev_tfc.h b/cl_dll/tfc/ev_tfc.h
new file mode 100644
index 00000000..4e41617e
--- /dev/null
+++ b/cl_dll/tfc/ev_tfc.h
@@ -0,0 +1,42 @@
+//========= Copyright 1996-2002, Valve LLC, All rights reserved. ============
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+
+#if !defined ( EV_HLDMH )
+#define EV_HLDMH
+
+// bullet types
+typedef enum
+{
+ BULLET_NONE = 0,
+ BULLET_PLAYER_9MM, // glock
+ BULLET_PLAYER_MP5, // mp5
+ BULLET_PLAYER_357, // python
+ BULLET_PLAYER_BUCKSHOT, // shotgun
+ BULLET_PLAYER_CROWBAR, // crowbar swipe
+
+ BULLET_MONSTER_9MM,
+ BULLET_MONSTER_MP5,
+ BULLET_MONSTER_12MM
+}Bullet;
+
+void EV_HLDM_GunshotDecalTrace( pmtrace_t *pTrace, char *decalName );
+void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType );
+int EV_HLDM_CheckTracer( int idx, float *vecSrc, float *end, float *forward, float *right, int iBulletType, int iTracerFreq, int *tracerCount );
+void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, float flDistance, int iBulletType, int iTracerFreq, int *tracerCount, float flSpreadX, float flSpreadY );
+void EV_TFC_NailTouch( struct tempent_s *ent, pmtrace_t *ptr );
+void EV_TFC_Explode( float *org, int dmg, pmtrace_t *pTrace, qboolean bDontSpark );
+void EV_TFC_BloodDrips( float *vecOrigin, signed int iDamage, long double height );
+void EV_TFC_TraceAttack( int idx, float *vecDir, pmtrace_t *ptr, float flDamage );
+long double EV_TFC_WaterLevel( float *position, float minz, float maxz );
+void EV_TFC_RailDie( struct particle_s *particle );
+int EV_TFC_IsAlly( int idx1, int idx2 );
+void EV_TFC_TranqNailTouch( tempent_s *ent, pmtrace_t *ptr );
+void EV_TFC_PlayAxeSound( int idx, int classid, float *origin, int iSoundType, float fSoundData );
+int EV_TFC_AxeHit(int idx, float *origin, float *forward, float *right, int entity, float *vecDir, pmtrace_t *ptr);
+int EV_TFC_Medkit(int idx, float *origin, float *forward, float *right, int entity, float *vecDir, pmtrace_t *ptr);
+//tempent_s EV_TFC_CreateGib(float *origin, float *attackdir, int multiplier, int ishead);
+#endif // EV_HLDMH
diff --git a/cl_dll/tfc/tfc_events.cpp b/cl_dll/tfc/tfc_events.cpp
new file mode 100644
index 00000000..b80b524e
--- /dev/null
+++ b/cl_dll/tfc/tfc_events.cpp
@@ -0,0 +1,129 @@
+/***
+*
+* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
+*
+* This product contains software technology licensed from Id
+* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
+* All Rights Reserved.
+*
+* Use, distribution, and modification of this source code and/or resulting
+* object code is restricted to non-commercial enhancements to products from
+* Valve LLC. All other use, distribution, or modification is prohibited
+* without written permission from Valve LLC.
+*
+****/
+
+#include "../hud.h"
+#include "../cl_util.h"
+#include "event_api.h"
+
+extern "C"
+{
+void EV_TFC_Axe( struct event_args_s *args );
+void EV_FireTFCShotgun( struct event_args_s *args );
+void EV_FireTFCSuperShotgun( struct event_args_s *args );
+void EV_ReloadTFCShotgun( struct event_args_s *args );
+void EV_PumpTFCShotgun( struct event_args_s *args );
+void EV_FireTFCNailgun( struct event_args_s *args );
+void EV_FireTFCSuperNailgun( struct event_args_s *args );
+void EV_FireTFCAutoRifle( struct event_args_s *args );
+void EV_TFC_Gas( struct event_args_s *args );
+void EV_TFC_DoorGoUp( struct event_args_s *args );
+void EV_TFC_DoorGoDown( struct event_args_s *args );
+void EV_TFC_DoorHitTop( struct event_args_s *args );
+void EV_TFC_DoorHitBottom( struct event_args_s *args );
+void EV_TFC_Explosion( struct event_args_s *args );
+void EV_TFC_Grenade( struct event_args_s *args );
+void EV_TFC_NormalGrenade( struct event_args_s *args );
+void EV_TFC_FireRPG( struct event_args_s *args );
+void EV_FireTFCSniper( struct event_args_s *args );
+void EV_TFC_SniperHit( struct event_args_s *args );
+void EV_TFC_FireIC( struct event_args_s *args );
+void EV_TFC_NailgrenadeNail( struct event_args_s *args );
+void EV_TFC_GrenadeLauncher( struct event_args_s *args );
+void EV_TFC_PipeLauncher( struct event_args_s *args );
+void EV_TFC_NormalShot( struct event_args_s *args );
+void EV_TFC_SuperShot( struct event_args_s *args );
+void EV_TFC_SteamShot( struct event_args_s *args );
+void EV_TFC_EngineerGrenade( struct event_args_s *args );
+void EV_TFC_Concussion( struct event_args_s *args );
+void EV_TFC_Assault_WindUp( struct event_args_s *args );
+void EV_TFC_Assault_WindDown( struct event_args_s *args );
+void EV_TFC_Assault_Start( struct event_args_s *args );
+void EV_TFC_Assault_Fire( struct event_args_s *args );
+void EV_TFC_Assault_Spin( struct event_args_s *args );
+void EV_TFC_Assault_StartSpin( struct event_args_s *args );
+void EV_TFC_AxeDecal( struct event_args_s *args );
+void EV_TFC_NapalmFire( struct event_args_s *args );
+void EV_TFC_MirvGrenadeMain( struct event_args_s *args );
+void EV_TFC_MirvGrenade( struct event_args_s *args );
+void EV_TFC_NapalmBurn( struct event_args_s *args );
+void EV_TFC_EMP( struct event_args_s *args );
+void EV_TFC_Flame_Fire( struct event_args_s *args );
+void EV_TFC_Railgun( struct event_args_s *args );
+void EV_TFC_Tranquilizer( struct event_args_s *args );
+void EV_TFC_NailGrenade( struct event_args_s *args );
+
+void EV_TrainPitchAdjust( struct event_args_s *args );
+}
+
+/*
+======================
+Game_HookEvents
+
+Associate script file name with callback functions. Callback's must be extern "C" so
+ the engine doesn't get confused about name mangling stuff. Note that the format is
+ always the same. Of course, a clever mod team could actually embed parameters, behavior
+ into the actual .sc files and create a .sc file parser and hook their functionality through
+ that.. i.e., a scripting system.
+
+That was what we were going to do, but we ran out of time...oh well.
+======================
+*/
+void Game_HookEvents( void )
+{
+ gEngfuncs.pfnHookEvent("events/wpn/tf_axe.sc", EV_TFC_Axe);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_sg.sc", EV_FireTFCShotgun);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_sgreload.sc", EV_ReloadTFCShotgun);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_sgpump.sc", EV_PumpTFCShotgun);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_nail.sc", EV_FireTFCNailgun);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_snail.sc", EV_FireTFCSuperNailgun);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_ssg.sc", EV_FireTFCSuperShotgun);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_ar.sc", EV_FireTFCAutoRifle);
+ gEngfuncs.pfnHookEvent("events/explode/tf_gas.sc", EV_TFC_Gas);
+ gEngfuncs.pfnHookEvent("events/door/doorgoup.sc", EV_TFC_DoorGoUp);
+ gEngfuncs.pfnHookEvent("events/door/doorgodown.sc", EV_TFC_DoorGoDown);
+ gEngfuncs.pfnHookEvent("events/door/doorhittop.sc", EV_TFC_DoorHitTop);
+ gEngfuncs.pfnHookEvent("events/door/doorhitbottom.sc", EV_TFC_DoorHitBottom);
+ gEngfuncs.pfnHookEvent("events/explode/tf_pipe.sc", EV_TFC_Explosion);
+ gEngfuncs.pfnHookEvent("events/explode/tf_gren.sc", EV_TFC_Grenade);
+ gEngfuncs.pfnHookEvent("events/explode/tf_normalgren.sc", EV_TFC_NormalGrenade);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_rpg.sc", EV_TFC_FireRPG);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_sniper.sc", EV_FireTFCSniper);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_sniperhit.sc", EV_TFC_SniperHit);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_ic.sc", EV_TFC_FireIC);
+ gEngfuncs.pfnHookEvent("events/explode/tf_nailgren.sc", EV_TFC_NailgrenadeNail);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_gl.sc", EV_TFC_GrenadeLauncher);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_pipel.sc", EV_TFC_PipeLauncher);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_mednormal.sc", EV_TFC_NormalShot);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_medsuper.sc", EV_TFC_SuperShot);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_medsteam.sc", EV_TFC_SteamShot);
+ gEngfuncs.pfnHookEvent("events/explode/tf_engrgren.sc", EV_TFC_EngineerGrenade);
+ gEngfuncs.pfnHookEvent("events/explode/tf_concuss.sc", EV_TFC_Concussion);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_acwu.sc", EV_TFC_Assault_WindUp);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_acwd.sc", EV_TFC_Assault_WindDown);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_acstart.sc", EV_TFC_Assault_Start);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_acfire.sc", EV_TFC_Assault_Fire);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_acspin.sc", EV_TFC_Assault_Spin);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_acsspin.sc", EV_TFC_Assault_StartSpin);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_axedecal.sc", EV_TFC_AxeDecal);
+ gEngfuncs.pfnHookEvent("events/explode/tf_mirvmain.sc", EV_TFC_MirvGrenadeMain);
+ gEngfuncs.pfnHookEvent("events/explode/tf_mirv.sc", EV_TFC_MirvGrenade);
+ gEngfuncs.pfnHookEvent("events/explode/tf_fire.sc", EV_TFC_NapalmFire);
+ gEngfuncs.pfnHookEvent("events/explode/tf_burn.sc", EV_TFC_NapalmBurn);
+ gEngfuncs.pfnHookEvent("events/explode/tf_emp.sc", EV_TFC_EMP);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_flame.sc", EV_TFC_Flame_Fire);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_rail.sc", EV_TFC_Railgun);
+ gEngfuncs.pfnHookEvent("events/wpn/tf_tranq.sc", EV_TFC_Tranquilizer);
+ gEngfuncs.pfnHookEvent("events/explode/tf_ng.sc", EV_TFC_NailGrenade);
+}
diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/tfc/tfc_weapons.cpp
similarity index 91%
rename from cl_dll/hl/hl_weapons.cpp
rename to cl_dll/tfc/tfc_weapons.cpp
index 75161a9e..0c945ba9 100644
--- a/cl_dll/hl/hl_weapons.cpp
+++ b/cl_dll/tfc/tfc_weapons.cpp
@@ -21,6 +21,8 @@
#include "nodes.h"
#include "player.h"
+#include "tf_defs.h"
+
#include "usercmd.h"
#include "entity_state.h"
#include "demo_api.h"
@@ -52,21 +54,21 @@ int g_irunninggausspred = 0;
vec3_t previousorigin;
-// HLDM Weapon placeholder entities.
-CGlock g_Glock;
-CCrowbar g_Crowbar;
-CPython g_Python;
-CMP5 g_Mp5;
-CCrossbow g_Crossbow;
-CShotgun g_Shotgun;
-CRpg g_Rpg;
-CGauss g_Gauss;
-CEgon g_Egon;
-CHgun g_HGun;
-CHandGrenade g_HandGren;
-CSatchel g_Satchel;
-CTripmine g_Tripmine;
-CSqueak g_Snark;
+// TFC Weapons
+CTFShotgun g_TFShotgun;
+CTFSuperShotgun g_TFSuperShotgun;
+CTFNailgun g_TFNailgun;
+CTFSuperNailgun g_TFSuperNailgun;
+CTFSniperRifle g_TFSniperRifle;
+CTFRpg g_TFRpg;
+CTFIncendiaryC g_TFIncediaryC;
+CTFFlamethrower g_TFFlamethrower;
+CTFAxe g_TFAxe;
+CTFSpanner g_TFSpanner;
+CTFRailgun g_TFRailgun;
+CTFGrenadeLauncher g_TFGrenadeLauncher;
+CTFAssaultC g_TFAssaultC;
+CTFPipebombLauncher g_TFPipebombLauncher;
/*
======================
@@ -602,20 +604,20 @@ void HUD_InitClientWeapons( void )
HUD_PrepEntity( &player, NULL );
// Allocate slot(s) for each weapon that we are going to be predicting
- HUD_PrepEntity( &g_Glock, &player );
- HUD_PrepEntity( &g_Crowbar, &player );
- HUD_PrepEntity( &g_Python, &player );
- HUD_PrepEntity( &g_Mp5, &player );
- HUD_PrepEntity( &g_Crossbow, &player );
- HUD_PrepEntity( &g_Shotgun, &player );
- HUD_PrepEntity( &g_Rpg, &player );
- HUD_PrepEntity( &g_Gauss, &player );
- HUD_PrepEntity( &g_Egon, &player );
- HUD_PrepEntity( &g_HGun, &player );
- HUD_PrepEntity( &g_HandGren, &player );
- HUD_PrepEntity( &g_Satchel, &player );
- HUD_PrepEntity( &g_Tripmine, &player );
- HUD_PrepEntity( &g_Snark, &player );
+ HUD_PrepEntity( &g_TFShotgun, &player );
+ HUD_PrepEntity( &g_TFSuperShotgun, &player );
+ HUD_PrepEntity( &g_TFNailgun, &player );
+ HUD_PrepEntity( &g_TFSuperNailgun, &player );
+ HUD_PrepEntity( &g_TFSniperRifle, &player );
+ HUD_PrepEntity( &g_TFRpg, &player );
+ HUD_PrepEntity( &g_TFIncediaryC, &player );
+ HUD_PrepEntity( &g_TFFlamethrower, &player );
+ HUD_PrepEntity( &g_TFAxe, &player );
+ HUD_PrepEntity( &g_TFSpanner, &player );
+ HUD_PrepEntity( &g_TFRailgun, &player );
+ HUD_PrepEntity( &g_TFGrenadeLauncher, &player );
+ HUD_PrepEntity( &g_TFAssaultC, &player );
+ HUD_PrepEntity( &g_TFPipebombLauncher, &player );
}
/*
@@ -679,47 +681,71 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
// FIXME, make this a method in each weapon? where you pass in an entity_state_t *?
switch( from->client.m_iId )
{
- case WEAPON_CROWBAR:
- pWeapon = &g_Crowbar;
+ case WEAPON_HOOK:
+ //pWeapon = &;
break;
- case WEAPON_GLOCK:
- pWeapon = &g_Glock;
+ case WEAPON_BIOWEAPON:
+ //pWeapon = &;
break;
- case WEAPON_PYTHON:
- pWeapon = &g_Python;
+ case WEAPON_SPANNER:
+ pWeapon = &g_TFSpanner;
break;
- case WEAPON_MP5:
- pWeapon = &g_Mp5;
+ case WEAPON_AXE:
+ pWeapon = &g_TFAxe;
break;
- case WEAPON_CROSSBOW:
- pWeapon = &g_Crossbow;
+ case WEAPON_SNIPER_RIFLE:
+ pWeapon = &g_TFSniperRifle;
break;
- case WEAPON_SHOTGUN:
- pWeapon = &g_Shotgun;
+ case WEAPON_AUTO_RIFLE:
+ //pWeapon = &;
break;
- case WEAPON_RPG:
- pWeapon = &g_Rpg;
+ case WEAPON_TF_SHOTGUN:
+ pWeapon = &g_TFShotgun;
break;
- case WEAPON_GAUSS:
- pWeapon = &g_Gauss;
+ case WEAPON_SUPER_SHOTGUN:
+ pWeapon = &g_TFSuperShotgun;
break;
- case WEAPON_EGON:
- pWeapon = &g_Egon;
+ case WEAPON_NAILGUN:
+ pWeapon = &g_TFNailgun;
break;
- case WEAPON_HORNETGUN:
- pWeapon = &g_HGun;
+ case WEAPON_SUPER_NAILGUN:
+ pWeapon = &g_TFSuperNailgun;
break;
- case WEAPON_HANDGRENADE:
- pWeapon = &g_HandGren;
+ case WEAPON_GRENADE_LAUNCHER:
+ pWeapon = &g_TFGrenadeLauncher;
break;
- case WEAPON_SATCHEL:
- pWeapon = &g_Satchel;
+ case WEAPON_FLAMETHROWER:
+ pWeapon = &g_TFFlamethrower;
break;
- case WEAPON_TRIPMINE:
- pWeapon = &g_Tripmine;
+ case WEAPON_ROCKET_LAUNCHER:
+ pWeapon = &g_TFRpg;
break;
- case WEAPON_SNARK:
- pWeapon = &g_Snark;
+ case WEAPON_INCENDIARY:
+ pWeapon = &g_TFIncediaryC;
+ break;
+ case WEAPON_ASSAULT_CANNON:
+ pWeapon = &g_TFAssaultC;
+ break;
+ case WEAPON_LIGHTNING:
+ //pWeapon = &;
+ break;
+ case WEAPON_DETPACK:
+ //pWeapon = &;
+ break;
+ case WEAPON_TRANQ:
+ //pWeapon = &;
+ break;
+ case WEAPON_LASER:
+ pWeapon = &g_TFRailgun;
+ break;
+ case WEAPON_PIPEBOMB_LAUNCHER:
+ pWeapon = &g_TFPipebombLauncher;
+ break;
+ case WEAPON_KNIFE:
+ //pWeapon = &;
+ break;
+ case WEAPON_BENCHMARK:
+ //pWeapon = &;
break;
}
@@ -824,13 +850,13 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
{
player.m_pActiveItem = g_pWpns[from->client.m_iId];
}
-
+/*
if( player.m_pActiveItem->m_iId == WEAPON_RPG )
{
( (CRpg *)player.m_pActiveItem )->m_fSpotActive = (int)from->client.vuser2[1];
( (CRpg *)player.m_pActiveItem )->m_cActiveRockets = (int)from->client.vuser2[2];
}
-
+*/
// Don't go firing anything if we have died.
// Or if we don't have a weapon model deployed
if( ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) &&
@@ -892,7 +918,7 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
to->client.ammo_cells = player.ammo_uranium;
to->client.vuser2[0] = player.ammo_hornets;
to->client.ammo_rockets = player.ammo_rockets;
-
+/*
if( player.m_pActiveItem->m_iId == WEAPON_RPG )
{
from->client.vuser2[1] = ( (CRpg *)player.m_pActiveItem)->m_fSpotActive;
@@ -916,7 +942,7 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
// Force a fixed anim down to viewmodel
HUD_SendWeaponAnim( to->client.weaponanim, body, 1 );
}
-
+*/
for( i = 0; i < 32; i++ )
{
pCurrent = g_pWpns[i];
diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp
index daecc3af..96f8d219 100644
--- a/cl_dll/view.cpp
+++ b/cl_dll/view.cpp
@@ -1313,21 +1313,21 @@ int V_FindViewModelByWeaponModel( int weaponindex )
{
static const char *modelmap[][2] =
{
- { "models/p_crossbow.mdl", "models/v_crossbow.mdl" },
- { "models/p_crowbar.mdl", "models/v_crowbar.mdl" },
- { "models/p_egon.mdl", "models/v_egon.mdl" },
- { "models/p_gauss.mdl", "models/v_gauss.mdl" },
- { "models/p_9mmhandgun.mdl", "models/v_9mmhandgun.mdl" },
- { "models/p_grenade.mdl", "models/v_grenade.mdl" },
- { "models/p_hgun.mdl", "models/v_hgun.mdl" },
- { "models/p_9mmAR.mdl", "models/v_9mmAR.mdl" },
- { "models/p_357.mdl", "models/v_357.mdl" },
- { "models/p_rpg.mdl", "models/v_rpg.mdl" },
- { "models/p_shotgun.mdl", "models/v_shotgun.mdl" },
- { "models/p_squeak.mdl", "models/v_squeak.mdl" },
- { "models/p_tripmine.mdl", "models/v_tripmine.mdl" },
- { "models/p_satchel_radio.mdl", "models/v_satchel_radio.mdl" },
- { "models/p_satchel.mdl", "models/v_satchel.mdl" },
+ { "models/p_mini.mdl", "models/v_tfac.mdl" },
+ { "models/p_sniper.mdl", "models/v_tfc_sniper.mdl" },
+ { "models/p_umbrella.mdl", "models/v_umbrella.mdl" },
+ { "models/p_crowbar.mdl", "models/v_tfc_crowbar.mdl" },
+ { "models/p_spanner.mdl", "models/v_tfc_spanner.mdl" },
+ { "models/p_knife.mdl", "models/v_tfc_knife.mdl" },
+ { "models/p_medkit.mdl", "models/v_tfc_medkit.mdl" },
+ { "models/p_egon.mdl", "models/v_flame.mdl" },
+ { "models/p_glauncher.mdl", "models/v_tfgl.mdl" },
+ { "models/p_rpg.mdl", "models/v_tfc_rpg.mdl" },
+ { "models/p_nailgun.mdl", "models/v_tfc_nailgun.mdl" },
+ { "models/p_snailgun.mdl", "models/v_tfc_supernailgun.mdl" },
+ { "models/p_9mmhandgun.mdl", "models/v_tfc_railgun.mdl" },
+ { "models/p_srpg.mdl", "models/v_tfc_rpg.mdl" },
+ { "models/p_smallshotgun.mdl", "models/v_tfc_12gauge.mdl" },
{ NULL, NULL }
};
diff --git a/dlls/tfc/assaultcannon.cpp b/dlls/tfc/assaultcannon.cpp
new file mode 100644
index 00000000..e6631758
--- /dev/null
+++ b/dlls/tfc/assaultcannon.cpp
@@ -0,0 +1,188 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_ac, CTFAssaultC )
+
+void CTFAssaultC::Spawn()
+{
+ Precache();
+
+ m_iId = 17;
+ m_iDefaultAmmo = 25;
+ m_iWeaponState = 0;
+ pev->solid = SOLID_TRIGGER;
+}
+
+int CTFAssaultC::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "buckshot";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 200;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 4;
+ p->iPosition = 3;
+ p->iFlags = 0;
+ p->iMaxClip = -1;
+ p->iId = 17;
+ p->iWeight = 15;
+ return 1;
+}
+
+void CTFAssaultC::Holster()
+{
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usWindDown, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 1, 0);
+ m_iWeaponState = 0;
+ //tfstate
+ //setspeed
+ m_fInReload = 0;
+ m_flTimeWeaponIdle = 2;
+ m_pPlayer->m_flNextAttack = 0.1;
+ SendWeaponAnim(ASSAULT_HOLSTER, 1);
+}
+
+void CTFAssaultC::Precache()
+{
+ PRECACHE_MODEL("models/v_tfac.mdl");
+ PRECACHE_MODEL("models/p_mini.mdl");
+ PRECACHE_MODEL("models/p_mini2.mdl");
+ m_iShell = PRECACHE_MODEL("models/shell.mdl");
+ PRECACHE_SOUND("weapons/357_cock1.wav");
+ PRECACHE_SOUND("weapons/asscan1.wav");
+ PRECACHE_SOUND("weapons/asscan2.wav");
+ PRECACHE_SOUND("weapons/asscan3.wav");
+ PRECACHE_SOUND("weapons/asscan4.wav");
+ m_usWindUp = PRECACHE_EVENT(1, "events/wpn/tf_acwu.sc");
+ m_usWindDown = PRECACHE_EVENT(1, "events/wpn/tf_acwd.sc");
+ m_usFire = PRECACHE_EVENT(1, "events/wpn/tf_acfire.sc");
+ m_usStartSpin = PRECACHE_EVENT(1, "events/wpn/tf_acsspin.sc");
+ m_usSpin = PRECACHE_EVENT(1, "events/wpn/tf_acspin.sc");
+ m_usACStart = PRECACHE_EVENT(1, "events/wpn/tf_acstart.sc");
+}
+
+void CTFAssaultC::WeaponIdle( void )
+{
+ ResetEmptySound();
+
+ if(m_flTimeWeaponIdle <= 0.0)
+ {
+ if(m_iWeaponState)
+ {
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usWindDown, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_iWeaponState = 0;
+ //tfstate
+ //setspeed
+ m_flTimeWeaponIdle = 2;
+ }
+ else
+ {
+ SendWeaponAnim(RANDOM_LONG(0, 1), 1);
+ m_flTimeWeaponIdle = 12.5;
+ }
+ }
+}
+
+BOOL CTFAssaultC::Deploy()
+{
+ //Velaron: "ac" deploy
+ return DefaultDeploy( "models/v_tfac.mdl", "models/p_mini.mdl", ASSAULT_DRAW, "mp5", 1 );
+}
+
+int CTFAssaultC::AddToPlayer( CBasePlayer *pPlayer )
+{
+ if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
+ {
+ MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
+ WRITE_BYTE( m_iId );
+ MESSAGE_END();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CTFAssaultC::PrimaryAttack()
+{
+ if(m_iWeaponState == 2)
+ {
+ if(m_pPlayer->ammo_buckshot <= 0)
+ {
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usStartSpin, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_iWeaponState = 3;
+ m_pPlayer->SetAnimation(PLAYER_ATTACK1);
+ pev->effects &= ~EF_MUZZLEFLASH;
+ }
+ else
+ Fire();
+
+ m_flTimeWeaponIdle = 0.1;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;
+ return;
+ }
+ if(m_iWeaponState == 3)
+ {
+ if(m_pPlayer->ammo_buckshot <= 0)
+ {
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usSpin, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_pPlayer->SetAnimation(PLAYER_ATTACK1);
+ }
+ else
+ {
+ m_iWeaponState = 1;
+ }
+ m_flTimeWeaponIdle = 0.1;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;
+ return;
+ }
+ if(m_iWeaponState == 1)
+ {
+ if(m_flNextPrimaryAttack > 0.0)
+ return;
+
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usACStart, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_iWeaponState = 2;
+ m_flTimeWeaponIdle = 0.1;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;
+ return;
+ }
+
+ if(m_pPlayer->pev->button & 1)
+ {
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usWindUp, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_iWeaponState = 1;
+ //tfstate
+ //setspeed
+ }
+
+ m_flTimeWeaponIdle = 0.6;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
+}
+
+void CTFAssaultC::Fire()
+{
+ vec3_t p_vecSrc, vecAiming, vecSpread;
+
+ if(m_flNextPrimaryAttack > 0)
+ return;
+
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usWindUp, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, m_pPlayer->ammo_buckshot & 1, 0);
+ m_pPlayer->m_iWeaponVolume = 600;
+ m_pPlayer->m_iWeaponFlash = 256;
+ m_pPlayer->pev->effects |= EF_MUZZLEFLASH;
+ m_pPlayer->SetAnimation(PLAYER_ATTACK1);
+ UTIL_MakeVectors(m_pPlayer->pev->v_angle);
+ p_vecSrc.x = gpGlobals->v_up.x * -4.0 + gpGlobals->v_right.x + gpGlobals->v_right.x + m_pPlayer->pev->origin.x + m_pPlayer->pev->view_ofs.x;
+ p_vecSrc.y = gpGlobals->v_up.y * -4.0 + gpGlobals->v_right.y + gpGlobals->v_right.y + m_pPlayer->pev->origin.y + m_pPlayer->pev->view_ofs.y;
+ p_vecSrc.z = gpGlobals->v_up.z * -4.0 + gpGlobals->v_right.z + gpGlobals->v_right.z + m_pPlayer->pev->origin.z + m_pPlayer->pev->view_ofs.z;
+ vecAiming = m_pPlayer->GetAutoaimVector(0.087155744);
+ vecSpread.x = 0.1;
+ vecSpread.y = 0.1;
+ vecSpread.z = 0.0;
+ FireBullets(5, p_vecSrc, vecAiming, vecSpread, 8192.0, 7, 8, 7, 0);
+ m_pPlayer->ammo_buckshot--;
+}
\ No newline at end of file
diff --git a/dlls/tfc/axe.cpp b/dlls/tfc/axe.cpp
new file mode 100644
index 00000000..f6505a0c
--- /dev/null
+++ b/dlls/tfc/axe.cpp
@@ -0,0 +1,93 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_axe, CTFAxe )
+
+void CTFAxe::Spawn()
+{
+ Precache();
+
+ m_iId = 5;
+ m_iClip = -1;
+ pev->solid = SOLID_TRIGGER;
+}
+
+int CTFAxe::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = 0;
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = -1;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 0;
+ p->iPosition = 3;
+ p->iFlags = 0;
+ p->iMaxClip = -1;
+ p->iId = 5;
+ p->iWeight = 0;
+ return 1;
+}
+
+void CTFAxe::Holster()
+{
+ SendWeaponAnim(AXE_HOLSTER, 1);
+ m_pPlayer->m_flNextAttack = 0.5;
+}
+
+void CTFAxe::Precache()
+{
+ PRECACHE_MODEL("models/v_umbrella.mdl");
+ PRECACHE_MODEL("models/p_umbrella.mdl");
+ PRECACHE_MODEL("models/v_tfc_crowbar.mdl");
+ PRECACHE_MODEL("models/p_crowbar.mdl");
+ PRECACHE_MODEL("models/p_crowbar2.mdl");
+ PRECACHE_SOUND("weapons/cbar_hit1.wav");
+ PRECACHE_SOUND("weapons/cbar_hit2.wav");
+ PRECACHE_SOUND("weapons/cbar_hitbod1.wav");
+ PRECACHE_SOUND("weapons/cbar_hitbod2.wav");
+ PRECACHE_SOUND("weapons/cbar_hitbod3.wav");
+ PRECACHE_SOUND("weapons/cbar_miss1.wav");
+ classid = 3;
+ m_usAxe = PRECACHE_EVENT(1, "events/wpn/tf_axe.sc");
+ m_usAxeDecal = PRECACHE_EVENT(1, "events/wpn/tf_axedecal.sc");
+}
+
+BOOL CTFAxe::Deploy()
+{
+ if(m_pPlayer->pev->playerclass == 11)
+ return DefaultDeploy( "models/v_umbrella.mdl", "models/p_umbrella.mdl", AXE_DRAW, "crowbar", 1 );
+ else
+ return DefaultDeploy( "models/v_tfc_crowbar.mdl", "models/p_crowbar.mdl", AXE_DRAW, "crowbar", 1 );
+}
+//Velaron: finish this?
+void CTFAxe::PrimaryAttack()
+{
+ vec3_t vecSrc, vecEnd;
+ TraceResult tr;
+
+ m_bHullHit = 0;
+ UTIL_MakeVectors(m_pPlayer->pev->v_angle);
+ vecSrc = m_pPlayer->GetGunPosition();
+ vecEnd.x = gpGlobals->v_forward.x * 32.0 + vecSrc.x;
+ vecEnd.y = gpGlobals->v_forward.y * 32.0 + vecSrc.y;
+ vecEnd.z = gpGlobals->v_forward.z * 32.0 + vecSrc.z;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usAxe, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, classid, 0, 0, 0);
+ if ( tr.flFraction >= 1.0 )
+ {
+ m_bHullHit = 1;
+ //m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.4;
+ m_flNextPrimaryAttack = 1.0;
+ m_flTimeWeaponIdle = 5;
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ return;
+ }
+ m_flNextPrimaryAttack = 1.0;
+ m_flTimeWeaponIdle = 5;
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+}
\ No newline at end of file
diff --git a/dlls/tfc/flamethrower.cpp b/dlls/tfc/flamethrower.cpp
new file mode 100644
index 00000000..5ab5ab31
--- /dev/null
+++ b/dlls/tfc/flamethrower.cpp
@@ -0,0 +1,120 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_flamethrower, CTFFlamethrower )
+
+void CTFFlamethrower::Spawn()
+{
+ Precache();
+
+ m_iId = 13;
+ SET_MODEL(ENT(pev), "models/w_egon.mdl");
+ m_iDefaultAmmo = 50;
+ pev->solid = SOLID_TRIGGER;
+}
+
+int CTFFlamethrower::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "uranium";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 200;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 3;
+ p->iPosition = 2;
+ p->iFlags = 0;
+ p->iMaxClip = -1;
+ p->iId = 13;
+ p->iWeight = 20;
+ return 1;
+}
+
+void CTFFlamethrower::Holster()
+{
+ m_fInReload = 0;
+ SendWeaponAnim(10, 1);
+ m_pPlayer->m_flNextAttack = 0.5;
+}
+
+void CTFFlamethrower::Precache()
+{
+ PRECACHE_MODEL("models/w_egon.mdl");
+ PRECACHE_MODEL("models/v_flame.mdl");
+ PRECACHE_MODEL("models/p_egon.mdl");
+ PRECACHE_MODEL("models/p_egon2.mdl");
+ PRECACHE_MODEL("models/w_9mmclip.mdl");
+ PRECACHE_SOUND("weapons/9mmclip1.wav");
+ UTIL_PrecacheOther("tf_flamethrower_burst");
+ PRECACHE_SOUND("weapons/flmfire2.wav");
+ m_usFireFlame = PRECACHE_EVENT(1, "events/wpn/tf_flame.sc");
+}
+
+void CTFFlamethrower::WeaponIdle( void )
+{
+ ResetEmptySound();
+
+ if(m_flTimeWeaponIdle <= 0.0)
+ {
+ if(UTIL_SharedRandomLong(m_pPlayer->random_seed, 0, 4))
+ {
+ m_flTimeWeaponIdle = 12.5;
+ SendWeaponAnim(0, 1);
+ }
+ else
+ {
+ m_flTimeWeaponIdle = 3;
+ SendWeaponAnim(1, 1);
+ }
+ }
+}
+
+BOOL CTFFlamethrower::Deploy()
+{
+ return DefaultDeploy( "models/v_flame.mdl", "models/p_egon.mdl", 5, "egon", 1 );
+}
+
+int CTFFlamethrower::AddToPlayer( CBasePlayer *pPlayer )
+{
+ if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
+ {
+ MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
+ WRITE_BYTE( m_iId );
+ MESSAGE_END();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CTFFlamethrower::PrimaryAttack()
+{
+ BOOL bUnderwater;
+
+ if(m_pPlayer->ammo_uranium <= 0)
+ {
+ PlayEmptySound();
+ return;
+ }
+
+ m_pPlayer->m_iWeaponVolume = 1000;
+ m_pPlayer->m_iWeaponFlash = 512;
+ bUnderwater = m_pPlayer->pev->waterlevel > 2;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireFlame, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, bUnderwater, 0);
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ if(bUnderwater)
+ {
+ m_flTimeWeaponIdle = 1;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1;
+ }
+ else
+ {
+ m_flTimeWeaponIdle = 0.15;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.15;
+ }
+ m_pPlayer->ammo_uranium--;
+}
\ No newline at end of file
diff --git a/dlls/tfc/grenadelauncher.cpp b/dlls/tfc/grenadelauncher.cpp
new file mode 100644
index 00000000..28786dcf
--- /dev/null
+++ b/dlls/tfc/grenadelauncher.cpp
@@ -0,0 +1,174 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_gl, CTFGrenadeLauncher )
+
+void CTFGrenadeLauncher::Spawn()
+{
+ Precache();
+
+ SET_MODEL( ENT( pev ), "models/w_gauss.mdl" );
+ m_iId = 12;
+ m_iDefaultAmmo = 50;
+ m_fReloadTime = 0.666667;
+ pev->solid = SOLID_TRIGGER;
+}
+
+void CTFGrenadeLauncher::Precache()
+{
+ PRECACHE_MODEL("models/v_tfgl.mdl");
+ PRECACHE_MODEL("models/p_glauncher.mdl");
+ PRECACHE_MODEL("models/p_p_glauncher2rpg.mdl");
+ PRECACHE_MODEL("models/pipebomb.mdl");
+ PRECACHE_SOUND("weapons/9mmclip1.wav");
+ PRECACHE_SOUND("items/clipinsert1.wav");
+ PRECACHE_SOUND("items/cliprelease1.wav");
+ PRECACHE_SOUND("weapons/hks1.wav");
+ PRECACHE_SOUND("weapons/hks2.wav");
+ PRECACHE_SOUND("weapons/hks3.wav");
+ PRECACHE_SOUND("weapons/glauncher.wav");
+ PRECACHE_SOUND("weapons/glauncher2.wav");
+ PRECACHE_SOUND("weapons/357_cock1.wav");
+ m_usFireGL = PRECACHE_EVENT(1, "events/wpn/tf_gl.sc");
+}
+
+int CTFGrenadeLauncher::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "rockets";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 50;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 3;
+ p->iPosition = 3;
+ p->iFlags = 0;
+ p->iMaxClip = 6;
+ p->iId = 12;
+ p->iWeight = 15;
+ return 1;
+}
+
+void CTFGrenadeLauncher::Holster()
+{
+ //m_pPlayer->m_iGLClip = m_iClip;
+ //tfstate?
+ m_fInSpecialReload = 0;
+ SendWeaponAnim(10, 1);
+ m_flTimeWeaponIdle = 1000;
+ m_pPlayer->m_flNextAttack = 0.5;
+}
+
+BOOL CTFGrenadeLauncher::Deploy()
+{
+ return DefaultDeploy( "models/v_tfgl.mdl", "models/p_glauncher.mdl", 8, "mp5", 1 );
+}
+
+void CTFGrenadeLauncher::Reload()
+{
+ if ( m_pPlayer->ammo_rockets > 0 )
+ {
+ if ( m_iClip != 6 && m_flNextReload <= 0.0 && m_flNextPrimaryAttack <= 0.0 )
+ {
+ if (m_fInSpecialReload)
+ {
+ if ( m_fInSpecialReload == 1 )
+ {
+ if ( m_flTimeWeaponIdle <= 0.0 )
+ {
+ m_fInSpecialReload = 2;
+ m_flNextReload = m_fReloadTime;
+ m_flTimeWeaponIdle = m_fReloadTime;
+ }
+ }
+ else
+ {
+ m_iClip++;
+ m_pPlayer->ammo_rockets--;
+ m_fInSpecialReload = 1;
+ //m_pPlayer->tfstate &= 2;
+ }
+ }
+ else
+ {
+ SendWeaponAnim(4, 1);
+ //m_pPlayer->tfstate |= 2;
+ m_fInSpecialReload = 1;
+ m_pPlayer->m_flNextAttack = 0.1;
+ m_flTimeWeaponIdle = 0.1;
+ m_flNextSecondaryAttack = 0.1;
+ m_flNextPrimaryAttack = 0.0;
+ }
+ }
+ }
+}
+
+int CTFGrenadeLauncher::AddToPlayer( CBasePlayer *pPlayer )
+{
+ if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
+ {
+ MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
+ WRITE_BYTE( m_iId );
+ MESSAGE_END();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CTFGrenadeLauncher::WeaponIdle( void )
+{
+ ResetEmptySound();
+
+ if(m_flTimeWeaponIdle > 0.0)
+ return;
+
+ if(m_iClip > 0)
+ {
+ if(m_fInSpecialReload)
+ {
+ if(m_iClip == 6)
+ {
+ SendWeaponAnim(5, 1);
+ m_fInSpecialReload = 0;
+ m_flTimeWeaponIdle = 1.5;
+ return;
+ }
+ if(m_pPlayer->ammo_rockets > 0)
+ {
+ Reload();
+ return;
+ }
+ }
+ }
+ m_flTimeWeaponIdle = 3;
+ SendWeaponAnim(0, 1);
+}
+
+void CTFGrenadeLauncher::PrimaryAttack()
+{
+ if(m_pPlayer->ammo_rockets <= 0)
+ {
+ m_flNextPrimaryAttack = 1;
+ SendWeaponAnim(0, 1);
+ PlayEmptySound();
+ m_fInSpecialReload = 0;
+ //tfstate
+ return;
+ }
+
+ m_pPlayer->m_iWeaponVolume = 1000;
+ m_pPlayer->m_iWeaponFlash = 512;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireGL, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_fInSpecialReload = 0;
+ //tfstate
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ m_iClip--;
+ m_flTimeWeaponIdle = 0.6;
+ m_flNextPrimaryAttack = 0.6;
+ m_flNextSecondaryAttack = 0.6;
+}
diff --git a/dlls/tfc/incendiarycannon.cpp b/dlls/tfc/incendiarycannon.cpp
new file mode 100644
index 00000000..eafa6f7f
--- /dev/null
+++ b/dlls/tfc/incendiarycannon.cpp
@@ -0,0 +1,107 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_ic, CTFIncendiaryC )
+
+void CTFIncendiaryC::Spawn()
+{
+ Precache();
+
+ m_iId = 15;
+ SET_MODEL(ENT(pev), "models/w_rpg.mdl");
+ m_iDefaultAmmo = 50;
+ pev->solid = SOLID_TRIGGER;
+}
+
+int CTFIncendiaryC::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "rockets";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 20;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 4;
+ p->iPosition = 2;
+ p->iFlags = 0;
+ p->iMaxClip = -1;
+ p->iId = 15;
+ p->iWeight = 20;
+ return 1;
+}
+
+void CTFIncendiaryC::Holster()
+{
+ m_fInReload = 0;
+ SendWeaponAnim(4, 1);
+ m_pPlayer->m_flNextAttack = 0.5;
+}
+
+void CTFIncendiaryC::Precache()
+{
+ PRECACHE_MODEL("models/w_rpg.mdl");
+ PRECACHE_MODEL("models/v_rpg.mdl");
+ PRECACHE_MODEL("models/p_rpg.mdl");
+ PRECACHE_MODEL("models/p_rpg2.mdl");
+ PRECACHE_SOUND("weapons/9mmclip1.wav");
+ UTIL_PrecacheOther("tf_ic_rocket");
+ PRECACHE_SOUND("weapons/rocketfire1.wav");
+ PRECACHE_SOUND("weapons/glauncher.wav");
+ m_usFireIC = PRECACHE_EVENT(1, "events/wpn/tf_ic.sc");
+}
+
+void CTFIncendiaryC::WeaponIdle( void )
+{
+ if(m_flTimeWeaponIdle <= 0.0)
+ {
+ if(m_pPlayer->ammo_rockets <= 0)
+ m_flTimeWeaponIdle = 1;
+ else
+ {
+ m_flTimeWeaponIdle = 3;
+ SendWeaponAnim(1, 1);
+ }
+ }
+}
+
+BOOL CTFIncendiaryC::Deploy()
+{
+ if(m_iClip >= 0)
+ return DefaultDeploy( "models/v_rpg.mdl", "models/p_rpg.mdl", 5, "rpg", 1 );
+ else
+ return DefaultDeploy( "models/v_tfc_rpg.mdl", "models/p_rpg.mdl", 7, "rpg", 1 );
+}
+
+int CTFIncendiaryC::AddToPlayer( CBasePlayer *pPlayer )
+{
+ if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
+ {
+ MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
+ WRITE_BYTE( m_iId );
+ MESSAGE_END();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CTFIncendiaryC::PrimaryAttack()
+{
+ if(m_pPlayer->ammo_rockets <= 0)
+ {
+ PlayEmptySound();
+ return;
+ }
+
+ m_pPlayer->m_iWeaponVolume = 1000;
+ m_pPlayer->m_iWeaponFlash = 512;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireIC, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ m_pPlayer->ammo_rockets--;
+ m_flTimeWeaponIdle = 1.2;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.2;
+}
diff --git a/dlls/tfc/nailgun.cpp b/dlls/tfc/nailgun.cpp
new file mode 100644
index 00000000..e37fbeac
--- /dev/null
+++ b/dlls/tfc/nailgun.cpp
@@ -0,0 +1,95 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_ng, CTFNailgun )
+
+void CTFNailgun::Spawn()
+{
+ Precache();
+
+ m_iId = 4;
+ m_iDefaultAmmo = 50;
+ pev->solid = SOLID_TRIGGER;
+}
+
+void CTFNailgun::Precache( void )
+{
+ PRECACHE_MODEL("models/v_tfc_nailgun.mdl");
+ PRECACHE_MODEL("models/v_tfc_supernailgun.mdl");
+ PRECACHE_MODEL("models/p_nailgun.mdl");
+ PRECACHE_MODEL("models/p_nailgun2.mdl");
+ PRECACHE_MODEL("models/p_snailgun.mdl");
+ PRECACHE_MODEL("models/p_snailgun2.mdl");
+ PRECACHE_SOUND("items/9mmclip1.wav");
+ PRECACHE_SOUND("items/clipinsert1.wav");
+ PRECACHE_SOUND("items/cliprelease1.wav");
+ PRECACHE_SOUND("weapons/airgun_1.wav");
+ PRECACHE_SOUND("weapons/spike2.wav");
+ PRECACHE_SOUND("weapons/357_cock1.wav");
+ m_usFireNailGun = PRECACHE_EVENT(1, "events/wpn/tf_nail.sc");
+}
+
+int CTFNailgun::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 200;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 3;
+ p->iPosition = 4;
+ p->iFlags = 0;
+ p->iMaxClip = 0;
+ p->iId = 10;
+ p->iWeight = 15;
+ return 1;
+}
+
+BOOL CTFNailgun::Deploy()
+{
+ return DefaultDeploy( "models/v_tfc_nailgun.mdl", "models/p_nailgun.mdl", NAILGUN_DEPLOY, "mp5", 1 );
+}
+
+void CTFNailgun::WeaponIdle( void )
+{
+ if(m_flTimeWeaponIdle < 0.0)
+ {
+ m_flTimeWeaponIdle = 15;
+ SendWeaponAnim(NAILGUN_IDLE1, 1);
+ }
+}
+
+int CTFNailgun::AddToPlayer( CBasePlayer *pPlayer )
+{
+ if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
+ {
+ MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
+ WRITE_BYTE( m_iId );
+ MESSAGE_END();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CTFNailgun::PrimaryAttack()
+{
+ if(m_pPlayer->ammo_bolts <= 0)
+ {
+ PlayEmptySound();
+ return;
+ }
+
+ m_pPlayer->m_iWeaponVolume = 1000;
+ m_pPlayer->m_iWeaponFlash = 512;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireNailGun, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ m_pPlayer->ammo_bolts--;
+ m_flTimeWeaponIdle = 10;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;
+}
\ No newline at end of file
diff --git a/dlls/tfc/pipebomblauncher.cpp b/dlls/tfc/pipebomblauncher.cpp
new file mode 100644
index 00000000..9c450610
--- /dev/null
+++ b/dlls/tfc/pipebomblauncher.cpp
@@ -0,0 +1,62 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_pl, CTFPipebombLauncher )
+
+void CTFPipebombLauncher::Spawn()
+{
+ Precache();
+
+ SET_MODEL( ENT( pev ), "models/w_gauss.mdl" );
+ m_iId = 22;
+ m_iDefaultAmmo = 50;
+ m_fReloadTime = 0.666667;
+ pev->solid = SOLID_TRIGGER;
+ m_usFireGL = PRECACHE_EVENT(1, "events/wpn/tf_gl.sc");
+}
+
+int CTFPipebombLauncher::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "rockets";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 50;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 4;
+ p->iPosition = 4;
+ p->iFlags = 0;
+ p->iMaxClip = 6;
+ p->iId = 22;
+ p->iWeight = 15;
+ return 1;
+}
+
+void CTFPipebombLauncher::PrimaryAttack()
+{
+ if(m_pPlayer->ammo_rockets <= 0)
+ {
+ m_flNextPrimaryAttack = 1;
+ SendWeaponAnim(0, 1);
+ PlayEmptySound();
+ m_fInSpecialReload = 0;
+ //tfstate
+ return;
+ }
+
+ m_pPlayer->m_iWeaponVolume = 1000;
+ m_pPlayer->m_iWeaponFlash = 512;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireGL, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_fInSpecialReload = 0;
+ //tfstate
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ m_iClip--;
+ m_flTimeWeaponIdle = 0.6;
+ m_flNextPrimaryAttack = 0.6;
+ m_flNextSecondaryAttack = 0.6;
+}
diff --git a/dlls/tfc/railgun.cpp b/dlls/tfc/railgun.cpp
new file mode 100644
index 00000000..feeb7f30
--- /dev/null
+++ b/dlls/tfc/railgun.cpp
@@ -0,0 +1,82 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_railgun, CTFRailgun )
+
+void CTFRailgun::Spawn()
+{
+ Precache();
+
+ //pev->classname = STRING("tf_weapon_railgun");
+ SET_MODEL( ENT( pev ), "models/w_gauss.mdl" );
+ m_iId = 21;
+ m_iDefaultAmmo = 17;
+ pev->solid = SOLID_TRIGGER;
+}
+
+int CTFRailgun::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 50;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 1;
+ p->iPosition = 2;
+ p->iFlags = 0;
+ p->iMaxClip = -1;
+ p->iId = 21;
+ p->iWeight = 10;
+ return 1;
+}
+
+void CTFRailgun::Precache()
+{
+ PRECACHE_MODEL("models/v_tfc_railgun.mdl");
+ PRECACHE_MODEL("models/w_gauss.mdl");
+ PRECACHE_MODEL("models/p_9mmhandgun.mdl");
+ PRECACHE_MODEL("models/p_9mmhandgun2.mdl");
+ PRECACHE_SOUND("weapons/railgun.wav");
+ m_usFireRail = PRECACHE_EVENT(1, "events/wpn/tf_rail.sc");
+}
+
+BOOL CTFRailgun::Deploy()
+{
+ return DefaultDeploy( "models/v_tfc_railgun.mdl", "models/p_9mmhandgun.mdl", 2, "onehanded", 1 );
+}
+
+void CTFRailgun::PrimaryAttack()
+{
+ if(m_pPlayer->ammo_bolts <= 0)
+ {
+ PlayEmptySound();
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.2;
+ return;
+ }
+
+ m_pPlayer->m_iWeaponVolume = 600;
+ m_pPlayer->m_iWeaponFlash = 256;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireRail, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_pPlayer->pev->effects |= EF_MUZZLEFLASH;
+ m_pPlayer->SetAnimation(PLAYER_ATTACK1);
+ m_pPlayer->ammo_bolts--;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.4;
+ m_flTimeWeaponIdle = 12.5;
+}
+
+void CTFRailgun::WeaponIdle( void )
+{
+ ResetEmptySound();
+
+ if(m_flTimeWeaponIdle <= 0.0)
+ {
+ m_flTimeWeaponIdle = 12.5;
+ SendWeaponAnim(0, 1);
+ }
+}
diff --git a/dlls/tfc/rpg.cpp b/dlls/tfc/rpg.cpp
new file mode 100644
index 00000000..ffb1bc64
--- /dev/null
+++ b/dlls/tfc/rpg.cpp
@@ -0,0 +1,193 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_rpg, CTFRpg )
+
+void CTFRpg::Spawn()
+{
+ Precache();
+
+ m_iId = 14;
+ SET_MODEL(ENT(pev), "models/w_rpg.mdl");
+ m_iDefaultAmmo = 50;
+ m_fReloadTime = 1.25;
+ pev->solid = SOLID_TRIGGER;
+}
+
+int CTFRpg::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "rockets";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 50;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 4;
+ p->iPosition = 1;
+ p->iFlags = 0;
+ p->iMaxClip = 4;
+ p->iId = 14;
+ p->iWeight = 20;
+ return 1;
+}
+
+void CTFRpg::Holster()
+{
+ //тф стейт чот там
+ m_fInSpecialReload = 0;
+ m_pPlayer->m_flNextAttack = 0.5;
+}
+
+void CTFRpg::Precache()
+{
+ PRECACHE_MODEL("models/v_tfc_rpg.mdl");
+ PRECACHE_MODEL("models/p_srpg.mdl");
+ PRECACHE_MODEL("models/p_shotgun2.mdl");
+ PRECACHE_MODEL("models/p_rpg2.mdl");
+ PRECACHE_SOUND("weapons/9mmclip1.wav");
+ UTIL_PrecacheOther("tf_rpg_rocket");
+ PRECACHE_SOUND("weapons/rocketfire1.wav");
+ PRECACHE_SOUND("weapons/glauncher.wav");
+ m_usFireRPG = PRECACHE_EVENT(1, "events/wpn/tf_rpg.sc");
+}
+
+void CTFRpg::Reload( void )
+{
+ if ( m_pPlayer->ammo_rockets == 0 || m_iClip == 4 || m_flNextReload > 0.0 || m_flNextPrimaryAttack > 0.0)
+ return;
+
+ if ( m_fInSpecialReload )
+ {
+ if ( m_fInSpecialReload == 1 )
+ {
+ if ( m_flTimeWeaponIdle <= gpGlobals->time )
+ {
+ m_fInSpecialReload = 2;
+ SendWeaponAnim(TFCRPG_RELCYCLE, 1);
+ m_flNextReload = UTIL_WeaponTimeBase() + m_fReloadTime;
+ m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + m_fReloadTime;
+ }
+ }
+ else
+ {
+ m_iClip += 1;
+ m_pPlayer->ammo_rockets -= 1;
+ m_fInSpecialReload = 1;
+ //m_pPlayer->tfstate &= 2;
+ }
+ }
+ else
+ {
+ SendWeaponAnim(TFCRPG_RELSTART, 1);
+ //m_pPlayer->tfstate |= 2;
+ m_fInSpecialReload = 1;
+ m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.1;
+ m_flTimeWeaponIdle = 0.1;
+ m_flNextSecondaryAttack = 0.1;
+ m_flNextPrimaryAttack = 0.0;
+ }
+}
+
+void CTFRpg::WeaponIdle( void )
+{
+ ResetEmptySound();
+ if (m_flTimeWeaponIdle > 0.0)
+ return;
+
+ if(m_iClip > 0)
+ {
+ if (!m_fInSpecialReload)
+ {
+ if (m_pPlayer->ammo_rockets > 0)
+ {
+ if(m_iClip == 0)
+ SendWeaponAnim(TFCRPG_FIDGET2, 1);
+ else
+ SendWeaponAnim(TFCRPG_IDLE, 1);
+ m_flTimeWeaponIdle = 3;
+ }
+ else
+ m_flTimeWeaponIdle = 1;
+ return;
+ }
+ if (m_iClip == 4)
+ {
+ SendWeaponAnim(TFCRPG_RELEND, 1);
+ m_fInSpecialReload = 0;
+ m_flTimeWeaponIdle = 1.5;
+ return;
+ }
+ }
+ else if (!m_fInSpecialReload)
+ {
+ if (m_pPlayer->ammo_rockets > 0)
+ {
+ Reload();
+ return;
+ }
+
+ if (m_pPlayer->ammo_rockets > 0)
+ {
+ if(m_iClip == 0)
+ SendWeaponAnim(TFCRPG_FIDGET2, 1);
+ else
+ SendWeaponAnim(TFCRPG_IDLE, 1);
+ m_flTimeWeaponIdle = 3;
+ }
+ else
+ m_flTimeWeaponIdle = 1;
+ return;
+ }
+
+ if (m_pPlayer->ammo_rockets > 0)
+ {
+ Reload();
+ return;
+ }
+
+ SendWeaponAnim(TFCRPG_RELEND, 1);
+ m_fInSpecialReload = 0;
+ m_flTimeWeaponIdle = 1.5;
+ return;
+}
+
+BOOL CTFRpg::Deploy()
+{
+ if(m_iClip >= 0)
+ return DefaultDeploy( "models/v_tfc_rpg.mdl", "models/p_srpg.mdl", TFCRPG_DRAW1, "rpg", 1 );
+ else
+ return DefaultDeploy( "models/v_tfc_rpg.mdl", "models/p_srpg.mdl", TFCRPG_DRAW2, "rpg", 1 );
+}
+
+int CTFRpg::AddToPlayer( CBasePlayer *pPlayer )
+{
+ if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
+ {
+ MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
+ WRITE_BYTE( m_iId );
+ MESSAGE_END();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CTFRpg::PrimaryAttack()
+{
+ if(m_iClip <= 0)
+ return;
+
+ m_pPlayer->m_iWeaponVolume = 1000;
+ m_pPlayer->m_iWeaponFlash = 512;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireRPG, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ m_fInSpecialReload = 0;
+ //tfstatatata
+ m_iClip--;
+ m_flTimeWeaponIdle = 0.8;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.8;
+}
\ No newline at end of file
diff --git a/dlls/tfc/shotgun.cpp b/dlls/tfc/shotgun.cpp
new file mode 100644
index 00000000..f7def98d
--- /dev/null
+++ b/dlls/tfc/shotgun.cpp
@@ -0,0 +1,204 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_shotgun, CTFShotgun )
+
+void CTFShotgun::Spawn()
+{
+ Precache();
+
+ m_iId = 8;
+ m_iDefaultAmmo = 8;
+ m_iMaxClipSize = 8;
+ m_iShellsReloaded = 1;
+ m_fReloadTime = 0.25;
+ m_flPumpTime = 1000;
+ pev->solid = SOLID_TRIGGER;
+}
+
+void CTFShotgun::Precache( void )
+{
+ PRECACHE_MODEL("models/v_tfc_12gauge.mdl");
+ PRECACHE_MODEL("models/p_smallshotgun.mdl");
+ PRECACHE_MODEL("models/p_shotgun2.mdl");
+ m_iShell = PRECACHE_MODEL("models/shotgunshell.mdl");
+ PRECACHE_SOUND("weapons/dbarrel1.wav");
+ PRECACHE_SOUND("weapons/sbarrel1.wav");
+ PRECACHE_SOUND("weapons/reload1.wav");
+ PRECACHE_SOUND("weapons/reload3.wav");
+ PRECACHE_SOUND("weapons/357_cock1.wav");
+ PRECACHE_SOUND("weapons/scock1.wav");
+ PRECACHE_SOUND("weapons/shotgn2.wav");
+ m_usFireShotgun = PRECACHE_EVENT(1, "events/wpn/tf_sg.sc");
+ m_usReloadShotgun = PRECACHE_EVENT(1, "events/wpn/tf_sgreload.sc");
+ m_usPumpShotgun = PRECACHE_EVENT(1, "events/wpn/tf_sgpump.sc");
+}
+
+int CTFShotgun::AddToPlayer( CBasePlayer *pPlayer )
+{
+ if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
+ {
+ MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
+ WRITE_BYTE( m_iId );
+ MESSAGE_END();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int CTFShotgun::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "buckshot";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 200;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 1;
+ p->iPosition = 3;
+ p->iFlags = 0;
+ p->iMaxClip = m_iMaxClipSize;
+ p->iId = 8;
+ p->iWeight = 15;
+ return 1;
+}
+
+BOOL CTFShotgun::Deploy()
+{
+ return DefaultDeploy( "models/v_tfc_12gauge.mdl", "models/p_smallshotgun.mdl", TFCSHOTGUN_DRAW, "shotgun", 1 );
+}
+
+void CTFShotgun::PrimaryAttack()
+{
+ float flDelta;
+ vec3_t *p_vecDirShooting;
+ vec3_t vecSrc, vecAiming;
+ vec3_t spread;
+
+ if ( m_iClip <= 0 )
+ {
+ Reload();
+ if( m_iClip == 0 )
+ PlayEmptySound();
+ }
+ else
+ {
+ m_pPlayer->m_iWeaponVolume = 1000;
+ m_pPlayer->m_iWeaponFlash = 256;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireShotgun, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ vecSrc = m_pPlayer->GetGunPosition();
+ vecAiming = m_pPlayer->GetAutoaimVector(AUTOAIM_5DEGREES);
+ spread.x = 0.04;
+ spread.y = 0.04;
+ spread.z = 0;
+ m_pPlayer->FireBullets(6, vecSrc, vecAiming, spread, 2048.0, 6, 0, 4, 0);
+ if ( !m_iClip && m_pPlayer->ammo_buckshot <= 0 )
+ {
+ p_vecDirShooting = 0;
+ flDelta = 0.0;
+ }
+ m_iClip--;
+ pev->effects |= EF_MUZZLEFLASH;
+ m_fInSpecialReload = 0;
+ m_flTimeWeaponIdle = 5;
+ //m_pPlayer->tfstate &= 2;
+ if ( m_iClip )
+ m_flPumpTime = 0.5;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
+ }
+}
+
+void CTFShotgun::Reload( void )
+{
+ if ( m_pPlayer->ammo_buckshot >= m_iShellsReloaded )
+ {
+ if ( m_iClip != m_iMaxClipSize && m_flNextReload <= 0.0 && m_flNextPrimaryAttack <= 0.0 )
+ {
+ if (m_fInSpecialReload)
+ {
+ if ( m_fInSpecialReload == 1 )
+ {
+ if ( m_flTimeWeaponIdle <= 0.0 )
+ {
+ m_fInSpecialReload = 2;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usReloadShotgun, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0);
+ m_flNextReload = m_fReloadTime;
+ m_flTimeWeaponIdle = m_fReloadTime;
+ }
+ }
+ else
+ {
+ m_iClip = m_iShellsReloaded + m_iClip;
+ m_pPlayer->ammo_buckshot -= m_iShellsReloaded;
+ m_fInSpecialReload = 1;
+ //m_pPlayer->tfstate &= 2;
+ }
+ }
+ else
+ {
+ SendWeaponAnim(TFCSHOTGUN_STARTRELOAD, 1);
+ //m_pPlayer->tfstate |= 2;
+ m_fInSpecialReload = 1;
+ m_pPlayer->m_flNextAttack = 0.1;
+ m_flTimeWeaponIdle = 0.1;
+ m_flNextSecondaryAttack = 0.1;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;
+ }
+ }
+ }
+}
+
+void CTFShotgun::WeaponIdle( void )
+{
+ int iAnim;
+
+ ResetEmptySound();
+ if ( m_flPumpTime != 1000.0 && m_flPumpTime < 0.0 )
+ {
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usPumpShotgun, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0);
+ m_flPumpTime = 1000;
+ }
+
+ if (m_flTimeWeaponIdle < 0.0 )
+ {
+ if ( m_fInSpecialReload )
+ {
+ if ( m_iClip == m_iMaxClipSize || m_pPlayer->ammo_buckshot < m_iShellsReloaded )
+ {
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usPumpShotgun, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 1, 0);
+ m_fInSpecialReload = 0;
+ m_flTimeWeaponIdle = 1.5;
+ return;
+ }
+ Reload();
+ return;
+ }
+
+ int i = UTIL_SharedRandomLong(m_pPlayer->random_seed, 0, 20);
+ if ( i == 5 * (i / 5) )
+ {
+ if ( i == 20 * (i / 20) )
+ {
+ m_flTimeWeaponIdle = 2.22222;
+ iAnim = TFCSHOTGUN_IDLE;
+ }
+ else
+ {
+ m_flTimeWeaponIdle = 2.10526;
+ iAnim = TFCSHOTGUN_IDLE4;
+ }
+ }
+ else
+ {
+ m_flTimeWeaponIdle = 5;
+ iAnim = TFCSHOTGUN_DEEPIDLE;
+ }
+ SendWeaponAnim(iAnim, 1);
+ }
+}
\ No newline at end of file
diff --git a/dlls/tfc/sniperrifle.cpp b/dlls/tfc/sniperrifle.cpp
new file mode 100644
index 00000000..c14e5639
--- /dev/null
+++ b/dlls/tfc/sniperrifle.cpp
@@ -0,0 +1,228 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( laser_spot, CLaserSpot )
+LINK_ENTITY_TO_CLASS( tf_weapon_sniperrifle, CTFSniperRifle )
+
+CLaserSpot *CLaserSpot::CreateSpot( void )
+{
+ CLaserSpot *pSpot = GetClassPtr( (CLaserSpot *)NULL );
+ pSpot->Spawn();
+ pSpot->pev->classname = MAKE_STRING( "laser_spot" );
+ return pSpot;
+}
+
+void CLaserSpot::Spawn( void )
+{
+ Precache();
+ pev->movetype = MOVETYPE_NONE;
+ pev->solid = SOLID_NOT;
+ pev->rendermode = kRenderGlow;
+ pev->renderfx = kRenderFxNoDissipation;
+ pev->renderamt = 255;
+ SET_MODEL( ENT( pev ), "sprites/laserdot.spr" );
+ UTIL_SetOrigin( pev, pev->origin );
+}
+
+void CLaserSpot::Suspend( float flSuspendTime )
+{
+ pev->effects |= EF_NODRAW;
+ SetThink( &CLaserSpot::Revive );
+ pev->nextthink = gpGlobals->time + flSuspendTime;
+}
+
+void CLaserSpot::Revive()
+{
+ pev->effects &= ~EF_NODRAW;
+ SetThink( NULL );
+}
+
+void CLaserSpot::Precache()
+{
+ PRECACHE_MODEL( "sprites/laserdot.spr" );
+}
+
+void CTFSniperRifle::Spawn()
+{
+ Precache();
+
+ m_iId = 6;
+ m_iDefaultAmmo = 5;
+ m_fAimedDamage = 0;
+ m_fNextAimBonus = -1;
+ pev->solid = SOLID_TRIGGER;
+}
+
+void CTFSniperRifle::Precache()
+{
+ PRECACHE_MODEL("models/v_tfc_sniper.mdl");
+ PRECACHE_MODEL("models/p_sniper.mdl");
+ PRECACHE_MODEL("models/p_sniper2.mdl");
+ PRECACHE_SOUND("ambience/rifle1.wav");
+ m_usFireSniper = PRECACHE_EVENT(1, "events/wpn/tf_sniper.sc");
+ m_usSniperHit = PRECACHE_EVENT(1, "events/wpn/tf_sniperhit.sc");
+}
+
+int CTFSniperRifle::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "buckshot";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 75;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 1;
+ p->iPosition = 1;
+ p->iFlags = 0;
+ p->iMaxClip = -1;
+ p->iId = 6;
+ p->iWeight = 10;
+ return 1;
+}
+
+void CTFSniperRifle::SecondaryAttack()
+{
+ if(m_fInZoom)
+ {
+ m_pPlayer->m_iFOV = 0;
+ pev->fov = 0;
+ m_fInZoom = 0;
+ }
+ else
+ {
+ m_pPlayer->m_iFOV = 20;
+ pev->fov = 20;
+ m_fInZoom = 1;
+ }
+
+ pev->nextthink = gpGlobals->time + 0.1;
+ m_flNextSecondaryAttack = 0.3;
+}
+
+void CTFSniperRifle::Holster()
+{
+ m_fInReload = 0;
+ if(m_fInZoom)
+ SecondaryAttack();
+
+ //m_pPlayer->tfstate &= 2;
+ //тф сет спид
+
+ if(m_pSpot)
+ m_pSpot->Killed(0, 0);
+
+ m_fAimedDamage = 0;
+ m_pPlayer->m_flNextAttack = 0.5;
+ SendWeaponAnim(SNIPER_HOLSTER, 1);
+}
+
+BOOL CTFSniperRifle::Deploy()
+{
+ m_pSpot = 0;
+ m_flTimeWeaponIdle = 0.5;
+ m_fAimedDamage = 0;
+ m_iSpotActive = 0;
+
+ //Velaron: "autosniper" draw animation
+ return DefaultDeploy( "models/v_tfc_sniper.mdl", "models/p_sniper.mdl", SNIPER_DRAW, "mp5", 1 );
+}
+
+int CTFSniperRifle::AddToPlayer( CBasePlayer *pPlayer )
+{
+ if( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
+ {
+ MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
+ WRITE_BYTE( m_iId );
+ MESSAGE_END();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CTFSniperRifle::UpdateSpot()
+{
+ vec3_t vecSrc, vecEnd;
+ TraceResult tr;
+
+ if(!m_iSpotActive)
+ return;
+
+ if(!m_pSpot)
+ {
+ m_pSpot = CLaserSpot::CreateSpot();
+ //Velaron: effect 256
+ //m_pSpot->pev->effects |= 256;
+ m_pSpot->pev->owner = ENT(m_pPlayer->pev);
+ }
+
+ UTIL_MakeVectors(m_pPlayer->pev->v_angle);
+ vecSrc = m_pPlayer->GetGunPosition();
+ vecEnd.x = gpGlobals->v_forward.x * 8192.0 + vecSrc.x;
+ vecEnd.y = gpGlobals->v_forward.y * 8192.0 + vecSrc.y;
+ vecEnd.z = gpGlobals->v_forward.z * 8192.0 + vecSrc.z;
+ UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr);
+ UTIL_SetOrigin(m_pSpot->pev, tr.vecEndPos);
+ m_pSpot->pev->renderamt = 0.25 * m_fAimedDamage + 150.0;
+}
+
+void CTFSniperRifle::WeaponIdle( void )
+{
+ if(m_iSpotActive)
+ UpdateSpot();
+
+ if(m_flTimeWeaponIdle < 0.0)
+ {
+ m_flTimeWeaponIdle = 12.5;
+ SendWeaponAnim(SNIPER_IDLE, 1);
+ }
+}
+
+//Velaron: finish this nightmare
+void CTFSniperRifle::PrimaryAttack()
+{
+ vec3_t anglesAim;
+ vec3_t vecAim;
+ vec3_t vecSrc, vecEnd;
+ TraceResult tr;
+
+ if(m_pPlayer->ammo_buckshot <= 0)
+ {
+ PlayEmptySound();
+ return;
+ }
+
+ m_pPlayer->m_iWeaponVolume = 200;
+ m_pPlayer->m_iWeaponFlash = 512;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireSniper, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, m_fAimedDamage, 0, 0, 0);
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ m_flTimeWeaponIdle = 0.5;
+ anglesAim.x = m_pPlayer->pev->v_angle.x + m_pPlayer->pev->punchangle.x;
+ anglesAim.y = m_pPlayer->pev->v_angle.y + m_pPlayer->pev->punchangle.y;
+ anglesAim.z = m_pPlayer->pev->v_angle.z + m_pPlayer->pev->punchangle.z;
+ UTIL_MakeVectors(anglesAim);
+ vecAim = m_pPlayer->GetGunPosition();
+ UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr);
+
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usSniperHit, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+
+ m_pPlayer->ammo_buckshot--;
+}
+
+void CTFSniperRifle::ItemPostFrame()
+{
+/*
+ if(!m_pPlayer->pev->button & 8 || m_flNextSecondaryAttack > 0.0)
+ {
+ if(m_pPlayer->m_afButtonReleased & 1 && m_flNextPrimaryAttack <= 0.0)
+ {
+ if(tfstate & 8)
+ {}
+ }
+ }
+*/
+}
\ No newline at end of file
diff --git a/dlls/tfc/spanner.cpp b/dlls/tfc/spanner.cpp
new file mode 100644
index 00000000..f232812f
--- /dev/null
+++ b/dlls/tfc/spanner.cpp
@@ -0,0 +1,68 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_spanner, CTFSpanner )
+
+void CTFSpanner::Spawn()
+{
+ Precache();
+
+ m_iId = 4;
+ SET_MODEL(ENT(pev), "models/w_egon.mdl");
+ m_iDefaultAmmo = 50;
+ pev->solid = SOLID_TRIGGER;
+ classid = 1;
+}
+
+void CTFSpanner::Precache()
+{
+ PRECACHE_MODEL("models/v_tfc_spanner.mdl");
+ PRECACHE_MODEL("models/p_spanner.mdl");
+ PRECACHE_MODEL("models/p_spanner2.mdl");
+ m_usAxe = PRECACHE_EVENT(1, "events/wpn/tf_axe.sc");
+ m_usAxeDecal = PRECACHE_EVENT(1, "events/wpn/tf_axedecal.sc");
+}
+
+void CTFSpanner::Holster()
+{
+ SendWeaponAnim(5, 1);
+ m_pPlayer->m_flNextAttack = 0.5;
+}
+
+int CTFSpanner::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "uranium";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = -1;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 0;
+ p->iPosition = 2;
+ p->iFlags = 0;
+ p->iMaxClip = -1;
+ p->iId = 4;
+ p->iWeight = 0;
+ return 1;
+}
+
+BOOL CTFSpanner::Deploy()
+{
+ return DefaultDeploy( "models/v_tfc_spanner.mdl", "models/p_spanner.mdl", 4, "crowbar", 1 );
+}
+
+void CTFSpanner::WeaponIdle( void )
+{
+ ResetEmptySound();
+
+ if(m_flTimeWeaponIdle <= 0.0)
+ {
+ m_flTimeWeaponIdle = 12.5;
+ SendWeaponAnim(0, 1);
+ }
+}
\ No newline at end of file
diff --git a/dlls/tfc/supernailgun.cpp b/dlls/tfc/supernailgun.cpp
new file mode 100644
index 00000000..fb19abc4
--- /dev/null
+++ b/dlls/tfc/supernailgun.cpp
@@ -0,0 +1,56 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_superng, CTFSuperNailgun )
+
+void CTFSuperNailgun::Precache()
+{
+ CTFNailgun::Precache();
+ m_usFireSuperNailGun = PRECACHE_EVENT(1, "events/wpn/tf_snail.sc");
+}
+
+int CTFSuperNailgun::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 150;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 3;
+ p->iPosition = 1;
+ p->iFlags = 0;
+ p->iMaxClip = 0;
+ p->iId = 11;
+ p->iWeight = 15;
+ return 1;
+}
+
+BOOL CTFSuperNailgun::Deploy()
+{
+ return DefaultDeploy( "models/v_tfc_supernailgun.mdl", "models/p_snailgun.mdl", NAILGUN_DEPLOY, "mp5", 1 );
+}
+
+void CTFSuperNailgun::PrimaryAttack()
+{
+ if(m_pPlayer->ammo_bolts <= 0)
+ {
+ PlayEmptySound();
+ return;
+ }
+
+ m_pPlayer->m_iWeaponVolume = 1000;
+ m_pPlayer->m_iWeaponFlash = 512;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireSuperNailGun, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ m_pPlayer->ammo_bolts -= 2;
+ if(m_pPlayer->ammo_bolts < 0)
+ m_pPlayer->ammo_bolts = 0;
+ m_flTimeWeaponIdle = 10;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1;
+}
\ No newline at end of file
diff --git a/dlls/tfc/supershotgun.cpp b/dlls/tfc/supershotgun.cpp
new file mode 100644
index 00000000..5c2bd1b2
--- /dev/null
+++ b/dlls/tfc/supershotgun.cpp
@@ -0,0 +1,109 @@
+#include "extdll.h"
+#include "util.h"
+#include "cbase.h"
+#include "monsters.h"
+#include "weapons.h"
+#include "nodes.h"
+#include "player.h"
+#include "gamerules.h"
+
+LINK_ENTITY_TO_CLASS( tf_weapon_supershotgun, CTFSuperShotgun )
+
+void CTFSuperShotgun::Spawn()
+{
+ Precache();
+
+ m_iId = 9;
+ m_iDefaultAmmo = 16;
+ m_iMaxClipSize = 16;
+ m_iShellsReloaded = 2;
+ m_fReloadTime = 0.375;
+ m_flPumpTime = 1000;
+ pev->solid = SOLID_TRIGGER;
+}
+
+void CTFSuperShotgun::Precache( void )
+{
+ PRECACHE_MODEL("models/v_tfc_shotgun.mdl");
+ PRECACHE_MODEL("models/p_shotgun.mdl");
+ PRECACHE_MODEL("models/p_shotgun2.mdl");
+ m_iShell = PRECACHE_MODEL("models/shotgunshell.mdl");
+ PRECACHE_SOUND("weapons/dbarrel1.wav");
+ PRECACHE_SOUND("weapons/sbarrel1.wav");
+ PRECACHE_SOUND("weapons/reload1.wav");
+ PRECACHE_SOUND("weapons/reload3.wav");
+ PRECACHE_SOUND("weapons/357_cock1.wav");
+ PRECACHE_SOUND("weapons/scock1.wav");
+ PRECACHE_SOUND("weapons/shotgn2.wav");
+ m_usFireSuperShotgun = PRECACHE_EVENT(1, "events/wpn/tf_ssg.sc");
+ m_usReloadShotgun = PRECACHE_EVENT(1, "events/wpn/tf_sgreload.sc");
+ m_usPumpShotgun = PRECACHE_EVENT(1, "events/wpn/tf_sgpump.sc");
+}
+
+int CTFSuperShotgun::GetItemInfo( ItemInfo *p )
+{
+ p->pszAmmo1 = "buckshot";
+ p->pszName = STRING( pev->classname );
+ p->iMaxAmmo1 = 200;
+ p->pszAmmo2 = 0;
+ p->iMaxAmmo2 = -1;
+ p->iSlot = 2;
+ p->iPosition = 2;
+ p->iFlags = 0;
+ p->iMaxClip = m_iMaxClipSize;
+ p->iId = 9;
+ p->iWeight = 15;
+ return 1;
+}
+
+BOOL CTFSuperShotgun::Deploy()
+{
+ return DefaultDeploy( "models/v_tfc_shotgun.mdl", "models/p_shotgun.mdl", 6, "shotgun", 1 );
+}
+
+void CTFSuperShotgun::PrimaryAttack()
+{
+ float flDelta;
+ vec3_t *p_vecDirShooting;
+ vec3_t vecSrc, vecAiming;
+ vec3_t spread;
+
+ if ( m_iClip == 1 )
+ {
+ CTFShotgun::PrimaryAttack();
+ return;
+ }
+
+ if ( m_iClip <= 0 )
+ {
+ Reload();
+ if( m_iClip == 0 )
+ PlayEmptySound();
+ }
+ else
+ {
+ m_pPlayer->m_iWeaponVolume = 1000;
+ m_pPlayer->m_iWeaponFlash = 256;
+ PLAYBACK_EVENT_FULL(1, ENT(m_pPlayer->pev), m_usFireSuperShotgun, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, 0, 0, 0);
+ m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
+ vecSrc = m_pPlayer->GetGunPosition();
+ vecAiming = m_pPlayer->GetAutoaimVector(AUTOAIM_5DEGREES);
+ spread.x = 0.04;
+ spread.y = 0.04;
+ spread.z = 0;
+ m_pPlayer->FireBullets(14, vecSrc, vecAiming, spread, 2048.0, 6, 4, 4, 0);
+ if ( !m_iClip && m_pPlayer->ammo_buckshot <= 0 )
+ {
+ p_vecDirShooting = 0;
+ flDelta = 0.0;
+ }
+ m_iClip -= 2;
+ pev->effects |= EF_MUZZLEFLASH;
+ m_fInSpecialReload = 0;
+ m_flTimeWeaponIdle = 5;
+ //m_pPlayer->tfstate &= 2;
+ if ( m_iClip )
+ m_flPumpTime = 0.7;
+ m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;
+ }
+}
\ No newline at end of file
diff --git a/dlls/weapons.h b/dlls/tfc/weapons.h
similarity index 59%
rename from dlls/weapons.h
rename to dlls/tfc/weapons.h
index 312f5531..67b4ecd3 100644
--- a/dlls/weapons.h
+++ b/dlls/tfc/weapons.h
@@ -1,9 +1,9 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
-*
-* This product contains software technology licensed from Id
-* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
+*
+* This product contains software technology licensed from Id
+* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
@@ -12,7 +12,6 @@
* without written permission from Valve LLC.
*
****/
-#pragma once
#ifndef WEAPONS_H
#define WEAPONS_H
@@ -21,63 +20,13 @@
class CBasePlayer;
extern int gmsgWeapPickup;
-void DeactivateSatchels( CBasePlayer *pOwner );
-
-// Contact Grenade / Timed grenade / Satchel Charge
-class CGrenade : public CBaseMonster
-{
-public:
- void Spawn( void );
-
- typedef enum { SATCHEL_DETONATE = 0, SATCHEL_RELEASE } SATCHELCODE;
-
- static CGrenade *ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time );
- static CGrenade *ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity );
- static CGrenade *ShootSatchelCharge( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity );
- static void UseSatchelCharges( entvars_t *pevOwner, SATCHELCODE code );
-
- void Explode( Vector vecSrc, Vector vecAim );
- void Explode( TraceResult *pTrace, int bitsDamageType );
- void EXPORT Smoke( void );
-
- void EXPORT BounceTouch( CBaseEntity *pOther );
- void EXPORT SlideTouch( CBaseEntity *pOther );
- void EXPORT ExplodeTouch( CBaseEntity *pOther );
- void EXPORT DangerSoundThink( void );
- void EXPORT PreDetonate( void );
- void EXPORT Detonate( void );
- void EXPORT DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
- void EXPORT TumbleThink( void );
-
- virtual void BounceSound( void );
- virtual int BloodColor( void ) { return DONT_BLEED; }
- virtual void Killed( entvars_t *pevAttacker, int iGib );
-
- BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet.
-};
-
// constant items
#define ITEM_HEALTHKIT 1
#define ITEM_ANTIDOTE 2
#define ITEM_SECURITY 3
#define ITEM_BATTERY 4
-#define WEAPON_NONE 0
-#define WEAPON_CROWBAR 1
-#define WEAPON_GLOCK 2
-#define WEAPON_PYTHON 3
-#define WEAPON_MP5 4
-#define WEAPON_CHAINGUN 5
-#define WEAPON_CROSSBOW 6
-#define WEAPON_SHOTGUN 7
-#define WEAPON_RPG 8
-#define WEAPON_GAUSS 9
-#define WEAPON_EGON 10
-#define WEAPON_HORNETGUN 11
-#define WEAPON_HANDGRENADE 12
-#define WEAPON_TRIPMINE 13
-#define WEAPON_SATCHEL 14
-#define WEAPON_SNARK 15
+#define WEAPON_CROWBAR 1
#define WEAPON_ALLWEAPONS (~(1<absmin = pev->origin + Vector(-16, -16, -5);
- pev->absmax = pev->origin + Vector(16, 16, 28);
- }
-
- void PrimaryAttack( void );
- BOOL Deploy( void );
- void Holster( int skiplocal = 0 );
- void WeaponIdle( void );
-
- virtual BOOL UseDecrement( void )
- {
-#if defined( CLIENT_WEAPONS )
- return TRUE;
-#else
- return FALSE;
-#endif
- }
-
-private:
- unsigned short m_usTripFire;
-};
-
-class CSqueak : public CBasePlayerWeapon
-{
-public:
- void Spawn( void );
- void Precache( void );
- int iItemSlot( void ) { return 5; }
- int GetItemInfo(ItemInfo *p);
-
- void PrimaryAttack( void );
- void SecondaryAttack( void );
- BOOL Deploy( void );
- void Holster( int skiplocal = 0 );
- void WeaponIdle( void );
- int m_fJustThrown;
+ int m_fInReload;
+ float m_flNextReload;
+ int m_iShell;
+ int m_iMaxClipSize;
+ int m_iShellsReloaded;
+ int m_fReloadTime;
virtual BOOL UseDecrement( void )
{
-#if defined( CLIENT_WEAPONS )
- return TRUE;
-#else
- return FALSE;
-#endif
+ return true;
}
+ unsigned short m_usReloadShotgun;
+ unsigned short m_usPumpShotgun;
+
private:
- unsigned short m_usSnarkFire;
+ unsigned short m_usFireShotgun;
};
+
+class CTFSuperShotgun : public CTFShotgun
+{
+public:
+ void Spawn(void);
+ void Precache(void);
+ int GetItemInfo(ItemInfo *p);
+ void PrimaryAttack(void);
+ BOOL Deploy();
+
+private:
+ unsigned short m_usFireSuperShotgun;
+};
+
+enum tfc_nailgun_e
+{
+ NAILGUN_LONGIDLE = 0,
+ NAILGUN_IDLE1,
+ NAILGUN_GRENADE,
+ NAILGUN_RELOAD,
+ NAILGUN_DEPLOY,
+ NAILGUN_SHOOT1,
+ NAILGUN_SHOOT2,
+ NAILGUN_SHOOT3
+};
+
+class CTFNailgun : public CBasePlayerWeapon
+{
+public:
+ void Spawn(void);
+ void Precache(void);
+ int GetItemInfo(ItemInfo *p);
+ int AddToPlayer(CBasePlayer *pPlayer);
+ void PrimaryAttack(void);
+ BOOL Deploy();
+ void WeaponIdle(void);
+
+ virtual BOOL UseDecrement( void )
+ {
+ return true;
+ }
+
+ unsigned short m_usFireNailGun;
+};
+
+class CTFSuperNailgun : public CTFNailgun
+{
+public:
+ void Precache(void);
+ int GetItemInfo(ItemInfo *p);
+ void PrimaryAttack(void);
+ BOOL Deploy();
+
+private:
+ unsigned short m_usFireSuperNailGun;
+};
+
+class CTFGrenadeLauncher : public CBasePlayerWeapon
+{
+public:
+ void Spawn(void);
+ void Precache(void);
+ int GetItemInfo(ItemInfo *p);
+ void Holster(void);
+ void WeaponIdle(void);
+ BOOL Deploy(void);
+ void Reload(void);
+ int AddToPlayer(CBasePlayer *pPlayer);
+ void PrimaryAttack(void);
+
+private:
+ unsigned short m_usFireGL;
+ float m_fReloadTime;
+ float m_flNextReload;
+};
+
+class CTFPipebombLauncher : public CTFGrenadeLauncher
+{
+public:
+ void Spawn(void);
+ int GetItemInfo(ItemInfo *p);
+ void PrimaryAttack(void);
+
+private:
+ unsigned short m_usFireGL;
+ float m_fReloadTime;
+ float m_flNextReload;
+};
+
+class CTFFlamethrower : public CBasePlayerWeapon
+{
+public:
+ void Spawn(void);
+ void Precache(void);
+ int GetItemInfo(ItemInfo *p);
+ BOOL CanHolster(void) {return 1;};
+ void Holster(void);
+ void WeaponIdle(void);
+ BOOL Deploy(void);
+ int AddToPlayer(CBasePlayer *pPlayer);
+ void PrimaryAttack(void);
+
+private:
+ unsigned short m_usFireFlame;
+};
+
+enum tfc_tfcrpg_e
+{
+ TFCRPG_IDLE = 0,
+ TFCRPG_FIDGET,
+ TFCRPG_FIRE,
+ TFCRPG_HOLSTER1,
+ TFCRPG_DRAW1,
+ TFCRPG_HOLSTER2,
+ TFCRPG_DRAW2,
+ TFCRPG_RELSTART,
+ TFCRPG_RELCYCLE,
+ TFCRPG_RELEND,
+ TFCRPG_IDLE2,
+ TFCRPG_FIDGET2
+};
+
+class CTFRpg : public CBasePlayerWeapon
+{
+public:
+ void Spawn(void);
+ void Precache(void);
+ int GetItemInfo(ItemInfo *p);
+ BOOL CanHolster(void) {return 1;};
+ void Holster(void);
+ void WeaponIdle(void);
+ void Reload(void);
+ BOOL Deploy(void);
+ int AddToPlayer(CBasePlayer *pPlayer);
+ void PrimaryAttack(void);
+
+private:
+ unsigned short m_usFireRPG;
+ float m_fReloadTime;
+ float m_flNextReload;
+};
+
+class CTFIncendiaryC : public CBasePlayerWeapon
+{
+public:
+ void Spawn(void);
+ void Precache(void);
+ int GetItemInfo(ItemInfo *p);
+ BOOL CanHolster(void) {return 1;};
+ void Holster(void);
+ void WeaponIdle(void);
+ BOOL Deploy(void);
+ int AddToPlayer(CBasePlayer *pPlayer);
+ void PrimaryAttack(void);
+
+private:
+ unsigned short m_usFireIC;
+};
+
+enum tfc_assault_e
+{
+ ASSAULT_IDLE = 0,
+ ASSAULT_IDLE2,
+ ASSAULT_SPINUP,
+ ASSAULT_SPINDOWN,
+ ASSAULT_FIRE,
+ ASSAULT_DRAW,
+ ASSAULT_HOLSTER
+};
+
+class CTFAssaultC : public CBasePlayerWeapon
+{
+public:
+ void Spawn(void);
+ void Precache(void);
+ int GetItemInfo(ItemInfo *p);
+ void Holster(void);
+ void WeaponIdle(void);
+ BOOL Deploy(void);
+ BOOL ShouldWeaponIdle() {return 1;};
+ int AddToPlayer(CBasePlayer *pPlayer);
+ void PrimaryAttack(void);
+ void Fire(void);
+
+private:
+ int m_iWeaponState;
+ int m_iShell;
+ unsigned short m_usWindUp;
+ unsigned short m_usWindDown;
+ unsigned short m_usFire;
+ unsigned short m_usStartSpin;
+ unsigned short m_usSpin;
+ unsigned short m_usACStart;
+};
+
+class CTFRailgun : public CBasePlayerWeapon
+{
+public:
+ void Spawn(void);
+ void Precache(void);
+ int GetItemInfo(ItemInfo *p);
+ void WeaponIdle(void);
+ BOOL Deploy(void);
+ void PrimaryAttack(void);
+
+private:
+ unsigned short m_usFireRail;
+};
+
#endif // WEAPONS_H