Access MarkEntitiesAsTouching directly from plugin, remove extension

This commit is contained in:
rio 2018-09-22 17:35:41 -05:00
parent 6c24ed46e7
commit 26c4d06b4b
12 changed files with 104 additions and 835 deletions

View File

@ -13,8 +13,8 @@ CSS and CS:GO are currently supported. Support for additional games may be added
## Dependencies
* **SourceMod 1.10 - Build 6326 or newer** - The trigger jumping fix makes use of ray trace functionality added to SourceMod in August 2018.
* [**DHooks**](https://forums.alliedmods.net/showthread.php?t=180114)
* [**DHooks**](https://forums.alliedmods.net/showthread.php?t=180114)
* MarkTouching Extension (included) - This simply exposes the function `IServerGameEnts::MarkEntitiesAsTouching` for this plugin to use.
@ -25,7 +25,7 @@ Also, remember that you should stop using Slopefix if using RNGFix.
## Fixes
**Downhill Inclines**
Sometimes a player will not be "boosted" when falling onto an inclined surface, specifically while moving downhill. This fix results in the player always getting boosted. This is the scenario addressed by the original slopefix. RNGFix also implements this fix in a way that does not cause double boosts when a `trigger_push` is on the incline, which is a problem the original slopefix had.
@ -46,7 +46,7 @@ It is possible to pass through a teleport trigger so quickly that you also colli
**Edge Bugs**
When moving at high speed and landing on the extreme trailing edge of a platform, it is possible to collide with the surface -- resulting in a loss of vertical speed -- but without jumping, despite pressing jump in time (or holding jump with auto-bhop enabled). This fix causes the player to always be able to jump in this scenario. Note that you are still able to slide off by not pressing jump, if you wish to do so.
When moving at high speed and landing on the extreme trailing edge of a platform, it is possible to collide with the surface -- resulting in a loss of vertical speed -- but without jumping, despite pressing jump in time (or holding jump with auto-bhop enabled). This fix causes the player to always be able to jump in this scenario. It also prevents you from touching the ground and edge bugging off it without activating triggers there. Note that you are still able to slide off by not pressing jump, if you wish to do so.
**Stair Sliding** (Surf Only)
@ -60,7 +60,7 @@ A more technical explanation of these fixes can be found [here](tech.md).
## Settings
The fixes can be disabled individually by setting the following cvars to `0` in `cfg/sourcemod/plugin.rngfix.cfg`. All fixes are enabled by default.
`rngfix_downhill`
`rngfix_uphill`

View File

@ -1,448 +0,0 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os, sys
# Simple extensions do not need to modify this file.
class SDK(object):
def __init__(self, sdk, ext, aDef, name, platform, dir):
self.folder = 'hl2sdk-' + dir
self.envvar = sdk
self.ext = ext
self.code = aDef
self.define = name
self.platform = platform
self.name = dir
self.path = None # Actual path
WinOnly = ['windows']
WinLinux = ['windows', 'linux']
WinLinuxMac = ['windows', 'linux', 'mac']
PossibleSDKs = {
'episode1': SDK('HL2SDK', '1.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'),
'ep2': SDK('HL2SDKOB', '2.ep2', '3', 'ORANGEBOX', WinLinux, 'orangebox'),
'css': SDK('HL2SDKCSS', '2.css', '6', 'CSS', WinLinuxMac, 'css'),
'hl2dm': SDK('HL2SDKHL2DM', '2.hl2dm', '7', 'HL2DM', WinLinuxMac, 'hl2dm'),
'dods': SDK('HL2SDKDODS', '2.dods', '8', 'DODS', WinLinuxMac, 'dods'),
'sdk2013': SDK('HL2SDK2013', '2.sdk2013', '9', 'SDK2013', WinLinuxMac, 'sdk2013'),
'tf2': SDK('HL2SDKTF2', '2.tf2', '11', 'TF2', WinLinuxMac, 'tf2'),
'l4d': SDK('HL2SDKL4D', '2.l4d', '12', 'LEFT4DEAD', WinLinuxMac, 'l4d'),
'nucleardawn': SDK('HL2SDKND', '2.nd', '13', 'NUCLEARDAWN', WinLinuxMac, 'nucleardawn'),
'l4d2': SDK('HL2SDKL4D2', '2.l4d2', '15', 'LEFT4DEAD2', WinLinuxMac, 'l4d2'),
'darkm': SDK('HL2SDK-DARKM', '2.darkm', '2', 'DARKMESSIAH', WinOnly, 'darkm'),
'swarm': SDK('HL2SDK-SWARM', '2.swarm', '16', 'ALIENSWARM', WinOnly, 'swarm'),
'bgt': SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'),
'eye': SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'),
'csgo': SDK('HL2SDKCSGO', '2.csgo', '21', 'CSGO', WinLinuxMac, 'csgo'),
'portal2': SDK('HL2SDKPORTAL2', '2.portal2', '17', 'PORTAL2', [], 'portal2'),
'blade': SDK('HL2SDKBLADE', '2.blade', '18', 'BLADE', WinLinux, 'blade'),
'insurgency': SDK('HL2SDKINSURGENCY', '2.insurgency', '19', 'INSURGENCY', WinLinuxMac, 'insurgency'),
'contagion': SDK('HL2SDKCONTAGION', '2.contagion', '14', 'CONTAGION', WinOnly, 'contagion'),
'bms': SDK('HL2SDKBMS', '2.bms', '10', 'BMS', WinLinux, 'bms'),
'doi': SDK('HL2SDKDOI', '2.doi', '20', 'DOI', WinLinuxMac, 'doi'),
}
def ResolveEnvPath(env, folder):
if env in os.environ:
path = os.environ[env]
if os.path.isdir(path):
return path
return None
head = os.getcwd()
oldhead = None
while head != None and head != oldhead:
path = os.path.join(head, folder)
if os.path.isdir(path):
return path
oldhead = head
head, tail = os.path.split(head)
return None
def Normalize(path):
return os.path.abspath(os.path.normpath(path))
class ExtensionConfig(object):
def __init__(self):
self.sdks = {}
self.binaries = []
self.extensions = []
self.generated_headers = None
self.mms_root = None
self.sm_root = None
@property
def tag(self):
if builder.options.debug == '1':
return 'Debug'
return 'Release'
def detectSDKs(self):
sdk_list = builder.options.sdks.split(',')
use_all = sdk_list[0] == 'all'
use_present = sdk_list[0] == 'present'
for sdk_name in PossibleSDKs:
sdk = PossibleSDKs[sdk_name]
if builder.target_platform in sdk.platform:
if builder.options.hl2sdk_root:
sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder)
else:
sdk_path = ResolveEnvPath(sdk.envvar, sdk.folder)
if sdk_path is None or not os.path.isdir(sdk_path):
if use_all or sdk_name in sdk_list:
raise Exception('Could not find a valid path for {0}'.format(sdk.envvar))
continue
if use_all or use_present or sdk_name in sdk_list:
sdk.path = Normalize(sdk_path)
self.sdks[sdk_name] = sdk
if len(self.sdks) < 1:
raise Exception('At least one SDK must be available.')
if builder.options.sm_path:
self.sm_root = builder.options.sm_path
else:
self.sm_root = ResolveEnvPath('SOURCEMOD18', 'sourcemod-1.8')
if not self.sm_root:
self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod')
if not self.sm_root:
self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod-central')
if not self.sm_root or not os.path.isdir(self.sm_root):
raise Exception('Could not find a source copy of SourceMod')
self.sm_root = Normalize(self.sm_root)
if builder.options.mms_path:
self.mms_root = builder.options.mms_path
else:
self.mms_root = ResolveEnvPath('MMSOURCE110', 'mmsource-1.10')
if not self.mms_root:
self.mms_root = ResolveEnvPath('MMSOURCE', 'metamod-source')
if not self.mms_root:
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'mmsource-central')
if not self.mms_root or not os.path.isdir(self.mms_root):
raise Exception('Could not find a source copy of Metamod:Source')
self.mms_root = Normalize(self.mms_root)
def configure(self):
cxx = builder.DetectCompilers()
if cxx.like('gcc'):
self.configure_gcc(cxx)
elif cxx.vendor == 'msvc':
self.configure_msvc(cxx)
# Optimizaiton
if builder.options.opt == '1':
cxx.defines += ['NDEBUG']
# Debugging
if builder.options.debug == '1':
cxx.defines += ['DEBUG', '_DEBUG']
# Platform-specifics
if builder.target_platform == 'linux':
self.configure_linux(cxx)
elif builder.target_platform == 'mac':
self.configure_mac(cxx)
elif builder.target_platform == 'windows':
self.configure_windows(cxx)
# Finish up.
cxx.includes += [
os.path.join(self.sm_root, 'public'),
]
def configure_gcc(self, cxx):
cxx.defines += [
'stricmp=strcasecmp',
'_stricmp=strcasecmp',
'_snprintf=snprintf',
'_vsnprintf=vsnprintf',
'HAVE_STDINT_H',
'GNUC',
]
cxx.cflags += [
'-pipe',
'-fno-strict-aliasing',
'-Wall',
'-Werror',
'-Wno-unused',
'-Wno-switch',
'-Wno-array-bounds',
'-msse',
'-m32',
'-fvisibility=hidden',
]
cxx.cxxflags += [
'-std=c++11',
'-fno-exceptions',
'-fno-threadsafe-statics',
'-Wno-non-virtual-dtor',
'-Wno-overloaded-virtual',
'-fvisibility-inlines-hidden',
]
cxx.linkflags += ['-m32']
have_gcc = cxx.vendor == 'gcc'
have_clang = cxx.vendor == 'clang'
if cxx.version >= 'clang-3.6':
cxx.cxxflags += ['-Wno-inconsistent-missing-override']
if have_clang or (cxx.version >= 'gcc-4.6'):
cxx.cflags += ['-Wno-narrowing']
if have_clang or (cxx.version >= 'gcc-4.7'):
cxx.cxxflags += ['-Wno-delete-non-virtual-dtor']
if cxx.version >= 'gcc-4.8':
cxx.cflags += ['-Wno-unused-result']
if have_clang:
cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch']
if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4':
cxx.cxxflags += ['-Wno-deprecated-register']
else:
cxx.cxxflags += ['-Wno-deprecated']
cxx.cflags += ['-Wno-sometimes-uninitialized']
if have_gcc:
cxx.cflags += ['-mfpmath=sse']
if builder.options.opt == '1':
cxx.cflags += ['-O3']
def configure_msvc(self, cxx):
if builder.options.debug == '1':
cxx.cflags += ['/MTd']
cxx.linkflags += ['/NODEFAULTLIB:libcmt']
else:
cxx.cflags += ['/MT']
cxx.defines += [
'_CRT_SECURE_NO_DEPRECATE',
'_CRT_SECURE_NO_WARNINGS',
'_CRT_NONSTDC_NO_DEPRECATE',
'_ITERATOR_DEBUG_LEVEL=0',
]
cxx.cflags += [
'/W3',
]
cxx.cxxflags += [
'/EHsc',
'/GR-',
'/TP',
]
cxx.linkflags += [
'/MACHINE:X86',
'kernel32.lib',
'user32.lib',
'gdi32.lib',
'winspool.lib',
'comdlg32.lib',
'advapi32.lib',
'shell32.lib',
'ole32.lib',
'oleaut32.lib',
'uuid.lib',
'odbc32.lib',
'odbccp32.lib',
]
if builder.options.opt == '1':
cxx.cflags += ['/Ox', '/Zo']
cxx.linkflags += ['/OPT:ICF', '/OPT:REF']
if builder.options.debug == '1':
cxx.cflags += ['/Od', '/RTC1']
# This needs to be after our optimization flags which could otherwise disable it.
# Don't omit the frame pointer.
cxx.cflags += ['/Oy-']
def configure_linux(self, cxx):
cxx.defines += ['_LINUX', 'POSIX']
cxx.linkflags += ['-Wl,--exclude-libs,ALL', '-lm']
if cxx.vendor == 'gcc':
cxx.linkflags += ['-static-libgcc']
elif cxx.vendor == 'clang':
cxx.linkflags += ['-lgcc_eh']
def configure_mac(self, cxx):
cxx.defines += ['OSX', '_OSX', 'POSIX']
cxx.cflags += ['-mmacosx-version-min=10.5']
cxx.linkflags += [
'-mmacosx-version-min=10.5',
'-arch', 'i386',
'-lstdc++',
'-stdlib=libstdc++',
]
cxx.cxxflags += ['-stdlib=libstdc++']
def configure_windows(self, cxx):
cxx.defines += ['WIN32', '_WINDOWS']
def ConfigureForExtension(self, context, compiler):
compiler.cxxincludes += [
os.path.join(context.currentSourcePath),
os.path.join(context.currentSourcePath, 'sdk'),
os.path.join(self.sm_root, 'public'),
os.path.join(self.sm_root, 'public', 'extensions'),
os.path.join(self.sm_root, 'sourcepawn', 'include'),
os.path.join(self.sm_root, 'public', 'amtl', 'amtl'),
os.path.join(self.sm_root, 'public', 'amtl'),
]
return compiler
def ConfigureForHL2(self, binary, sdk):
compiler = binary.compiler
if sdk.name == 'episode1':
mms_path = os.path.join(self.mms_root, 'core-legacy')
else:
mms_path = os.path.join(self.mms_root, 'core')
compiler.cxxincludes += [
os.path.join(mms_path),
os.path.join(mms_path, 'sourcehook'),
]
defines = ['SE_' + PossibleSDKs[i].define + '=' + PossibleSDKs[i].code for i in PossibleSDKs]
compiler.defines += defines
paths = [
['public'],
['public', 'engine'],
['public', 'mathlib'],
['public', 'vstdlib'],
['public', 'tier0'],
['public', 'tier1']
]
if sdk.name == 'episode1' or sdk.name == 'darkm':
paths.append(['public', 'dlls'])
paths.append(['game_shared'])
else:
paths.append(['public', 'game', 'server'])
paths.append(['public', 'toolframework'])
paths.append(['game', 'shared'])
paths.append(['common'])
compiler.defines += ['SOURCE_ENGINE=' + sdk.code]
if sdk.name in ['sdk2013', 'bms'] and compiler.like('gcc'):
# The 2013 SDK already has these in public/tier0/basetypes.h
compiler.defines.remove('stricmp=strcasecmp')
compiler.defines.remove('_stricmp=strcasecmp')
compiler.defines.remove('_snprintf=snprintf')
compiler.defines.remove('_vsnprintf=vsnprintf')
if compiler.like('msvc'):
compiler.defines += ['COMPILER_MSVC', 'COMPILER_MSVC32']
else:
compiler.defines += ['COMPILER_GCC']
# For everything after Swarm, this needs to be defined for entity networking
# to work properly with sendprop value changes.
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
compiler.defines += ['NETWORK_VARS_ENABLED']
if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2']:
if builder.target_platform in ['linux', 'mac']:
compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE']
if sdk.name == 'csgo' and builder.target_platform == 'linux':
compiler.linkflags += ['-lstdc++']
for path in paths:
compiler.cxxincludes += [os.path.join(sdk.path, *path)]
if builder.target_platform == 'linux':
if sdk.name == 'episode1':
lib_folder = os.path.join(sdk.path, 'linux_sdk')
elif sdk.name in ['sdk2013', 'bms']:
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32')
else:
lib_folder = os.path.join(sdk.path, 'lib', 'linux')
elif builder.target_platform == 'mac':
if sdk.name in ['sdk2013', 'bms']:
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32')
else:
lib_folder = os.path.join(sdk.path, 'lib', 'mac')
if builder.target_platform in ['linux', 'mac']:
if sdk.name in ['sdk2013', 'bms']:
compiler.postlink += [
compiler.Dep(os.path.join(lib_folder, 'tier1.a')),
compiler.Dep(os.path.join(lib_folder, 'mathlib.a'))
]
else:
compiler.postlink += [
compiler.Dep(os.path.join(lib_folder, 'tier1_i486.a')),
compiler.Dep(os.path.join(lib_folder, 'mathlib_i486.a'))
]
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))]
dynamic_libs = []
if builder.target_platform == 'linux':
if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2', 'insurgency', 'doi']:
dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so']
elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo']:
dynamic_libs = ['libtier0.so', 'libvstdlib.so']
else:
dynamic_libs = ['tier0_i486.so', 'vstdlib_i486.so']
elif builder.target_platform == 'mac':
compiler.linkflags.append('-liconv')
dynamic_libs = ['libtier0.dylib', 'libvstdlib.dylib']
elif builder.target_platform == 'windows':
libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
if sdk.name in ['swarm', 'blade', 'insurgency', 'doi', 'csgo']:
libs.append('interfaces')
for lib in libs:
lib_path = os.path.join(sdk.path, 'lib', 'public', lib) + '.lib'
compiler.linkflags.append(compiler.Dep(lib_path))
for library in dynamic_libs:
source_path = os.path.join(lib_folder, library)
output_path = os.path.join(binary.localFolder, library)
def make_linker(source_path, output_path):
def link(context, binary):
cmd_node, (output,) = context.AddSymlink(source_path, output_path)
return output
return link
linker = make_linker(source_path, output_path)
compiler.linkflags[0:0] = [compiler.Dep(library, linker)]
return binary
def HL2Library(self, context, name, sdk):
binary = context.compiler.Library(name)
self.ConfigureForExtension(context, binary.compiler)
return self.ConfigureForHL2(binary, sdk)
def HL2Project(self, context, name):
project = context.compiler.LibraryProject(name)
self.ConfigureForExtension(context, project.compiler)
return project
def HL2Config(self, project, name, sdk):
binary = project.Configure(name, '{0} - {1}'.format(self.tag, sdk.name))
return self.ConfigureForHL2(binary, sdk)
Extension = ExtensionConfig()
Extension.detectSDKs()
Extension.configure()
# Add additional buildscripts here
BuildScripts = [
'AMBuilder',
]
if builder.backend == 'amb2':
BuildScripts += [
'PackageScript',
]
builder.RunBuildScripts(BuildScripts, { 'Extension': Extension})

