/** * @brief Send the appear or perish event to the affected clients * @param[in] playerMask These are the affected players or clients * In case of e.g. teamplay there can be more than one client affected - thus * this is a player mask * @param[in] appear Is this event about an appearing actor (or a perishing one) * @param[in] check The edict we are talking about (that appears or perishes) * @param[in] ent The edict that was responsible for letting the check edict appear * or perish. Might be @c NULL. * @sa CL_ActorAppear */ void G_AppearPerishEvent (playermask_t playerMask, bool appear, edict_t *check, const edict_t *ent) { teammask_t teamMaskDiff; /* test for pointless player mask */ if (!playerMask) return; teamMaskDiff = G_PMToVis(playerMask); G_VisFlagsSwap(check, teamMaskDiff); if (appear) { /* appear */ switch (check->type) { case ET_ACTOR: case ET_ACTOR2x2: G_EventActorAppear(playerMask, check, ent); break; case ET_CAMERA: G_EventCameraAppear(playerMask, check); break; case ET_ITEM: G_EventEdictAppear(playerMask, check); G_SendInventory(playerMask, check); break; case ET_PARTICLE: G_EventEdictAppear(playerMask, check); G_EventSendParticle(playerMask, check); break; case ET_TRIGGER_RESCUE: G_EventAddBrushModel(playerMask, check); break; default: if (G_IsVisibleOnBattlefield(check)) gi.Error("Missing edict type %i in G_AppearPerishEvent", check->type); break; } } else if (G_IsVisibleOnBattlefield(check)) { G_EventEdictPerish(playerMask, check); } }
/** * @brief test if check is visible by from * @param[in] team Living team members are always visible. If this is a negative * number we inverse the team rules (see comments included). In combination with VT_NOFRUSTUM * we can check whether there is any edict (that is no in our team) that can see @c check * @param[in] from is from team @c team and must be a living actor * @param[in] check The edict we want to get the visibility for * @param[in] flags @c VT_NOFRUSTUM, ... */ bool G_Vis (const int team, const Edict* from, const Edict* check, const vischeckflags_t flags) { vec3_t eye; /* if any of them isn't in use, then they're not visible */ if (!from->inuse || !check->inuse) return false; /* only actors and 2x2 units can see anything */ if (!G_IsLivingActor(from) && !G_IsActiveCamera(from)) return false; /* living team members are always visible */ if (team >= 0 && check->getTeam() == team && !G_IsDead(check)) return true; /* standard team rules */ if (team >= 0 && from->getTeam() != team) return false; /* inverse team rules */ if (team < 0 && check->getTeam() == -team) return false; /* check for same pos */ if (VectorCompare(from->pos, check->pos)) return true; if (!G_IsVisibleOnBattlefield(check)) return false; /* view distance check */ const int spotDist = G_VisCheckDist(from); if (VectorDistSqr(from->origin, check->origin) > spotDist * spotDist) return false; /* view frustum check */ if (!(flags & VT_NOFRUSTUM) && !G_FrustumVis(from, check->origin)) return false; /* get viewers eye height */ G_ActorGetEyeVector(from, eye); /* line trace check */ switch (check->type) { case ET_ACTOR: case ET_ACTOR2x2: return G_ActorVis(eye, from, check, false) > ACTOR_VIS_0; case ET_ITEM: case ET_CAMERA: case ET_PARTICLE: return !G_LineVis(eye, check->origin); default: return false; } }