Veteran Member
|
04-26-2010
, 13:00
Re: Get player's hitboxes?
|
#31
|
Трейсит параллелепипед из точки А в точку Б и записывает результат туда, куда ты хочешь. Вот я его использовал для своих ботов чтобы узнать, можно ли пройти пешком:
PHP Code:
public bool:IsTargetVisible (const Float:coords1[3], const Float:coords2[3], const VisibilityFilter:filter, const startentindex, const endentindex) { decl Handle:ray; switch (filter) { case FILTER_NODE_LINKING:{ new Float:mins[]={-24.0, -24.0, 0.0}; new Float:maxs[]={24.0, 24.0, 60.0}; ray=TR_TraceHullFilterEx(coords1, coords2, mins, maxs, MASK_PLAYERSOLID, FilterNodeLinking); if (TR_DidHit(ray)) { CloseHandle(ray); return false; } CloseHandle(ray); return true; } case FILTER_BOT_NAVIGATION:{ new Float:mins[]={-24.0, -24.0, 0.0}; new Float:maxs[]={24.0, 24.0, 60.0}; ray=TR_TraceHullFilterEx(coords1, coords2, mins, maxs, MASK_PLAYERSOLID, FilterBotNavigation, startentindex); if (TR_DidHit(ray)) { if (TR_GetEntityIndex(ray)==endentindex) { CloseHandle(ray); return true; } CloseHandle(ray); return false; } else { CloseHandle(ray); return true; } } case FILTER_PLAYER_VISIBLE:{ ray=TR_TraceRayFilterEx(coords1, coords2, MASK_PLAYERSOLID, RayType_EndPoint, FilterPlayerVisible, startentindex); if (TR_GetEntityIndex(ray)==endentindex) { CloseHandle(ray); return true; } CloseHandle(ray); return false; } } return false; } public bool:FilterNodeLinking (entity, mask) { if(entity <=32) { return false; } else { decl String:entclass[64]; GetEdictClassname(entity, entclass, 64); decl enttype; if (!GetTrieValue(NodeLinkPassTrie, entclass, enttype)) { return true; } else { return false; } } } public bool:FilterBotNavigation (entity, mask, any:startent) { if (entity == startent) { return false; } else { decl String:entclass[64]; GetEdictClassname(entity, entclass, 64); decl enttype; if (!GetTrieValue(BotNavigationVisTrie, entclass, enttype)) { return true; } else { switch (enttype) { case PASS_ALWAYS:{return false;} case PASS_TEAM_ONLY:{ if ((startent<33)&&(startent>0)) { if (PlayerTeam[startent]==Team:GetEntProp(entity, Prop_Send, "m_iTeamNum")) { return false; } else { return true; } } else { return false; } } case PASS_TEAM_ONLY_NOT_SELF:{ if ((startent<33)&&(startent>0)) { if ((PlayerTeam[startent]==Team:GetEntProp(entity, Prop_Send, "m_iTeamNum"))&&(GetEntPropEnt(entity, Prop_Send, "m_hBuilder")!=startent)) { return false; } else { return true; } } else { return false; } } } } } return true; } public bool:FilterPlayerVisible (entity, mask, any:client) { if (entity == client) { return false; } else { decl String:entclass[64]; GetEdictClassname(entity, entclass, 64); decl enttype; if (!GetTrieValue(PlayerVisTrie, entclass, enttype)) { return true; } else { switch (enttype) { case PASS_ALWAYS:{return false;} case PASS_TEAM_ONLY:{ if (PlayerTeam[client]==Team:GetEntProp(entity, Prop_Send, "m_iTeamNum")) { return false; } else { return true; } } } } } return true; } public Walkability:IsTargetWalkable (const Float:coords1[3], const Float:coords2[3], const Float:coords3, const bool:brush, const VisibilityFilter:filter, const startent, const endent) { if (!CheckForPit(coords1, filter, startent)) { return PIT_START; } if (!CheckForPit(coords2, filter, startent)) { return PIT_END; } new numchecks=1; decl Float:endcoords[3]; endcoords=coords2; if (brush) { numchecks=RoundToFloor(FloatAbs(coords3-coords2[2])/32.0); } for (new i=0;i<numchecks;i++) { if (IsTargetVisible(coords1, endcoords, filter, startent, endent)) { decl Float:coords2D1[2]; decl Float:coords2D2[2]; decl Float:distance2D; coords2D1[0]=coords1[0]; coords2D1[1]=coords1[1]; coords2D2[0]=endcoords[0]; coords2D2[1]=endcoords[1]; distance2D=GetDistance2D(coords2D1, coords2D2); if (distance2D>(FloatAbs(coords1[2]-endcoords[2]))) { if (distance2D>49.0) { new numrays=RoundToFloor(distance2D/49.0); decl Float:raystartcoords[3]; decl Float:offset[3]; offset[0]=49.0*Cosine(ArcTangent((endcoords[1]-coords1[1])/(endcoords[0]-coords1[0]))); if (coords1[0]>endcoords[0]) { offset[0]=0.0-offset[0]; } raystartcoords[0]=coords1[0]+offset[0]; offset[1]=SquareRoot(2401.0-Pow(offset[0], 2.0)); if (coords1[1]>endcoords[1]) { offset[1]=0.0-offset[1]; } raystartcoords[1]=coords1[1]+offset[1]; raystartcoords[2]=((raystartcoords[0]-coords1[0])*(endcoords[2]-coords1[2]))/(endcoords[0]-coords1[0])+coords1[2]; offset[2]=raystartcoords[2]-coords1[2]; for (new j=1;j<=numrays;j++) { if ((brush)&&(IsPositionInBrush(raystartcoords, endent))) { return WALKABLE; } if (!CheckForPit(raystartcoords, filter, startent)) { return PIT_MIDDLE; } raystartcoords[0]=raystartcoords[0]+offset[0]; raystartcoords[1]=raystartcoords[1]+offset[1]; raystartcoords[2]=raystartcoords[2]+offset[2]; } return WALKABLE; } else { return WALKABLE; } } } if (brush) { endcoords[2]=endcoords[2]+32.0; } } return WALL; } public bool:CheckForPit (const Float:coords[3], const VisibilityFilter:filter, const startent) { decl Float:coords2[3]; coords2[0]=coords[0]; coords2[1]=coords[1]; coords2[2]=-64000.0; decl Handle:ray; new Float:mins[]={-24.0, -24.0, 0.0}; new Float:maxs[]={24.0, 24.0, 60.0}; switch (filter) { case FILTER_NODE_LINKING:{ ray=TR_TraceHullFilterEx(coords, coords2, mins, maxs, MASK_PLAYERSOLID, FilterNodeLinking); } case FILTER_BOT_NAVIGATION:{ ray=TR_TraceHullFilterEx(coords, coords2, mins, maxs, MASK_PLAYERSOLID, FilterBotNavigation, startent); } } TR_GetEndPosition(coords2, ray); CloseHandle(ray); if ((coords[2]-coords2[2])>50.0) { //InformAdmin("Found pit"); //InformAdmin("Start: %f %f %f", coords[0], coords[1], coords[2]); //InformAdmin("End: %f %f %f", coords2[0], coords2[1], coords2[2]); return false; } return true; } public bool:GetBrushPosition (const entindex, Float:coords[6]) { decl enttype; decl String:entclass[64]; GetEdictClassname(entindex, entclass, 64); if (GetTrieValue(BrushTypesTrie, entclass, enttype)) { switch (enttype) { case BRUSH_STATIC:{} case BRUSH_DYNAMIC:{} case BRUSH_PARSED:{ KvRewind(ftzmapkv); KvJumpToKey(ftzmapkv, entclass); decl String:entindexstring[8]; IntToString(entindex, entindexstring, 8); KvJumpToKey(ftzmapkv, entindexstring); decl Float:mins[3]; decl Float:maxs[3]; KvGetVector(ftzmapkv, "mins", mins); KvGetVector(ftzmapkv, "maxs", maxs); coords[0]=mins[0]; coords[1]=mins[1]; coords[2]=mins[2]; coords[3]=maxs[0]; coords[4]=maxs[1]; coords[5]=maxs[2]; return true; } } } return false; } public bool:IsPositionInBrush (const Float:coords[3], const entindex) { decl Float:brushcoords[6]; if (!GetBrushPosition(entindex, brushcoords)) { return false; } if ((coords[0]>brushcoords[0])&&(coords[0]<brushcoords[3])&&(coords[1]>brushcoords[1])&&(coords[1]<brushcoords[4])&&(coords[2]>brushcoords[2])&&(coords[2]<brushcoords[5])) { return true; } return false; }
|
|