View File

@ -1,31 +0,0 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os, sys
projectName = 'marktouching'
# smsdk_ext.cpp will be automatically added later
sourceFiles = [
'extension.cpp',
]
###############
# Make sure to edit PackageScript, which copies your files to their appropriate locations
# Simple extensions do not need to modify past this point.
project = Extension.HL2Project(builder, projectName + '.ext')
if os.path.isfile(os.path.join(builder.currentSourcePath, 'sdk', 'smsdk_ext.cpp')):
# Use the copy included in the project
project.sources += [os.path.join('sdk', 'smsdk_ext.cpp')]
else:
# Use the copy included with SM 1.6 and newer
project.sources += [os.path.join(Extension.sm_root, 'public', 'smsdk_ext.cpp')]
project.sources += sourceFiles
for sdk_name in Extension.sdks:
sdk = Extension.sdks[sdk_name]
binary = Extension.HL2Config(project, projectName + '.ext.' + sdk.ext, sdk)
Extension.extensions = builder.Add(project)

View File

@ -1,52 +0,0 @@
# vim: set ts=8 sts=2 sw=2 tw=99 et ft=python:
import os
# This is where the files will be output to
# package is the default
builder.SetBuildFolder('package')
# Add any folders you need to this list
folder_list = [
'addons/sourcemod/extensions',
#'addons/sourcemod/scripting/include',
#'addons/sourcemod/gamedata',
#'addons/sourcemod/configs',
]
# Create the distribution folder hierarchy.
folder_map = {}
for folder in folder_list:
norm_folder = os.path.normpath(folder)
folder_map[folder] = builder.AddFolder(norm_folder)
# Do all straight-up file copies from the source tree.
def CopyFiles(src, dest, files):
if not dest:
dest = src
dest_entry = folder_map[dest]
for source_file in files:
source_path = os.path.join(builder.sourcePath, src, source_file)
builder.AddCopy(source_path, dest_entry)
# Include files
#CopyFiles('include', 'addons/sourcemod/scripting/include',
# [ 'sample.inc', ]
#)
# GameData files
#CopyFiles('gamedata', 'addons/sourcemod/gamedata',
# [ 'myfile.txt',
# 'file2.txt'
# ]
#)
# Config Files
#CopyFiles('configs', 'addons/sourcemod/configs',
# [ 'configfile.cfg',
# 'otherconfig.cfg,
# ]
#)
# Copy binaries.
for cxx_task in Extension.extensions:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions'])

