16/12/2019, 06:06 PM
Hay alguna forma de detectar cuando una entidad del tipo func_tracktrain le toca la cabeza a algún jugador? Lo que quiero es que si algún jugador esta debajo de esa entidad lo mate porque en teoría la esta bugeando.
(17/12/2019, 11:30 AM)kryder11 escribió: [ -> ]Con la primera opción no se puede. El func_tracktrain nunca toca el suelo (pev_groundentity). La segunda no tengo ni idea de como hacerla... la verdad que con los vectores no voy muy alla.
Tiene que haber alguna forma de detectar si el func_tracktrain le toca la cabeza al jugador...
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#define PLUGIN ""
#define VERSION "0.0.1"
new g_iMaxPlayers
#define IsPlayer(%0) ( 1 <= (%0) <= g_iMaxPlayers )
public plugin_init()
{
register_plugin( PLUGIN, VERSION, "ConnorMcLeod" )
RegisterHam(Ham_Player_PostThink, "func_tracktrain", "OnCBasePlayer_PostThink", false)
g_iMaxPlayers = get_maxplayers()
}
public OnCBasePlayer_PostThink( ent )
{
if(!pev_valid(ent) )
{
//Una entidad no tiene velocidad de caida por lo que lo siguiente se comenta
//new Float:flFallVelocity = get_pdata_float(id, m_flFallVelocity)
//if( flFallVelocity > 10.0 )
//{
// No puedo obtener el target si la entidad NO TIENE pev_groundentity
new target = pev(ent, pev_groundentity) // <-- No da ningun target
if( IsPlayer(target) && is_user_alive(target) )
{
ExecuteHam(Ham_TakeDamage, target, id, id, flFallVelocity * 0.1, DMG_FALL)
}
//}
}
}
(19/12/2019, 10:54 PM)Gonza.-* escribió: [ -> ]Tenes que usar Ham_Touch, no postthink. Los argumentos que devuelve son los que necesitas, id de entidad e id del player, toucher touched
(19/12/2019, 11:01 PM)Gonza.-* escribió: [ -> ]para detectar si toca la cabeza usas min y mix size de ambas entidades, así hacía yo en mi blockmaker para el antibug de los bhop, si tocaban de abajo con la cabeza return...
(17/12/2019, 11:30 AM)kryder11 escribió: [ -> ]Con la primera opción no se puede. El func_tracktrain nunca toca el suelo (pev_groundentity). La segunda no tengo ni idea de como hacerla... la verdad que con los vectores no voy muy alla.
Tiene que haber alguna forma de detectar si el func_tracktrain le toca la cabeza al jugador...
(23/12/2019, 05:55 AM)Gonza.-* escribió: [ -> ]Con respecto a lo que dice raulitop, si vas a hacerlo de la manera que te dijo toto, ten cuidado con los negativos se refiere al eje Z en origin, puede que en algun mapa ande y en otro no debido a que el centro del eje Z (0) no sea el punto mas "bajo" del mapa, y de la casualidad que en esa parte está tu trenOh my god. Me entendió rapidísimo
public fw_TouchTrain(entity, caller)
{
// Player died
if(!is_user_alive(caller)) return HAM_IGNORED;
// Invalid entity
if (!pev_valid(entity)) return HAM_IGNORED;
static Float:fMaxs[2][3], Float:fMins[2][3], Float:fOrigin[2][3], Float:posicionCabeza, Float:posicionTracktrain
static ID, ENT; ID = 0; ENT = 1
pev(caller, pev_origin, fOrigin[ID])
pev(entity, pev_origin, fOrigin[ENT])
pev(caller, pev_mins, fMins[ID])
pev(entity, pev_mins, fMins[ENT])
pev(caller, pev_maxs, fMaxs[ID])
pev(entity, pev_maxs, fMaxs[ENT])
posicionCabeza = fOrigin[ID][2] + fMaxs[ID][2]
posicionTracktrain = fOrigin[ENT][2] - floatabs(fMins[ENT][2])
client_print(0, print_chat, "P.T: %f", posicionTracktrain)
client_print(0, print_chat, "P.C: %f", posicionCabeza)
if(posicionCabeza < posicionTracktrain+2.0)
{
client_print(0, print_chat, "estoy debajo")
}
P.T: -56.883998
P.C: -55.968750
estoy debajo
new const NameEntArsenalBox[] = "ArsenalBox"
public plugin_init() {
RegisterHam(Ham_Touch, "info_target", "fw_ArsenalBoxTouched_Post", true)
}
public fw_ArsenalBoxTouched_Post(ent, toucher)
{
if(!pev_valid(ent) || !is_user_alive(toucher))
return HAM_IGNORED;
new classname[32]
entity_get_string(ent, EV_SZ_classname, classname, charsmax(classname))
if(equal(classname, NameEntArsenalBox))
{
ColorChat(toucher, NORMAL, "^4%s^3 Estas tocando la entidad! CAJA", g_playername[toucher])
}
return HAM_IGNORED;
}
(25/12/2019, 10:28 PM)Gonza.-* escribió: [ -> ]con respecto a que no te detecta hasta que te muevas, entonces tendras que usar think, tambien en mi plugin de bcm expmod tenes la funcion que necesitas, chequeas los mismos parametros (origin y min/max) usando este metodo ya no vas a necesitar al jugador con movimiento para detectar el touch, y tu helicoptero podrá aterrizar! Saludos!
public fwPreThink(iEnt)
{
// se me ocurren dos metodos
// 1. trace
// 2. loop y comprobar origins de los jugadores
// que venga metalicross y diga cual es mas eficiente xD
static Float:fEntOrigin[3];
entity_get_vector(iEnt, EV_VEC_origin, fEntOrigin);
static Float:fEntMins[3], Float:fEntMaxs[3] = {0.0, 0.0, 0.0};
if (fEntMaxs[0] == 0.0)
{
entity_get_vector(iEnt, EV_VEC_mins, fEntMins);
entity_get_vector(iEnt, EV_VEC_maxs, fEntMaxs);
}
// metodo 1: trace
// se haran traces en lineas horizontales, a 5 unidades bajo el minimo de la entidad
// dejando fPlayerMinWidth unidades de espacio entre los traces
const Float:fPlayerMinWidth = 32.0; // creo que es 32? obtener con floatmin(fPlayerMaxs[0] - fPlayerMins[0], fPlayerMaxs[1] - fPlayerMins[1])
static iIterNum = 0;
if (!iIterNum)
{
iIterNum = floatround((fEntMaxs[1] - fEntMins[1]) / fPlayerMinWidth, floatround_floor);
}
static Float:fTraceStart[3], Float:fTraceEnd[3];
xs_vec_add(fEntOrigin, fEntMins, fTraceStart);
fTraceStart[2] -= 5.0;
xs_vec_copy(fTraceStart, fTraceEnd);
fTraceEnd[0] = fEntOrigin[0] + fEntMaxs[0];
static iFoundEnt, Float:fFoundEntOrigin[3];
for (new i = 0; i < iIterNum; i++)
{
iFoundEnt = trace_line(0, fTraceStart, fTraceEnd, fFoundEntOrigin);
if (is_user_alive(iFoundEnt))
{
// kill?
user_kill(iFoundEnt);
}
fTraceStart[1] += fPlayerMinWidth;
fTraceEnd[1] = fTraceStart[1];
}
// metodo 2: loop
// se comprobara que el origin de cada player este entre los limites en X e Y, y a menos de 5 unidades en Z
static Float:fPlayerOrigin[3], Float:fPlayerMins[3], Float:fPlayerMaxs[3];
static Float:fEntAbsoluteMaxs[3], Float:fEntAbsoluteMins[3], Float:fAbsoluteZ;
xs_vec_add(fEntOrigin, fEntMins, fEntAbsoluteMins);
xs_vec_add(fEntOrigin, fEntMaxs, fEntAbsoluteMaxs);
// los mins y maxs del player no son los mismos si el jugador esta de pie o duckeado
static players[32], num, iId;
get_players(players, num, "a");
for (new i = 0; i < num; i++)
{
iId = players[i];
if (!is_user_alive(iId))
{
continue;
}
entity_get_vector(iId, EV_VEC_origin, fPlayerOrigin);
entity_get_vector(iId, EV_VEC_mins, fPlayerMins);
entity_get_vector(iId, EV_VEC_maxs, fPlayerMaxs);
fAbsoluteZ = fPlayerOrigin[2] + fPlayerMaxs[2];
xs_vec_add(fEntAbsoluteMins, fPlayerMins, fPlayerMins);
xs_vec_add(fEntAbsoluteMaxs, fPlayerMaxs, fPlayerMaxs);
if (fPlayerMins[0] <= fPlayerOrigin[0] <= fPlayerMaxs[0] && fPlayerMins[1] <= fPlayerOrigin[1] <= fPlayerMaxs[1] && fEntAbsoluteMins[2] - fAbsoluteZ <= 5.0)
{
// kill?
user_kill(iId);
}
}
}
void CFuncTrackTrain::Blocked(CBaseEntity *pOther)
{
entvars_t *pevOther = pOther->pev;
// Blocker is on-ground on the train
if ((pevOther->flags & FL_ONGROUND) && VARS(pevOther->groundentity) == pev)
{
real_t deltaSpeed = Q_fabs(real_t(pev->speed));
if (deltaSpeed > 50)
{
deltaSpeed = 50;
}
if (!pevOther->velocity.z)
{
pevOther->velocity.z += deltaSpeed;
}
return;
}
else
pevOther->velocity = (pevOther->origin - pev->origin).Normalize() * pev->dmg;
ALERT(at_aiconsole, "TRAIN(%s): Blocked by %s (dmg:%.2f)\n", STRING(pev->targetname), STRING(pOther->pev->classname), pev->dmg);
#ifdef REGAMEDLL_FIXES
if (pev->dmg <= 0)
return;
// we can't hurt this thing, so we're not concerned with it
pOther->TakeDamage(pev, pev, pev->dmg, DMG_CRUSH);
#endif
}
RegisterHam(Ham_Blocked, "func_tracktrain", "fw_Block")
public fw_Block(entity, blocker)
{
// Player died
if(!is_user_alive(blocker)) return HAM_IGNORED;
// Invalid entity
if (!pev_valid(entity)) return HAM_IGNORED;
user_kill(blocker, 1)
return HAM_IGNORED
}