diff --git a/extensions/sdktools/extension.cpp b/extensions/sdktools/extension.cpp index a4055923..695841d5 100644 --- a/extensions/sdktools/extension.cpp +++ b/extensions/sdktools/extension.cpp @@ -61,6 +61,7 @@ SH_DECL_HOOK1_void_vafmt(IVEngineServer, ClientCommand, SH_NOATTRIB, 0, edict_t SDKTools g_SdkTools; /**< Global singleton for extension's main interface */ IServerGameEnts *gameents = NULL; IEngineTrace *enginetrace = NULL; +ISpatialPartition *partition = NULL; IEngineSound *engsound = NULL; INetworkStringTableContainer *netstringtables = NULL; IServerPluginHelpers *pluginhelpers = NULL; @@ -269,6 +270,7 @@ bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool GET_V_IFACE_ANY(GetServerFactory, gameents, IServerGameEnts, INTERFACEVERSION_SERVERGAMEENTS); GET_V_IFACE_ANY(GetEngineFactory, engsound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION); GET_V_IFACE_ANY(GetEngineFactory, enginetrace, IEngineTrace, INTERFACEVERSION_ENGINETRACE_SERVER); + GET_V_IFACE_ANY(GetEngineFactory, partition, ISpatialPartition, INTERFACEVERSION_SPATIALPARTITION); GET_V_IFACE_ANY(GetEngineFactory, netstringtables, INetworkStringTableContainer, INTERFACENAME_NETWORKSTRINGTABLESERVER); GET_V_IFACE_ANY(GetEngineFactory, pluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS); GET_V_IFACE_ANY(GetServerFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS); diff --git a/extensions/sdktools/extension.h b/extensions/sdktools/extension.h index 5c5d562a..a4d97221 100644 --- a/extensions/sdktools/extension.h +++ b/extensions/sdktools/extension.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -131,6 +132,7 @@ extern SDKTools g_SdkTools; /* Interfaces from engine or gamedll */ extern IServerGameEnts *gameents; extern IEngineTrace *enginetrace; +extern ISpatialPartition *partition; extern IEngineSound *engsound; extern INetworkStringTableContainer *netstringtables; extern IServerPluginHelpers *pluginhelpers; diff --git a/extensions/sdktools/trnatives.cpp b/extensions/sdktools/trnatives.cpp index 555319d1..8dab8747 100644 --- a/extensions/sdktools/trnatives.cpp +++ b/extensions/sdktools/trnatives.cpp @@ -74,17 +74,17 @@ private: cell_t m_Data; }; -class CSMTraceEnumerator : public IEntityEnumerator +class CSMTraceEnumerator : public IPartitionEnumerator { public: - bool EnumEntity(IHandleEntity *pEntity) override + IterationRetval_t EnumElement(IHandleEntity *pEntity) override { cell_t res = 1; m_pFunc->PushCell(gamehelpers->EntityToBCompatRef(reinterpret_cast(pEntity))); m_pFunc->PushCell(m_Data); m_pFunc->Execute(&res); - return (res) ? true : false; + return (res) ? ITERATION_CONTINUE : ITERATION_STOP; } void SetFunctionPtr(IPluginFunction *pFunc, cell_t data) { @@ -114,6 +114,20 @@ enum RayType_Infinite }; +// For backwards compatibility, old EnumerateEntities functions accepted bool instead of flags +static int TranslatePartitionFlags(int input) +{ + switch (input) + { + case 0: + return PARTITION_ENGINE_SOLID_EDICTS; + case 1: + return PARTITION_ENGINE_TRIGGER_EDICTS; + default: + return input >> 1; + } +} + static cell_t smn_TRTraceRay(IPluginContext *pContext, const cell_t *params) { cell_t *startaddr, *endaddr; @@ -211,8 +225,8 @@ static cell_t smn_TREnumerateEntities(IPluginContext *pContext, const cell_t *pa g_Ray.Init(g_StartVec, g_EndVec); - bool triggers = (params[3]) ? true : false; - enginetrace->EnumerateEntities(g_Ray, triggers, &g_SMTraceEnumerator); + int mask = TranslatePartitionFlags(params[3]); + partition->EnumerateElementsAlongRay(mask, g_Ray, false, &g_SMTraceEnumerator); return 1; } @@ -246,8 +260,8 @@ static cell_t smn_TREnumerateEntitiesHull(IPluginContext *pContext, const cell_t g_Ray.Init(g_StartVec, g_EndVec, g_HullMins, g_HullMaxs); - bool triggers = (params[5]) ? true : false; - enginetrace->EnumerateEntities(g_Ray, triggers, &g_SMTraceEnumerator); + int mask = TranslatePartitionFlags(params[5]); + partition->EnumerateElementsAlongRay(mask, g_Ray, false, &g_SMTraceEnumerator); return 1; } @@ -752,6 +766,22 @@ static cell_t smn_TRGetFraction(IPluginContext *pContext, const cell_t *params) return sp_ftoc(tr->fraction); } +static cell_t smn_TRGetFractionLeftSolid(IPluginContext *pContext, const cell_t *params) +{ + sm_trace_t *tr; + HandleError err; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if (params[1] == BAD_HANDLE) + { + tr = &g_Trace; + } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); + } + + return sp_ftoc(tr->fractionleftsolid); +} + static cell_t smn_TRGetPlaneNormal(IPluginContext *pContext, const cell_t *params) { sm_trace_t *tr; @@ -776,6 +806,28 @@ static cell_t smn_TRGetPlaneNormal(IPluginContext *pContext, const cell_t *param return 1; } +static cell_t smn_TRGetStartPosition(IPluginContext *pContext, const cell_t *params) +{ + sm_trace_t *tr; + HandleError err; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if (params[1] == BAD_HANDLE) + { + tr = &g_Trace; + } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); + } + + cell_t *addr; + pContext->LocalToPhysAddr(params[2], &addr); + + addr[0] = sp_ftoc(tr->startpos.x); + addr[1] = sp_ftoc(tr->startpos.y); + addr[2] = sp_ftoc(tr->startpos.z); + + return 1; +} static cell_t smn_TRGetEndPosition(IPluginContext *pContext, const cell_t *params) { @@ -800,6 +852,120 @@ static cell_t smn_TRGetEndPosition(IPluginContext *pContext, const cell_t *param return 1; } +static cell_t smn_TRGetDisplacementFlags(IPluginContext *pContext, const cell_t *params) +{ + sm_trace_t *tr; + HandleError err; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if (params[1] == BAD_HANDLE) + { + tr = &g_Trace; + } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); + } + + return tr->dispFlags; +} + +static cell_t smn_TRGetSurfaceName(IPluginContext *pContext, const cell_t *params) +{ + sm_trace_t *tr; + HandleError err; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if (params[1] == BAD_HANDLE) + { + tr = &g_Trace; + } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); + } + + pContext->StringToLocal(params[2], params[3], tr->surface.name); + + return 1; +} + +static cell_t smn_TRGetSurfaceProps(IPluginContext *pContext, const cell_t *params) +{ + sm_trace_t *tr; + HandleError err; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if (params[1] == BAD_HANDLE) + { + tr = &g_Trace; + } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); + } + + return tr->surface.surfaceProps; +} + +static cell_t smn_TRGetSurfaceFlags(IPluginContext *pContext, const cell_t *params) +{ + sm_trace_t *tr; + HandleError err; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if (params[1] == BAD_HANDLE) + { + tr = &g_Trace; + } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); + } + + return tr->surface.flags; +} + +static cell_t smn_TRGetPhysicsBone(IPluginContext *pContext, const cell_t *params) +{ + sm_trace_t *tr; + HandleError err; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if (params[1] == BAD_HANDLE) + { + tr = &g_Trace; + } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); + } + + return tr->physicsbone; +} + +static cell_t smn_TRAllSolid(IPluginContext *pContext, const cell_t *params) +{ + sm_trace_t *tr; + HandleError err; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if (params[1] == BAD_HANDLE) + { + tr = &g_Trace; + } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); + } + + return tr->allsolid ? 1 : 0; +} + +static cell_t smn_TRStartSolid(IPluginContext *pContext, const cell_t *params) +{ + sm_trace_t *tr; + HandleError err; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if (params[1] == BAD_HANDLE) + { + tr = &g_Trace; + } else if ((err = handlesys->ReadHandle(params[1], g_TraceHandle, &sec, (void **)&tr)) != HandleError_None) { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); + } + + return tr->startsolid ? 1 : 0; +} + static cell_t smn_TRDidHit(IPluginContext *pContext, const cell_t *params) { sm_trace_t *tr; @@ -923,8 +1089,17 @@ sp_nativeinfo_t g_TRNatives[] = {"TR_TraceRayEx", smn_TRTraceRayEx}, {"TR_TraceHullEx", smn_TRTraceHullEx}, {"TR_GetFraction", smn_TRGetFraction}, + {"TR_GetFractionLeftSolid", smn_TRGetFractionLeftSolid}, + {"TR_GetStartPosition", smn_TRGetStartPosition}, {"TR_GetEndPosition", smn_TRGetEndPosition}, {"TR_GetEntityIndex", smn_TRGetEntityIndex}, + {"TR_GetDisplacementFlags", smn_TRGetDisplacementFlags }, + {"TR_GetSurfaceName", smn_TRGetSurfaceName}, + {"TR_GetSurfaceProps", smn_TRGetSurfaceProps}, + {"TR_GetSurfaceFlags", smn_TRGetSurfaceFlags}, + {"TR_GetPhysicsBone", smn_TRGetPhysicsBone}, + {"TR_AllSolid", smn_TRAllSolid}, + {"TR_StartSolid", smn_TRStartSolid}, {"TR_DidHit", smn_TRDidHit}, {"TR_GetHitGroup", smn_TRGetHitGroup}, {"TR_ClipRayToEntity", smn_TRClipRayToEntity}, diff --git a/plugins/include/sdktools_trace.inc b/plugins/include/sdktools_trace.inc index afa1541f..96102ff8 100644 --- a/plugins/include/sdktools_trace.inc +++ b/plugins/include/sdktools_trace.inc @@ -35,79 +35,133 @@ #endif #define _sdktools_trace_included -#define CONTENTS_EMPTY 0 /**< No contents. */ -#define CONTENTS_SOLID 0x1 /**< an eye is never valid in a solid . */ -#define CONTENTS_WINDOW 0x2 /**< translucent, but not watery (glass). */ -#define CONTENTS_AUX 0x4 -#define CONTENTS_GRATE 0x8 /**< alpha-tested "grate" textures. Bullets/sight pass through, but solids don't. */ -#define CONTENTS_SLIME 0x10 -#define CONTENTS_WATER 0x20 -#define CONTENTS_MIST 0x40 -#define CONTENTS_OPAQUE 0x80 /**< things that cannot be seen through (may be non-solid though). */ -#define LAST_VISIBLE_CONTENTS 0x80 -#define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1)) -#define CONTENTS_TESTFOGVOLUME 0x100 -#define CONTENTS_UNUSED5 0x200 -#define CONTENTS_UNUSED6 0x4000 -#define CONTENTS_TEAM1 0x800 /**< per team contents used to differentiate collisions. */ -#define CONTENTS_TEAM2 0x1000 /**< between players and objects on different teams. */ -#define CONTENTS_IGNORE_NODRAW_OPAQUE 0x2000 /**< ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW. */ -#define CONTENTS_MOVEABLE 0x4000 /**< hits entities which are MOVETYPE_PUSH (doors, plats, etc) */ -#define CONTENTS_AREAPORTAL 0x8000 /**< remaining contents are non-visible, and don't eat brushes. */ -#define CONTENTS_PLAYERCLIP 0x10000 -#define CONTENTS_MONSTERCLIP 0x20000 +#define CONTENTS_EMPTY 0 /**< No contents. */ +#define CONTENTS_SOLID 0x1 /**< an eye is never valid in a solid . */ +#define CONTENTS_WINDOW 0x2 /**< translucent, but not watery (glass). */ +#define CONTENTS_AUX 0x4 +#define CONTENTS_GRATE 0x8 /**< alpha-tested "grate" textures. Bullets/sight pass through, but solids don't. */ +#define CONTENTS_SLIME 0x10 +#define CONTENTS_WATER 0x20 +#define CONTENTS_MIST 0x40 +#define CONTENTS_OPAQUE 0x80 /**< things that cannot be seen through (may be non-solid though). */ +#define LAST_VISIBLE_CONTENTS 0x80 +#define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1)) +#define CONTENTS_TESTFOGVOLUME 0x100 +#define CONTENTS_UNUSED5 0x200 +#define CONTENTS_UNUSED6 0x4000 +#define CONTENTS_TEAM1 0x800 /**< per team contents used to differentiate collisions. */ +#define CONTENTS_TEAM2 0x1000 /**< between players and objects on different teams. */ +#define CONTENTS_IGNORE_NODRAW_OPAQUE 0x2000 /**< ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW. */ +#define CONTENTS_MOVEABLE 0x4000 /**< hits entities which are MOVETYPE_PUSH (doors, plats, etc) */ +#define CONTENTS_AREAPORTAL 0x8000 /**< remaining contents are non-visible, and don't eat brushes. */ +#define CONTENTS_PLAYERCLIP 0x10000 +#define CONTENTS_MONSTERCLIP 0x20000 /** * @section currents can be added to any other contents, and may be mixed */ -#define CONTENTS_CURRENT_0 0x40000 -#define CONTENTS_CURRENT_90 0x80000 -#define CONTENTS_CURRENT_180 0x100000 -#define CONTENTS_CURRENT_270 0x200000 -#define CONTENTS_CURRENT_UP 0x400000 -#define CONTENTS_CURRENT_DOWN 0x800000 +#define CONTENTS_CURRENT_0 0x40000 +#define CONTENTS_CURRENT_90 0x80000 +#define CONTENTS_CURRENT_180 0x100000 +#define CONTENTS_CURRENT_270 0x200000 +#define CONTENTS_CURRENT_UP 0x400000 +#define CONTENTS_CURRENT_DOWN 0x800000 /** * @endsection */ -#define CONTENTS_ORIGIN 0x1000000 /**< removed before bsp-ing an entity. */ -#define CONTENTS_MONSTER 0x2000000 /**< should never be on a brush, only in game. */ -#define CONTENTS_DEBRIS 0x4000000 -#define CONTENTS_DETAIL 0x8000000 /**< brushes to be added after vis leafs. */ -#define CONTENTS_TRANSLUCENT 0x10000000 /**< auto set if any surface has trans. */ -#define CONTENTS_LADDER 0x20000000 -#define CONTENTS_HITBOX 0x40000000 /**< use accurate hitboxes on trace. */ +#define CONTENTS_ORIGIN 0x1000000 /**< removed before bsp-ing an entity. */ +#define CONTENTS_MONSTER 0x2000000 /**< should never be on a brush, only in game. */ +#define CONTENTS_DEBRIS 0x4000000 +#define CONTENTS_DETAIL 0x8000000 /**< brushes to be added after vis leafs. */ +#define CONTENTS_TRANSLUCENT 0x10000000 /**< auto set if any surface has trans. */ +#define CONTENTS_LADDER 0x20000000 +#define CONTENTS_HITBOX 0x40000000 /**< use accurate hitboxes on trace. */ /** * @section Trace masks. */ -#define MASK_ALL (0xFFFFFFFF) -#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that is normally solid */ -#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that blocks player movement */ -#define MASK_NPCSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< blocks npc movement */ -#define MASK_WATER (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME) /**< water physics in these contents */ -#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE) /**< everything that blocks line of sight for AI, lighting, etc */ -#define MASK_OPAQUE_AND_NPCS (MASK_OPAQUE|CONTENTS_MONSTER) /**< everything that blocks line of sight for AI, lighting, etc, but with monsters added. */ -#define MASK_VISIBLE (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players */ -#define MASK_VISIBLE_AND_NPCS (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players, but with monsters added. */ -#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX) /**< bullets see these as solid */ -#define MASK_SHOT_HULL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE) /**< non-raycasted weapons see this as solid (includes grates) */ -#define MASK_SHOT_PORTAL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW) /**< hits solids (not grates) and passes through everything else */ -#define MASK_SOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE) /**< everything normally solid, except monsters (world+brush only) */ -#define MASK_PLAYERSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE) /**< everything normally solid for player movement, except monsters (world+brush only) */ -#define MASK_NPCSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< everything normally solid for npc movement, except monsters (world+brush only) */ -#define MASK_NPCWORLDSTATIC (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< just the world, used for route rebuilding */ -#define MASK_SPLITAREAPORTAL (CONTENTS_WATER|CONTENTS_SLIME) /**< These are things that can split areaportals */ +#define MASK_ALL (0xFFFFFFFF) +#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that is normally solid */ +#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that blocks player movement */ +#define MASK_NPCSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< blocks npc movement */ +#define MASK_WATER (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME) /**< water physics in these contents */ +#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE) /**< everything that blocks line of sight for AI, lighting, etc */ +#define MASK_OPAQUE_AND_NPCS (MASK_OPAQUE|CONTENTS_MONSTER) /**< everything that blocks line of sight for AI, lighting, etc, but with monsters added. */ +#define MASK_VISIBLE (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players */ +#define MASK_VISIBLE_AND_NPCS (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players, but with monsters added. */ +#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX) /**< bullets see these as solid */ +#define MASK_SHOT_HULL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE) /**< non-raycasted weapons see this as solid (includes grates) */ +#define MASK_SHOT_PORTAL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW) /**< hits solids (not grates) and passes through everything else */ +#define MASK_SOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE) /**< everything normally solid, except monsters (world+brush only) */ +#define MASK_PLAYERSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE) /**< everything normally solid for player movement, except monsters (world+brush only) */ +#define MASK_NPCSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< everything normally solid for npc movement, except monsters (world+brush only) */ +#define MASK_NPCWORLDSTATIC (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< just the world, used for route rebuilding */ +#define MASK_SPLITAREAPORTAL (CONTENTS_WATER|CONTENTS_SLIME) /**< These are things that can split areaportals */ /** * @endsection */ + +/** + * @section Surface flags. + */ + +#define SURF_LIGHT 0x0001 /**< value will hold the light strength */ +#define SURF_SKY2D 0x0002 /**< don't draw, indicates we should skylight + draw 2d sky but not draw the 3D skybox */ +#define SURF_SKY 0x0004 /**< don't draw, but add to skybox */ +#define SURF_WARP 0x0008 /**< turbulent water warp */ +#define SURF_TRANS 0x0010 +#define SURF_NOPORTAL 0x0020 /**< the surface can not have a portal placed on it */ +#define SURF_TRIGGER 0x0040 /**< This is an xbox hack to work around elimination of trigger surfaces, which breaks occluders */ +#define SURF_NODRAW 0x0080 /**< don't bother referencing the texture */ +#define SURF_HINT 0x0100 /**< make a primary bsp splitter */ + +#define SURF_SKIP 0x0200 /**< completely ignore, allowing non-closed brushes */ +#define SURF_NOLIGHT 0x0400 /**< Don't calculate light */ +#define SURF_BUMPLIGHT 0x0800 /**< calculate three lightmaps for the surface for bumpmapping */ +#define SURF_NOSHADOWS 0x1000 /**< Don't receive shadows */ +#define SURF_NODECALS 0x2000 /**< Don't receive decals */ +#define SURF_NOCHOP 0x4000 /**< Don't subdivide patches on this surface */ +#define SURF_HITBOX 0x8000 /**< surface is part of a hitbox */ + +/** + * @endsection + */ + +/** + * @section Partition masks. + */ + +#define PARTITION_SOLID_EDICTS (1 << 1) /**< every edict_t that isn't SOLID_TRIGGER or SOLID_NOT (and static props) */ +#define PARTITION_TRIGGER_EDICTS (1 << 2) /**< every edict_t that IS SOLID_TRIGGER */ +#define PARTITION_NON_STATIC_EDICTS (1 << 5) /**< everything in solid & trigger except the static props, includes SOLID_NOTs */ +#define PARTITION_STATIC_PROPS (1 << 7) + +/** + * @endsection + */ + +/** + * @section Displacement flags. + */ + +#define DISPSURF_FLAG_SURFACE (1<<0) +#define DISPSURF_FLAG_WALKABLE (1<<1) +#define DISPSURF_FLAG_BUILDABLE (1<<2) +#define DISPSURF_FLAG_SURFPROP1 (1<<3) +#define DISPSURF_FLAG_SURFPROP2 (1<<4) + +/** + * @endsection + */ + enum RayType { - RayType_EndPoint, /**< The trace ray will go from the start position to the end position. */ - RayType_Infinite /**< The trace ray will go from the start position to infinity using a direction vector. */ + RayType_EndPoint, /**< The trace ray will go from the start position to the end position. */ + RayType_Infinite /**< The trace ray will go from the start position to infinity using a direction vector. */ }; typeset TraceEntityFilter @@ -206,8 +260,7 @@ native void TR_TraceHull(const float pos[3], * @param pos Starting position of the ray. * @param vec Depending on RayType, it will be used as the ending * point, or the direction angle. - * @param triggers If true, enumerate only triggers. Otherwise, enumerate - * only non-triggers. + * @param mask Mask to use for the trace. See PARTITION_* flags. * @param rtype Method to calculate the ray direction. * @param enumerator Function to use as enumerator. For each entity found * along the ray, this function is called. @@ -215,7 +268,7 @@ native void TR_TraceHull(const float pos[3], */ native void TR_EnumerateEntities(const float pos[3], const float vec[3], - bool triggers, + int mask, RayType rtype, TraceEntityEnumerator enumerator, any data=0); @@ -229,8 +282,7 @@ native void TR_EnumerateEntities(const float pos[3], * @param vec Ending position of the ray. * @param mins Hull minimum size. * @param maxs Hull maximum size. - * @param triggers If true, enumerate only triggers. Otherwise, enumerate - * only non-triggers. + * @param mask Mask to use for the trace. See PARTITION_* flags. * @param enumerator Function to use as enumerator. For each entity found * along the ray, this function is called. * @param data Arbitrary data value to pass through to the enumerator. @@ -239,7 +291,7 @@ native void TR_EnumerateEntitiesHull(const float pos[3], const float vec[3], const float mins[3], const float maxs[3], - bool triggers, + int mask, TraceEntityEnumerator enumerator, any data=0); @@ -462,6 +514,25 @@ native Handle TR_ClipCurrentRayToEntityEx(int flags, int entity); */ native float TR_GetFraction(Handle hndl=INVALID_HANDLE); +/** + * Returns the time fraction from a trace result when it left a solid. + * Only valid if trace started in solid + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return Time fraction left solid value of the trace. + * @error Invalid Handle. + */ +native float TR_GetFractionLeftSolid(Handle hndl=INVALID_HANDLE); + +/** + * Returns the starting position of a trace. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @param pos Vector buffer to store data in. + * @error Invalid Handle. + */ +native void TR_GetStartPosition(Handle hndl, float pos[3]); + /** * Returns the collision position of a trace result. * @@ -480,6 +551,71 @@ native void TR_GetEndPosition(float pos[3], Handle hndl=INVALID_HANDLE); */ native int TR_GetEntityIndex(Handle hndl=INVALID_HANDLE); +/** + * Returns the displacement flags for the surface that was hit. See DISPSURF_FLAG_*. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return Displacement flags. + * @error Invalid Handle. + */ +native int TR_GetDisplacementFlags(Handle hndl=INVALID_HANDLE); + +/** + * Returns the name of the surface that was hit. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @param buffer Buffer to store surface name in + * @param maxlen Maximum length of output buffer + * @noreturn + * @error Invalid Handle. + */ +native void TR_GetSurfaceName(Handle hndl, char[] buffer, int maxlen); + +/** + * Returns the surface properties index of the surface that was hit. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return Surface props. + * @error Invalid Handle. + */ +native int TR_GetSurfaceProps(Handle hndl=INVALID_HANDLE); + +/** + * Returns the surface flags. See SURF_*. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return Surface flags. + * @error Invalid Handle. + */ +native int TR_GetSurfaceFlags(Handle hndl=INVALID_HANDLE); + +/** + * Returns the index of the physics bone that was hit. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return Physics bone index. + * @error Invalid Handle. + */ +native int TR_GetPhysicsBone(Handle hndl=INVALID_HANDLE); + +/** + * Returns whether the entire trace was in a solid area. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return True if entire trace was in a solid area, otherwise false. + * @error Invalid Handle. + */ +native bool TR_AllSolid(Handle hndl=INVALID_HANDLE); + +/** + * Returns whether the initial point was in a solid area. + * + * @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result. + * @return True if initial point was in a solid area, otherwise false. + * @error Invalid Handle. + */ +native bool TR_StartSolid(Handle hndl=INVALID_HANDLE); + /** * Returns if there was any kind of collision along the trace ray. *