Helloes
DISCLAIMER: I have never done SourceMod scripting
What you are trying to accomplish might be something like this:
1) You have the origin of the target player, the center of the explosion
2) Loop through all players (skip the target player to avoid division by zero =P )
2.1) for each player: calculate the distance: get his origin, subtract the two vectors, compute VectorLength (either through a native or by using good old pythagoras)
2.2) if that distance is <= MAXRADIUS, the player is potentially in your explosion radius. If the distance is greater, skip this player as he is unaffected
2.3) Now the trace ray would be used - basically only in order to find out whether there is a wall between the explosion center point and the currently examined player. The start position of the trace ray would be the explosion center point, the direction vector would be (current loop player origin - explosion center point) (you might need to normalise this vector or you might not, I don't know). It can be an infinite trace because you're going to hit the player in that diretion anyway. With the mask flags you can decide what makes the trace stop and what is ignored. You might also need to set up a filter function and filter out the target player if the trace hits him. Then if
TR_GetEntityIndex returns the index of the player's entity which is in the current loop, the trace didn't hit anything else in between, so there was no wall and you can safely let the player explode.
You could also make the damage done depend on the distance.
The easiest way would be a linear relation: damage = MAX_DAMAGE * (MAX_RADIUS - distance) / MAX_RADIUS
edit: pseudo code added:
Code:
new g_FilteredEntity = -1;
public bool:MyTraceFilter(ent, contentMask)
{
return (ent == g_FilteredEntity) ? false : true;
}
// variable center_point: the target player's origin
g_FilteredEntity = target_player_id; // player id == entity index!?
for (loop through all players)
{
// variable cur_player_id is the current eximaned player's id
// variable cur_player_pos is his origin
distance = GetVectorDistance(cur_player_pos, center_point);
if (distance < MAX_RADIUS)
{
// he is in the radius - is there something between the explosion center and the player?
new Float:trace_dir[3];
SubtractVectors(cur_player_pos, center_point, trace_dir);
TR_TraceRayFilter(center_point, trace_dir, RayType_Infinite, MASK_SOLID, MyFilterFunction);
if (TR_GetEntityIndex() == cur_player_id) // player id == entity index!?
{
// HE SHALL EXPLODE (nothing else was in between)
}
}
}
edit2: ohnoes my words said something different than the code. The filter function's purpose is to make sure that the trace doesn't hit the target player - the one where the trace begins, as it MIGHT hit his own hitbox and thus not go too far. I corrected the g_FilteredEntity variable now. Note that this is probably not needed for MASK_SOLID as player hitboxes are not included in that. See the sdktools_trace api reference.
__________________