View File

@ -1,23 +0,0 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et:
import sys
from ambuild2 import run
# Simple extensions do not need to modify this file.
builder = run.PrepareBuild(sourcePath = sys.path[0])
builder.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None,
help='Root search folder for HL2SDKs')
builder.options.add_option('--mms-path', type=str, dest='mms_path', default=None,
help='Path to Metamod:Source')
builder.options.add_option('--sm-path', type=str, dest='sm_path', default=None,
help='Path to SourceMod')
builder.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',
help='Enable debugging symbols')
builder.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt',
help='Enable optimization')
builder.options.add_option('-s', '--sdks', default='all', dest='sdks',
help='Build against specified SDKs; valid args are "all", "present", or '
'comma-delimited list of engine names (default: %default)')
builder.Configure()

View File

@ -1,43 +0,0 @@
#include "extension.h"
MarkTouching g_MarkTouching; /**< Global singleton for extension's main interface */
IServerGameEnts *gameents = NULL;
SMEXT_LINK(&g_MarkTouching);
void MarkTouching::SDK_OnAllLoaded()
{
sharesys->AddNatives(myself, MyNatives);
}
bool MarkTouching::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late)
{
GET_V_IFACE_ANY(GetServerFactory, gameents, IServerGameEnts, INTERFACEVERSION_SERVERGAMEENTS);
return true;
}
cell_t MarkEntitiesAsTouching(IPluginContext *pContext, const cell_t *params)
{
edict_t *pEdict1 = gamehelpers->EdictOfIndex(params[1]);
if (!pEdict1 || pEdict1->IsFree())
{
return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
}
edict_t *pEdict2 = gamehelpers->EdictOfIndex(params[2]);
if (!pEdict2 || pEdict2->IsFree())
{
return pContext->ThrowNativeError("Entity %d is invalid", params[2]);
}
gameents->MarkEntitiesAsTouching(pEdict1, pEdict2);
return true;
}
sp_nativeinfo_t MyNatives[] =
{
{"MarkEntitiesAsTouching", MarkEntitiesAsTouching},
{NULL, NULL},
};

