this is it, the plugin fixes the player blocking moving platforms like func_tracktrain. If the plugin detects a blockage, it gently moves the player to the side and the platform continues to move. The plugin was written for the Zombie Escape mod, where players often manage to block the helicopter.
PHP Code:
#include <amxmodx>
#include <hamsandwich>
#include <fakemeta>
#if AMXX_VERSION_NUM < 183
#define NULL_VECTOR {0.0, 0.0, 0.0}
#endif
enum _:XYZ { Float:X, Float:Y, Float:Z }
new const Float:g_fSize[][XYZ] = {
{0.0, 2.0, 0.0}, {0.0, -2.0, 0.0}, {2.0, 0.0, 0.0}, {-2.0, 0.0, 0.0}
}
new g_Cvar_TraceMode
new bool:g_bSemiclipFound
/* -------------------- */
public plugin_init() {
register_plugin("AutoUnstuck", "0.2", "alliedmodders")
RegisterHam(Ham_Blocked, "func_tracktrain", "OnBlocked_Pre")
bind_pcvar_num(create_cvar("amx_unstuck_trace_mode", "-1"), g_Cvar_TraceMode)
g_bSemiclipFound = (get_cvar_pointer("resemiclip_version") != 0)
}
/* -------------------- */
public OnBlocked_Pre(pBlocked, pBlocker) {
if(is_user_alive(pBlocker)) {
// unstuck in next frame as EngFunc_SetOrigin won't work in this frame (even if superceded, even in post)
RequestFrame("func_Unstuck", pBlocker)
}
}
/* -------------------- */
public func_Unstuck(pBlocker) {
if(!is_user_alive(pBlocker)) {
return
}
new Float:fOrigin[XYZ], Float:fMins[XYZ], Float:fVec[XYZ], iHull
pev(pBlocker, pev_origin, fOrigin)
iHull = (pev(pBlocker, pev_flags) & FL_DUCKING) ? HULL_HEAD : HULL_HUMAN;
pev(pBlocker, pev_mins, fMins)
for(new a; a < sizeof(g_fSize); a++) {
fVec[X] = fOrigin[X] - fMins[X] * g_fSize[a][X]
fVec[Y] = fOrigin[Y] - fMins[Y] * g_fSize[a][Y]
fVec[Z] = fOrigin[Z] - fMins[Z] * g_fSize[a][Z]
if(is_hull_vacant(fVec, iHull, pBlocker)) {
//client_print(pBlocker, print_chat, "[%i] Unstuck %i", a, random_num(0, 9999))
engfunc(EngFunc_SetOrigin, pBlocker, fVec)
set_pev(pBlocker, pev_velocity, NULL_VECTOR)
return
}
}
user_kill(pBlocker)
}
/* -------------------- */
stock bool:is_hull_vacant(const Float:fOrigin[XYZ], iHull, pPlayer) {
new iTraceResult
engfunc(EngFunc_TraceHull, fOrigin, fOrigin, func_GetTraceMode(), iHull, pPlayer, iTraceResult)
return (!get_tr2(iTraceResult, TR_StartSolid) || !get_tr2(iTraceResult, TR_AllSolid))
}
/* -------------------- */
func_GetTraceMode() {
switch(g_Cvar_TraceMode) {
case -1: return g_bSemiclipFound ? IGNORE_MONSTERS : DONT_IGNORE_MONSTERS;
case 0: return DONT_IGNORE_MONSTERS
case 1: return IGNORE_MONSTERS
}
return IGNORE_MONSTERS
}