|
public IsEntityInStartSaferoom(entity) |
|
{ |
|
if ( !IsValidEntity(entity) || GetEntSendPropOffs(entity, "m_vecOrigin", true) == -1 ) { return false; } |
|
|
|
// get entity location |
|
new Float: location[3]; |
|
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", location); |
|
|
|
return IsPointInStartSaferoom(location); |
|
} |
|
|
|
public IsEntityInEndSaferoom(entity) |
|
{ |
|
if ( !IsValidEntity(entity) || GetEntSendPropOffs(entity, "m_vecOrigin", true) == -1 ) { return false; } |
|
|
|
// get entity location |
|
new Float: location[3]; |
|
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", location); |
|
|
|
return IsPointInEndSaferoom(location); |
|
} |
|
|
|
|
|
public IsPlayerInStartSaferoom(client) |
|
{ |
|
if (client < 1 || client > MaxClients || !IsClientInGame(client)) { return false; } |
|
|
|
// get client location |
|
new Float: locationA[3]; |
|
new Float: locationB[3]; |
|
|
|
// try both abs & eye |
|
GetClientAbsOrigin(client, locationA); |
|
GetClientEyePosition(client, locationB); |
|
|
|
return bool: (IsPointInStartSaferoom(locationA) || IsPointInStartSaferoom(locationB)); |
|
} |
|
|
|
public IsPlayerInEndSaferoom(client) |
|
{ |
|
if (client < 1 || client > MaxClients || !IsClientInGame(client)) { return false; } |
|
|
|
// get client location |
|
new Float: locationA[3]; |
|
new Float: locationB[3]; |
|
|
|
// try both abs & eye |
|
GetClientAbsOrigin(client, locationA); |
|
GetClientEyePosition(client, locationB); |
|
|
|
return bool: (IsPointInEndSaferoom(locationA) || IsPointInEndSaferoom(locationB)); |
|
} |
|
|
|
|
|
IsPointInStartSaferoom(Float:location[3], entity=-1) |
|
{ |
|
if (g_iMode == DETMODE_EXACT) |
|
{ |
|
if (!g_bHasStart) { return false; } |
|
|
|
new bool: inSaferoom = false; |
|
|
|
// rotate point if necessary |
|
if (g_fStartRotate) |
|
{ |
|
RotatePoint(g_fStartLocA, location[0], location[1], g_fStartRotate); |
|
} |
|
|
|
// check if the point is inside the box (end or start) |
|
new Float: xMin, Float: xMax; |
|
new Float: yMin, Float: yMax; |
|
new Float: zMin, Float: zMax; |
|
|
|
if (g_fStartLocA[0] < g_fStartLocB[0]) { xMin = g_fStartLocA[0]; xMax = g_fStartLocB[0]; } else { xMin = g_fStartLocB[0]; xMax = g_fStartLocA[0]; } |
|
if (g_fStartLocA[1] < g_fStartLocB[1]) { yMin = g_fStartLocA[1]; yMax = g_fStartLocB[1]; } else { yMin = g_fStartLocB[1]; yMax = g_fStartLocA[1]; } |
|
if (g_fStartLocA[2] < g_fStartLocB[2]) { zMin = g_fStartLocA[2]; zMax = g_fStartLocB[2]; } else { zMin = g_fStartLocB[2]; zMax = g_fStartLocA[2]; } |
|
|
|
PrintDebug("dimensions checked: %f - %f (%f) -- %f - %f (%f) -- %f - %f (%f)", xMin, xMax, location[0], yMin, yMax, location[1], zMin, zMax, location[2]); |
|
|
|
inSaferoom = bool: ( location[0] >= xMin && location[0] <= xMax |
|
&& location[1] >= yMin && location[1] <= yMax |
|
&& location[2] >= zMin && location[2] <= zMax ); |
|
|
|
// two-part saferooms: |
|
if (!inSaferoom && g_bHasStartExtra) |
|
{ |
|
if (g_fStartLocC[0] < g_fStartLocD[0]) { xMin = g_fStartLocC[0]; xMax = g_fStartLocD[0]; } else { xMin = g_fStartLocD[0]; xMax = g_fStartLocC[0]; } |
|
if (g_fStartLocC[1] < g_fStartLocD[1]) { yMin = g_fStartLocC[1]; yMax = g_fStartLocD[1]; } else { yMin = g_fStartLocD[1]; yMax = g_fStartLocC[1]; } |
|
if (g_fStartLocC[2] < g_fStartLocD[2]) { zMin = g_fStartLocC[2]; zMax = g_fStartLocD[2]; } else { zMin = g_fStartLocD[2]; zMax = g_fStartLocC[2]; } |
|
|
|
PrintDebug("extra dimensions checked: %f - %f (%f) -- %f - %f (%f) -- %f - %f (%f)", xMin, xMax, location[0], yMin, yMax, location[1], zMin, zMax, location[2]); |
|
|
|
inSaferoom = bool: ( location[0] >= xMin && location[0] <= xMax |
|
&& location[1] >= yMin && location[1] <= yMax |
|
&& location[2] >= zMin && location[2] <= zMax ); |
|
} |
|
|
|
return inSaferoom; |
|
} |
|
else if (g_bLGOIsAvailable) |
|
{ |
|
// trust confogl / mapinfo |
|
|
|
new Float:saferoom_distance = LGO_GetMapValueFloat("start_dist", SR_RADIUS); |
|
new Float:saferoom_distance_extra = LGO_GetMapValueFloat("start_extra_dist", 0.0); |
|
new Float:saferoom[3]; |
|
LGO_GetMapValueVector("start_point", saferoom, NULL_VECTOR); |
|
|
|
if ( entity != -1 && IsValidEntity(entity) && GetEntSendPropOffs(entity, "m_vecOrigin", true) != -1 ) |
|
{ |
|
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", location); |
|
} |
|
|
|
// distance to entity |
|
return bool: ( GetVectorDistance(location, saferoom) <= ((saferoom_distance_extra > saferoom_distance) ? saferoom_distance_extra : saferoom_distance) ); |
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
IsPointInEndSaferoom(Float:location[3], entity = -1) |
|
{ |
|
if (g_iMode == DETMODE_EXACT) |
|
{ |
|
if (!g_bHasEnd) { return false; } |
|
|
|
new bool: inSaferoom = false; |
|
|
|
// rotate point if necessary |
|
if (g_fEndRotate) |
|
{ |
|
RotatePoint(g_fEndLocA, location[0], location[1], g_fEndRotate); |
|
} |
|
|
|
|
|
// check if the point is inside the box (end or start) |
|
new Float: xMin, Float: xMax; |
|
new Float: yMin, Float: yMax; |
|
new Float: zMin, Float: zMax; |
|
|
|
if (g_fEndLocA[0] < g_fEndLocB[0]) { xMin = g_fEndLocA[0]; xMax = g_fEndLocB[0]; } else { xMin = g_fEndLocB[0]; xMax = g_fEndLocA[0]; } |
|
if (g_fEndLocA[1] < g_fEndLocB[1]) { yMin = g_fEndLocA[1]; yMax = g_fEndLocB[1]; } else { yMin = g_fEndLocB[1]; yMax = g_fEndLocA[1]; } |
|
if (g_fEndLocA[2] < g_fEndLocB[2]) { zMin = g_fEndLocA[2]; zMax = g_fEndLocB[2]; } else { zMin = g_fEndLocB[2]; zMax = g_fEndLocA[2]; } |
|
|
|
PrintDebug("dimensions checked: %f - %f (%f) -- %f - %f (%f) -- %f - %f (%f)", xMin, xMax, location[0], yMin, yMax, location[1], zMin, zMax, location[2]); |
|
|
|
inSaferoom = bool: ( location[0] >= xMin && location[0] <= xMax |
|
&& location[1] >= yMin && location[1] <= yMax |
|
&& location[2] >= zMin && location[2] <= zMax ); |
|
|
|
// two-part saferooms: |
|
if (!inSaferoom && g_bHasEndExtra) |
|
{ |
|
if (g_fEndLocC[0] < g_fEndLocD[0]) { xMin = g_fEndLocC[0]; xMax = g_fEndLocD[0]; } else { xMin = g_fEndLocD[0]; xMax = g_fEndLocC[0]; } |
|
if (g_fEndLocC[1] < g_fEndLocD[1]) { yMin = g_fEndLocC[1]; yMax = g_fEndLocD[1]; } else { yMin = g_fEndLocD[1]; yMax = g_fEndLocC[1]; } |
|
if (g_fEndLocC[2] < g_fEndLocD[2]) { zMin = g_fEndLocC[2]; zMax = g_fEndLocD[2]; } else { zMin = g_fEndLocD[2]; zMax = g_fEndLocC[2]; } |
|
|
|
PrintDebug("extra dimensions checked: %f - %f (%f) -- %f - %f (%f) -- %f - %f (%f)", xMin, xMax, location[0], yMin, yMax, location[1], zMin, zMax, location[2]); |
|
|
|
inSaferoom = bool: ( location[0] >= xMin && location[0] <= xMax |
|
&& location[1] >= yMin && location[1] <= yMax |
|
&& location[2] >= zMin && location[2] <= zMax ); |
|
} |
|
|
|
return inSaferoom; |
|
} |
|
else if (g_bLGOIsAvailable) |
|
{ |
|
// trust confogl / mapinfo |
|
|
|
new Float:saferoom_distance = LGO_GetMapValueFloat("end_dist", SR_RADIUS); |
|
new Float:saferoom[3]; |
|
LGO_GetMapValueVector("end_point", saferoom, NULL_VECTOR); |
|
|
|
if ( entity != -1 && IsValidEntity(entity) && GetEntSendPropOffs(entity, "m_vecOrigin", true) != -1 ) |
|
{ |
|
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", location); |
|
} |
|
|
|
// distance to entity |
|
return bool: ( GetVectorDistance(location, saferoom) <= saferoom_distance ); |
|
} |
|
|
|
return false; |
|
} |
Latest Left 4 DHooks introduces more nav stuff and spawn attributes become available, pretty clean in use.
Pratically this was used in one of my plugin
l4d2_spit_spread_patchand worked without issues.Related plugin sources:
L4D2-Competitive-Rework/addons/sourcemod/scripting/l4d2_saferoom_detect.sp
Lines 160 to 345 in 5f553ac
L4D2-Competitive-Rework/addons/sourcemod/scripting/confoglcompmod/MapInfo.sp
Lines 339 to 356 in 14e2603
L4D2-Competitive-Rework/addons/sourcemod/scripting/l4d2lib/mapinfo.sp
Lines 314 to 339 in c048ca7
L4D2-Competitive-Rework/addons/sourcemod/scripting/confoglcompmod/WeaponInformation.sp
Lines 1035 to 1050 in 14e2603
L4D2-Competitive-Rework/addons/sourcemod/scripting/confoglcompmod/WeaponInformation.sp
Lines 894 to 918 in 14e2603
L4D2-Competitive-Rework/addons/sourcemod/scripting/nosaferoomkits.sp
Lines 44 to 72 in c0e5ae9