View File

@ -1,81 +0,0 @@
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#include "smsdk_ext.h"
extern IServerGameEnts *gameents;
extern sp_nativeinfo_t MyNatives[];
class MarkTouching : public SDKExtension
{
public:
/**
* @brief This is called after the initial loading sequence has been processed.
*
* @param error Error message buffer.
* @param maxlength Size of error message buffer.
* @param late Whether or not the module was loaded after map load.
* @return True to succeed loading, false to fail.
*/
//virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
/**
* @brief This is called right before the extension is unloaded.
*/
//virtual void SDK_OnUnload();
/**
* @brief This is called once all known extensions have been loaded.
* Note: It is is a good idea to add natives here, if any are provided.
*/
virtual void SDK_OnAllLoaded();
/**
* @brief Called when the pause state is changed.
*/
//virtual void SDK_OnPauseChange(bool paused);
/**
* @brief this is called when Core wants to know if your extension is working.
*
* @param error Error message buffer.
* @param maxlength Size of error message buffer.
* @return True if working, false otherwise.
*/
//virtual bool QueryRunning(char *error, size_t maxlength);
public:
#if defined SMEXT_CONF_METAMOD
/**
* @brief Called when Metamod is attached, before the extension version is called.
*
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @param late Whether or not Metamod considers this a late load.
* @return True to succeed, false to fail.
*/
virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
/**
* @brief Called when Metamod is detaching, after the extension version is called.
* NOTE: By default this is blocked unless sent from SourceMod.
*
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail.
*/
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
/**
* @brief Called when Metamod's pause state is changing.
* NOTE: By default this is blocked unless sent from SourceMod.
*
* @param paused Pause state being set.
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail.
*/
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
#endif
};
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_

