$$QUERY Objects b:Player (store in [e:SavedObjectSlot]) is within the [i:Cone=90] degree view cone of [o:Object] at a max distance of [f:Distance] using flags [g:FVIHitFlags=1048585:16269119] qObjCanSeePlayerAdvancedWithStore Can object see a player Determines if the specified object can see a player (but allowing some customizability as to what the object can see through), and if the player can
| 6307 | $$END |
| 6308 | */ |
| 6309 | bool qObjCanSeePlayerAdvancedWithStore(int slot, int cone, int handlesrc, float max_distance, int fvi_flags) { |
| 6310 | vector vsource, vtarget, viewvec; |
| 6311 | msafe_struct mstruct; |
| 6312 | matrix orient; |
| 6313 | int sourceroom; |
| 6314 | |
| 6315 | // Get half of the angle that the user specified because they specified a cone, and we want an angle |
| 6316 | double cangle = (double)((double)cone / (double)2); |
| 6317 | double t = cangle * PI / 180; |
| 6318 | double testangle = cos(t); |
| 6319 | |
| 6320 | // Get the viewer position |
| 6321 | mstruct.objhandle = handlesrc; |
| 6322 | MSafe_GetValue(MSAFE_OBJECT_POS, &mstruct); |
| 6323 | vsource = mstruct.pos; |
| 6324 | |
| 6325 | // Get the viewer orientation |
| 6326 | MSafe_GetValue(MSAFE_OBJECT_ORIENT, &mstruct); |
| 6327 | orient = mstruct.orient; |
| 6328 | |
| 6329 | // Get the viewer room |
| 6330 | MSafe_GetValue(MSAFE_OBJECT_ROOMNUM, &mstruct); |
| 6331 | sourceroom = mstruct.roomnum; |
| 6332 | |
| 6333 | // Loop though all possible players |
| 6334 | for (int p = 0; p < MAX_PLAYERS; p++) { |
| 6335 | |
| 6336 | // Get player position |
| 6337 | mstruct.slot = p; |
| 6338 | MSafe_GetValue(MSAFE_OBJECT_PLAYER_HANDLE, &mstruct); |
| 6339 | |
| 6340 | // See if this player active |
| 6341 | if (mstruct.objhandle == OBJECT_HANDLE_NONE) |
| 6342 | continue; |
| 6343 | |
| 6344 | // Get the target position |
| 6345 | MSafe_GetValue(MSAFE_OBJECT_POS, &mstruct); |
| 6346 | vtarget = mstruct.pos; |
| 6347 | |
| 6348 | // Get the normalized vector from the source to the target |
| 6349 | float dist = vm_GetNormalizedDirFast(&viewvec, &vtarget, &vsource); |
| 6350 | |
| 6351 | // Get the angle between the objects |
| 6352 | float dot = vm_DotProduct(&viewvec, &orient.fvec); |
| 6353 | |
| 6354 | // Check angle and distance |
| 6355 | if ((dot > testangle) && (dist < max_distance)) { |
| 6356 | // see if we can cast a ray to the player |
| 6357 | ray_info ray; |
| 6358 | fvi_flags |= (FQ_CHECK_OBJS | FQ_ONLY_PLAYER_OBJ); |
| 6359 | int fate = FVI_RayCast(handlesrc, &vsource, &vtarget, sourceroom, 0.0f, fvi_flags, &ray); |
| 6360 | |
| 6361 | if (fate == HIT_NONE) { |
| 6362 | if ((slot >= 0) && (slot < MAX_SAVED_OBJECT_HANDLES)) |
| 6363 | Saved_object_handles[slot] = mstruct.objhandle; |
| 6364 | return true; |
| 6365 | } |
| 6366 |
no test coverage detected