-
Notifications
You must be signed in to change notification settings - Fork 153
Description
#define DOOR_RANGE_TOLLERANCE 2000.0
bool IsEntityInSaferoom(int entity, bool bStartSaferoom)
{
float vecPos[3];
GetEntPropVector(entity, Prop_Data, "m_vecAbsOrigin", vecPos);
Address nav = L4D_GetNearestNavArea(vecPos);
if (nav != Address_Null)
{
int spawnAttributes = L4D_GetNavArea_SpawnAttributes(nav);
if (spawnAttributes & NAV_SPAWN_CHECKPOINT)
{
return bStartSaferoom != L4D2Direct_GetTerrorNavAreaFlow(nav) > DOOR_RANGE_TOLLERANCE;
}
}
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_patch and worked without issues.
Related plugin sources:
L4D2-Competitive-Rework/addons/sourcemod/scripting/l4d2_saferoom_detect.sp
Lines 160 to 345 in 5f553ac
| 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; | |
| } |
L4D2-Competitive-Rework/addons/sourcemod/scripting/confoglcompmod/MapInfo.sp
Lines 339 to 356 in 14e2603
| stock bool IsEntityInSaferoom(int ent, int saferoom = 3) //ItemTracking (commented out) | |
| { | |
| float origins[3]; | |
| GetEntPropVector(ent, Prop_Send, "m_vecOrigin", origins); | |
| if ((saferoom & START_SAFEROOM) | |
| && (GetVectorDistance(origins, Start_Point) <= ((Start_Extra_Dist > Start_Dist) ? Start_Extra_Dist : Start_Dist)) | |
| ) { | |
| return true; | |
| } else if ((saferoom & END_SAFEROOM) && (GetVectorDistance(origins, End_Point) <= End_Dist)) { | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| // return ((GetVectorDistance(origins, Start_Point) <= ((Start_Extra_Dist > Start_Dist) ? Start_Extra_Dist : Start_Dist)) | |
| // || (GetVectorDistance(origins, End_Point) <= End_Dist)); | |
| } |
L4D2-Competitive-Rework/addons/sourcemod/scripting/l4d2lib/mapinfo.sp
Lines 314 to 339 in c048ca7
| /** | |
| * Determines if an entity is in a start or end saferoom (based on mapinfo.txt or automatically generated info) | |
| * | |
| * @param ent The entity to be checked | |
| * @return eSaferoom_Neither if entity is not in any saferoom | |
| * eSaferoom_Start if it is in the starting saferoom | |
| * eSaferoom_End if it is in the ending saferoom | |
| * eSaferoom_Start | eSaferoom_End if it is in both saferooms (probably won't happen) | |
| */ | |
| static int IsEntityInSaferoom(int iEntity) | |
| { | |
| int iResult = eSaferoom_Neither; | |
| float fOrigins[3]; | |
| GetEntPropVector(iEntity, Prop_Send, "m_vecOrigin", fOrigins); | |
| if ((GetVectorDistance(fOrigins, g_fStartPoint) <= (g_fStartExtraDist > g_fStartDist ? g_fStartExtraDist : g_fStartDist))) { | |
| iResult |= eSaferoom_Start; | |
| } | |
| if (GetVectorDistance(fOrigins, g_fEndPoint) <= g_fEndDist) { | |
| iResult |= eSaferoom_End; | |
| } | |
| return iResult; | |
| } |
L4D2-Competitive-Rework/addons/sourcemod/scripting/confoglcompmod/WeaponInformation.sp
Lines 1035 to 1050 in 14e2603
| float fOrigin[3]; | |
| GetEntPropVector(iEntity, Prop_Send, "m_vecOrigin", fOrigin); | |
| bool bIsInStartSaferoom = false, bIsInStartSaferoomExtra = false; | |
| bool bIsInEndSaferoom = false, bIsInFinaleArea = false; | |
| float fStartDistance = GetVectorDistance(Weapon_fMapOrigin_Start, fOrigin); | |
| if (fStartDistance <= Weapon_fMapDist_Start) { | |
| bIsInStartSaferoom = true; | |
| bIsInStartSaferoomExtra = true; | |
| } else if (fStartDistance <= Weapon_fMapDist_StartExtra) { | |
| bIsInStartSaferoomExtra = true; | |
| } else if (GetVectorDistance(Weapon_fMapOrigin_End, fOrigin) <= Weapon_fMapDist_End) { | |
| bIsInFinaleArea = (L4D_IsMissionFinalMap()); | |
| } |
L4D2-Competitive-Rework/addons/sourcemod/scripting/confoglcompmod/WeaponInformation.sp
Lines 894 to 918 in 14e2603
| bool bIsInSaferoom = false; | |
| GetEntPropVector(iEntity, Prop_Send, "m_vecOrigin", fOrigin); | |
| // Within start safe room | |
| if (!Weapon_bReplaceTier2_All && IsVersus()) { | |
| if (GetVectorDistance(Weapon_fMapOrigin_Start, fOrigin) > Weapon_fMapDist_StartExtra | |
| && GetVectorDistance(Weapon_fMapOrigin_End, fOrigin) > Weapon_fMapDist_End | |
| ) { | |
| #if (DEBUG_WI) | |
| LogMessage("[%s] Weapon is outside of a saferoom", WI_MODULE_NAME); | |
| #endif | |
| if (!bSpawnerEvent) { | |
| #if (DEBUG_WI) | |
| LogMessage("[%s] }", WI_MODULE_NAME); | |
| #endif | |
| return; | |
| } | |
| } else { | |
| #if (DEBUG_WI) | |
| LogMessage("[%s] Weapon is inside a saferoom", WI_MODULE_NAME); | |
| #endif | |
| bIsInSaferoom = true; | |
| } | |
| } |
L4D2-Competitive-Rework/addons/sourcemod/scripting/nosaferoomkits.sp
Lines 44 to 72 in c0e5ae9
| void FindSurvivorStart() | |
| { | |
| int iEntityCount = GetEntityCount(); | |
| char EdictClassName[128]; | |
| float Location[3]; | |
| //Search entities for either a locked saferoom door, | |
| for (int i = 0; i <= iEntityCount; i++) { | |
| if (IsValidEntity(i)) { | |
| GetEdictClassname(i, EdictClassName, sizeof(EdictClassName)); | |
| if ((StrContains(EdictClassName, "prop_door_rotating_checkpoint", false) != -1) && (GetEntProp(i, Prop_Send, "m_bLocked")== 1)) { | |
| GetEntPropVector(i, Prop_Send, "m_vecOrigin", Location); | |
| SurvivorStart = Location; | |
| return; | |
| } | |
| } | |
| } | |
| //or a survivor start point. | |
| for (int i = 0; i <= iEntityCount; i++) { | |
| if (IsValidEntity(i)) { | |
| GetEdictClassname(i, EdictClassName, sizeof(EdictClassName)); | |
| if (StrContains(EdictClassName, "info_survivor_position", false) != -1) { | |
| GetEntPropVector(i, Prop_Send, "m_vecOrigin", Location); | |
| SurvivorStart = Location; | |
| return; | |
| } | |
| } | |
| } | |
| } |