View File

@ -1,45 +0,0 @@
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
/* Basic information exposed publicly */
#define SMEXT_CONF_NAME "MarkTouching"
#define SMEXT_CONF_DESCRIPTION "Exposes IServerGameEnts::MarkEntitiesAsTouching"
#define SMEXT_CONF_VERSION "1.0.0.0"
#define SMEXT_CONF_AUTHOR "rio"
#define SMEXT_CONF_URL ""
#define SMEXT_CONF_LOGTAG "MARKTOUCHING"
#define SMEXT_CONF_LICENSE "GPL"
#define SMEXT_CONF_DATESTRING __DATE__
/**
* @brief Exposes plugin's main interface.
*/
#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name;
/**
* @brief Sets whether or not this plugin required Metamod.
* NOTE: Uncomment to enable, comment to disable.
*/
#define SMEXT_CONF_METAMOD
/** Enable interfaces you want to use here by uncommenting lines */
//#define SMEXT_ENABLE_FORWARDSYS
//#define SMEXT_ENABLE_HANDLESYS
//#define SMEXT_ENABLE_PLAYERHELPERS
//#define SMEXT_ENABLE_DBMANAGER
//#define SMEXT_ENABLE_GAMECONF
//#define SMEXT_ENABLE_MEMUTILS
#define SMEXT_ENABLE_GAMEHELPERS
//#define SMEXT_ENABLE_TIMERSYS
//#define SMEXT_ENABLE_THREADER
//#define SMEXT_ENABLE_LIBSYS
//#define SMEXT_ENABLE_MENUS
//#define SMEXT_ENABLE_ADTFACTORY
//#define SMEXT_ENABLE_PLUGINSYS
//#define SMEXT_ENABLE_ADMINSYS
//#define SMEXT_ENABLE_TEXTPARSERS
//#define SMEXT_ENABLE_USERMSGS
//#define SMEXT_ENABLE_TRANSLATOR
//#define SMEXT_ENABLE_ROOTCONSOLEMENU
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_

