/** * @brief Intercept mission ends: UFO leave earth. * @param[in] mission Pointer to the mission * @param[in] destroyed true if the UFO actually destroyed the installation, false else * @note Intercept mission -- Stage 3 */ void CP_InterceptMissionLeave (mission_t* mission, bool destroyed) { installation_t* installation; assert(mission->ufo); mission->stage = STAGE_RETURN_TO_ORBIT; /* if the mission was an attack of an installation, destroy it */ installation = mission->data.installation; if (installation) { vec3_t missionPos; Vector2Copy(mission->pos, missionPos); missionPos[2] = installation->pos[2]; if (destroyed && VectorCompareEps(missionPos, installation->pos, UFO_EPSILON)) INS_DestroyInstallation(installation); } CP_MissionDisableTimeLimit(mission); UFO_SetRandomDest(mission->ufo); CP_MissionRemoveFromGeoscape(mission); /* Display UFO on geoscape if it is detected */ mission->ufo->landed = false; }
/** * @brief Interpolates the camera movement from the given start point to the given end point * @sa CL_CameraMove * @sa CL_ViewCenterAtGridPosition * @param[in] from The grid position to start the camera movement from * @param[in] target The grid position to move the camera to */ void CL_CameraRoute (const pos3_t from, const pos3_t target) { if (!cl_centerview->integer) return; vec3_t targetCamera; PosToVec(target, targetCamera); const bool closeEnough = VectorCompareEps(targetCamera, cl.cam.origin, UNIT_SIZE); if (closeEnough) return; /* initialize the camera route variables */ PosToVec(from, routeFrom); PosToVec(target, routeDelta); VectorSubtract(routeDelta, routeFrom, routeDelta); routeDelta[2] = 0; routeDist = VectorLength(routeDelta); VectorNormalize(routeDelta); /* center the camera on the route starting position */ VectorCopy(routeFrom, cl.cam.origin); /* set the world level to the z axis value of the camera target * the camera lerp will do a smooth translate from the old level * to the new one */ Cvar_SetValue("cl_worldlevel", target[2]); VectorClear(cl.cam.speed); cameraRoute = true; CL_BlockBattlescapeEvents(true); }
/** * @brief Particle tracing with caching */ static trace_t PTL_Trace (ptl_t* ptl, const AABB& aabb) { static ptlTraceCache_t ptlCache; const float epsilonPos = 3.0f; const float epsilonBBox = 1.0f; if (VectorCompareEps(ptlCache.start, ptl->origin, epsilonPos) && VectorCompareEps(ptlCache.end, ptl->s, epsilonPos) && VectorCompareEps(ptlCache.pBox.mins, aabb.mins, epsilonBBox) && VectorCompareEps(ptlCache.pBox.maxs, aabb.maxs, epsilonBBox)) { ptlCache.count++; return ptlCache.trace; } VectorCopy(ptl->origin, ptlCache.start); VectorCopy(ptl->s, ptlCache.end); ptlCache.pBox.set(aabb); ptlCache.trace = CL_Trace(Line(ptl->origin, ptl->s), aabb, nullptr, nullptr, MASK_SOLID, cl.mapMaxLevel - 1); return ptlCache.trace; }
/** * @brief Particle tracing with caching */ static inline trace_t PTL_Trace (ptl_t *ptl, const vec3_t mins, const vec3_t maxs) { static ptlTraceCache_t ptlCache; const float epsilonPos = 3.0f; const float epsilonBBox = 1.0f; if (VectorCompareEps(ptlCache.start, ptl->origin, epsilonPos) && VectorCompareEps(ptlCache.end, ptl->s, epsilonPos) && VectorCompareEps(ptlCache.mins, mins, epsilonBBox) && VectorCompareEps(ptlCache.maxs, maxs, epsilonBBox)) { ptlCache.count++; return ptlCache.trace; } VectorCopy(ptl->origin, ptlCache.start); VectorCopy(ptl->s, ptlCache.end); VectorCopy(mins, ptlCache.mins); VectorCopy(maxs, ptlCache.maxs); ptlCache.trace = CL_Trace(ptl->origin, ptl->s, AABB(mins, maxs), nullptr, nullptr, MASK_SOLID, cl.mapMaxLevel - 1); return ptlCache.trace; }
/** * @brief UFO starts to attack the installation. * @note Intercept mission -- Stage 2 */ static void CP_InterceptAttackInstallation (mission_t* mission) { const date_t minAttackDelay = {0, 3600}; const date_t attackDelay = {0, 21600}; /* How long the UFO should stay on earth */ installation_t* installation; vec3_t missionPos; mission->stage = STAGE_INTERCEPT; installation = mission->data.installation; Vector2Copy(mission->pos, missionPos); if (!VectorCompareEps(missionPos, installation->pos, UFO_EPSILON)) { mission->finalDate = ccs.date; return; } /* Make round around the position of the mission */ UFO_SetRandomDestAround(mission->ufo, mission->pos); mission->finalDate = Date_Add(ccs.date, Date_Random(minAttackDelay, attackDelay)); }