View File

@ -1,31 +0,0 @@
"Games"
{
"#default"
{
"Keys"
{
"IGameMovement" "GameMovement001"
}
"Signatures"
{
"CreateInterface"
{
"library" "server"
"windows" "@CreateInterface"
"linux" "@CreateInterface"
}
}
}
"#default"
{
"Offsets"
{
"ProcessMovement"
{
"windows" "1"
"linux" "2"
}
}
}
}

View File

@ -1,5 +1,34 @@
"Games"
{
"#default"
{
"Keys"
{
"IGameMovement" "GameMovement001"
"IServerGameEnts" "ServerGameEnts001"
}
"Signatures"
{
"CreateInterface"
{
"library" "server"
"windows" "@CreateInterface"
"linux" "@CreateInterface"
}
}
"Offsets"
{
"ProcessMovement"
{
"windows" "1"
"linux" "2"
}
}
}
"csgo"
{
"Offsets"
@ -10,33 +39,45 @@
"windows" "196"
"linux" "197"
}
// applies to all other triggers
"CBaseTrigger::PassesTriggerFilters"
{
"windows" "206"
"linux" "207"
}
"IServerGameEnts::MarkEntitiesAsTouching"
{
"windows" "1"
"linux" "2"
}
}
}
"cstrike"
{
"Offsets"
{
{
// applies to trigger_vphysics_motion and trigger_wind
"CBaseVPhysicsTrigger::PassesTriggerFilters"
{
"windows" "188"
"linux" "189"
}
// applies to all other triggers
"CBaseTrigger::PassesTriggerFilters"
{
"windows" "197"
"linux" "198"
}
"IServerGameEnts::MarkEntitiesAsTouching"
{
"windows" "2"
"linux" "3"
}
}
}
}
}

View File

@ -1,38 +0,0 @@
#if defined _marktouching_included
#endinput
#endif
#define _marktouching_included
/**
* Mark two entities as touching each other
* This is the same call that is triggered when two entities touch, and triggers StartTouch, Touch, and later EndTouch.
* Note that this will fire Touch() even if the entities were already touching, meaning Touch() will be called multiple times in one tick
*
* @param entity1 Entity index.
* @param entity2 Entity index.
* @noreturn
*/
native void MarkEntitiesAsTouching(int entity1, int entity2);
#if !defined REQUIRE_EXTENSIONS
public __ext_marktouching_SetNTVOptional()
{
MarkNativeAsOptional("MarkEntitiesAsTouching");
}
#endif
public Extension __ext_marktouching =
{
name = "MarkTouching",
file = "marktouching.ext",
#if defined AUTOLOAD_EXTENSIONS
autoload = 1,
#else
autoload = 0,
#endif
#if defined REQUIRE_EXTENSIONS
required = 1,
#else
required = 0,
#endif
};

View File

@ -2,12 +2,11 @@
#include <sdkhooks>
#include <dhooks>
#include <marktouching>
#pragma semicolon 1
#pragma newdecls required
#define PLUGIN_VERSION "1.0.0"
#define PLUGIN_VERSION "1.1.0"
public Plugin myinfo =
{
@ -83,6 +82,8 @@ ConVar g_cvAutoBunnyHopping;
Handle g_hPassesTriggerFilters;
Handle g_hProcessMovementHookPre;
Address g_IServerGameEnts;
Handle g_hMarkEntitiesAsTouching;
bool g_bIsSurfMap;
@ -144,8 +145,6 @@ public void OnPluginStart()
g_flDuckDelta = (g_vecMaxsUnducked[2]-g_vecMaxsDucked[2]) / 2;
CreateConVar("rngfix_version", PLUGIN_VERSION, "RNGFix Version", FCVAR_NOTIFY|FCVAR_REPLICATED);
g_cvDownhill = CreateConVar("rngfix_downhill", "1", "Enable downhill incline fix.", FCVAR_NOTIFY, true, 0.0, true, 1.0);
g_cvUphill = CreateConVar("rngfix_uphill", "1", "Enable uphill incline fix. Set to -1 to normalize effects not in the player's favor (not recommended).", FCVAR_NOTIFY, true, -1.0, true, 1.0);
g_cvEdge = CreateConVar("rngfix_edge", "1", "Enable edgebug fix.", FCVAR_NOTIFY, true, 0.0, true, 1.0);
@ -173,11 +172,12 @@ public void OnPluginStart()
g_cvJumpImpulse = FindConVar("sv_jump_impulse");
g_cvAutoBunnyHopping = FindConVar("sv_autobunnyhopping");
Handle filtersConf = LoadGameConfigFile("triggerfilters.games");
if (filtersConf == null) SetFailState("Failed to load triggerfilters gamedata");
Handle gamedataConf = LoadGameConfigFile("rngfix.games");
if (gamedataConf == null) SetFailState("Failed to load rngfix gamedata");
// PassesTriggerFilters
StartPrepSDKCall(SDKCall_Entity);
if (!PrepSDKCall_SetFromConf(filtersConf, SDKConf_Virtual, "CBaseTrigger::PassesTriggerFilters"))
if (!PrepSDKCall_SetFromConf(gamedataConf, SDKConf_Virtual, "CBaseTrigger::PassesTriggerFilters"))
{
SetFailState("Failed to get CBaseTrigger::PassesTriggerFilters offset");
}
@ -187,45 +187,65 @@ public void OnPluginStart()
if (g_hPassesTriggerFilters == null) SetFailState("Unable to prepare SDKCall for CBaseTrigger::PassesTriggerFilters");
delete filtersConf;
// CreateInterface
// Thanks SlidyBat and ici
Handle gameMovementConf = LoadGameConfigFile("gamemovement.games");
if (gameMovementConf == null) SetFailState("Failed to load gamemovement gamedata");
StartPrepSDKCall(SDKCall_Static);
if (!PrepSDKCall_SetFromConf(gameMovementConf, SDKConf_Signature, "CreateInterface"))
if (!PrepSDKCall_SetFromConf(gamedataConf, SDKConf_Signature, "CreateInterface"))
{
SetFailState("Failed to get CreateInterface");
}
PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer);
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL);
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
Handle CreateInterface = EndPrepSDKCall();
if (CreateInterface == null) SetFailState("Unable to prepare SDKCall for CreateInterface");
char interfaceName[64];
if (!GameConfGetKeyValue(gameMovementConf, "IGameMovement", interfaceName, sizeof(interfaceName)))
// ProcessMovement
if (!GameConfGetKeyValue(gamedataConf, "IGameMovement", interfaceName, sizeof(interfaceName)))
{
SetFailState("Failed to get IGameMovement interface name");
}
Handle CreateInterface = EndPrepSDKCall();
Address gameMovement = SDKCall(CreateInterface, interfaceName, 0);
delete CreateInterface;
if (!gameMovement)
{
}
Address IGameMovement = SDKCall(CreateInterface, interfaceName, 0);
if (!IGameMovement)
{
SetFailState("Failed to get IGameMovement pointer");
}
int offset = GameConfGetOffset(gameMovementConf, "ProcessMovement");
int offset = GameConfGetOffset(gamedataConf, "ProcessMovement");
if (offset == -1) SetFailState("Failed to get ProcessMovement offset");
g_hProcessMovementHookPre = DHookCreate(offset, HookType_Raw, ReturnType_Void, ThisPointer_Ignore, DHook_ProcessMovementPre);
DHookAddParam(g_hProcessMovementHookPre, HookParamType_CBaseEntity);
DHookAddParam(g_hProcessMovementHookPre, HookParamType_ObjectPtr);
DHookRaw(g_hProcessMovementHookPre, false, gameMovement);
delete gameMovementConf;
DHookRaw(g_hProcessMovementHookPre, false, IGameMovement);
// MarkEntitiesAsTouching
if (!GameConfGetKeyValue(gamedataConf, "IServerGameEnts", interfaceName, sizeof(interfaceName)))
{
SetFailState("Failed to get IServerGameEnts interface name");
}
g_IServerGameEnts = SDKCall(CreateInterface, interfaceName, 0);
if (!g_IServerGameEnts)
{
SetFailState("Failed to get IServerGameEnts pointer");
}
StartPrepSDKCall(SDKCall_Raw);
if (!PrepSDKCall_SetFromConf(gamedataConf, SDKConf_Virtual, "IServerGameEnts::MarkEntitiesAsTouching"))
{
SetFailState("Failed to get IServerGameEnts::MarkEntitiesAsTouching offset");
}
PrepSDKCall_AddParameter(SDKType_Edict, SDKPass_Pointer);
PrepSDKCall_AddParameter(SDKType_Edict, SDKPass_Pointer);
g_hMarkEntitiesAsTouching = EndPrepSDKCall();
if (g_hMarkEntitiesAsTouching == null) SetFailState("Unable to prepare SDKCall for IServerGameEnts::MarkEntitiesAsTouching");
delete CreateInterface;
delete gamedataConf;
if (g_bLateLoad)
{
@ -420,9 +440,9 @@ bool CanJump(int client)
void CheckJumpButton(int client, float velocity[3])
{
// Skip dead and water checks since we already did them
// Skip dead and water checks since we already did them.
// We need to check for ground somewhere so stick it here
// We need to check for ground somewhere so stick it here.
if (GetEntityFlags(client) & FL_ONGROUND == 0) return;
if (!CanJump(client)) return;
@ -501,7 +521,7 @@ void StartGravity(int client, float velocity[3])
GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", baseVelocity);
velocity[2] += baseVelocity[2] * g_flFrameTime[client];
// baseVelocity[2] would get cleared here but we shouldn't do that since this is just a prediction
// baseVelocity[2] would get cleared here but we shouldn't do that since this is just a prediction.
CheckVelocity(velocity);
}
@ -538,7 +558,7 @@ void PreventCollision(int client, Handle hParams, const float origin[3], const f
newOrigin[2] += 0.1;
// Since the MoveData for this tick has already been filled and is about to be used, we need
// to modify it directly instead of changing the player entity's actual position (such as with TeleportEntity)
// to modify it directly instead of changing the player entity's actual position (such as with TeleportEntity).
DHookSetParamObjectPtrVarVector(hParams, 2, GetEngineVersion() == Engine_CSGO ? 172 : 152, ObjectValueType_Vector, newOrigin);
DebugLaser(client, origin, newOrigin, 15.0, 0.5, g_color2);
@ -600,7 +620,7 @@ public MRESReturn DHook_ProcessMovementPre(Handle hParams)
void RunPreTickChecks(int client, Handle hParams)
{
// Recreate enough of CGameMovement::ProcessMovement to predict if fixes are needed.
// We only really care about a limited set of scenarios (less than waist-deep in water, MOVETYPE_WALK, air movement)
// We only really care about a limited set of scenarios (less than waist-deep in water, MOVETYPE_WALK, air movement).
if (!IsPlayerAlive(client)) return;
if (GetEntityMoveType(client) != MOVETYPE_WALK) return;
@ -828,7 +848,7 @@ bool DoTriggerjumpFix(int client, const float landingPoint[3], const float landi
DebugMsg(client, "DO FIX: Trigger Jumping (entity %i)", trigger);
MarkEntitiesAsTouching(client, trigger);
SDKCall(g_hMarkEntitiesAsTouching, g_IServerGameEnts, client, trigger);
didSomething = true;
}