static void SCP_CampaignActivateStageSets (stage_t *stage) { setState_t *set; int i; scd->testStage = stage; for (i = 0, set = &scd->set[stage->first]; i < stage->num; i++, set++) { if (!set->active && !set->done && !set->num) { const date_t zero = {0, 0}; int i; /* check needed sets */ if (!BEP_Evaluate(set->def->needed, SCP_StageSetDone)) continue; Com_Printf("activate stage set '%s'\n", set->def->name); /* activate it */ set->active = true; set->start = Date_Add(ccs.date, set->def->delay); set->event = Date_Add(set->start, Date_Random(zero, set->def->frame)); for (i = 0; i < set->def->ufos; i++) { const float r = frand(); interestCategory_t category = INTERESTCATEGORY_TERROR_ATTACK; if (r > 0.9f) category = INTERESTCATEGORY_BASE_ATTACK; else if (r > 0.6f) category = INTERESTCATEGORY_INTERCEPT; CP_CreateNewMission(category, true); } } } }
/** * @brief UFO arrived on new base destination: Supply base. * @param[in,out] mission Pointer to the mission * @note Supply mission -- Stage 2 */ static void CP_SupplySetStayAtBase (mission_t *mission) { const date_t minSupplyTime = {3, 0}; const date_t supplyTime = {10, 0}; /**< Max time needed to supply base */ assert(mission->ufo); /* there must be an alien base set */ assert(mission->data.alienBase); mission->stage = STAGE_SUPPLY; /* Maybe base has been destroyed since mission creation ? */ if (!AB_CheckSupplyMissionPossible()) { Com_DPrintf(DEBUG_CLIENT, "No base in game: removing supply mission.\n"); CP_MissionRemove(mission); return; } mission->finalDate = Date_Add(ccs.date, Date_Random(minSupplyTime, supplyTime)); AB_SupplyBase(mission->data.alienBase, mission->ufo->detected); /* ufo becomes invisible on geoscape */ CP_UFORemoveFromGeoscape(mission, false); }
/** * @brief Set Intercept mission: UFO looks for new aircraft target. * @note Intercept mission -- Stage 1 */ void CP_InterceptAircraftMissionSet (mission_t* mission) { const date_t minReconDelay = {3, 0}; const date_t reconDelay = {6, 0}; /* How long the UFO should stay on earth */ mission->stage = STAGE_INTERCEPT; mission->finalDate = Date_Add(ccs.date, Date_Random(minReconDelay, reconDelay)); }
static void SCP_CampaignAddMission (setState_t *set) { actMis_t *mis; mission_t * mission; const nation_t *nation; /* add mission */ if (scd->numActiveMissions >= MAX_ACTMISSIONS) { return; } mis = &scd->activeMissions[scd->numActiveMissions]; OBJZERO(*mis); /* set relevant info */ mis->def = SCP_GetMission(set); if (mis->def == NULL) { return; } mis->cause = set; if (set->def->expire.day) mis->expire = Date_Add(ccs.date, set->def->expire); /* prepare next event (if any) */ set->num++; if (set->def->number && set->num >= set->def->number) { set->active = false; } else { const date_t minTime = {0, 0}; set->event = Date_Add(ccs.date, Date_Random(minTime, set->def->frame)); } mission = CP_CreateNewMission(INTERESTCATEGORY_TERROR_ATTACK, true); mission->mapDef = cgi->Com_GetMapDefinitionByID(mis->def->id); if (!mission->mapDef) { Com_Printf("SCP_CampaignAddMission: Could not get the mapdef '%s'\n", mis->def->id); CP_MissionRemove(mission); return; } Vector2Copy(mis->def->pos, mission->pos); mission->posAssigned = true; nation = MAP_GetNation(mission->pos); if (nation) { Com_sprintf(mission->location, sizeof(mission->location), "%s", _(nation->name)); } else { Com_sprintf(mission->location, sizeof(mission->location), "%s", _("No nation")); } CP_TerrorMissionStart(mission); mission->finalDate = mis->expire; mis->mission = mission; Com_Printf("spawned map '%s'\n", mis->def->id); scd->numActiveMissions++; }
/** * @brief Set aerial mission. * @note Recon mission -- Stage 1 * @sa CP_ReconMissionSelect */ void CP_ReconMissionAerial (mission_t *mission) { const date_t minReconDelay = {1, 0}; const date_t reconDelay = {2, 0}; /* How long the UFO will fly on earth */ assert(mission->ufo); mission->stage = STAGE_RECON_AIR; mission->finalDate = Date_Add(ccs.date, Date_Random(minReconDelay, reconDelay)); }
/** * @brief Start Terror attack mission. * @note Terror attack mission -- Stage 2 */ void CP_TerrorMissionStart (mission_t *mission) { const date_t minMissionDelay = {2, 0}; const date_t missionDelay = {3, 0}; mission->stage = STAGE_TERROR_MISSION; mission->finalDate = Date_Add(ccs.date, Date_Random(minMissionDelay, missionDelay)); /* ufo becomes invisible on geoscape, but don't remove it from ufo global array (may reappear)*/ if (mission->ufo) CP_UFORemoveFromGeoscape(mission, false); /* mission appear on geoscape, player can go there */ CP_MissionAddToGeoscape(mission, false); }
/** * @brief Start ground mission. * @note Recon mission -- Stage 1 */ static void CP_ReconMissionGround (mission_t *mission) { const date_t minMissionDelay = {2, 0}; const date_t missionDelay = {3, 0}; mission->stage = STAGE_RECON_GROUND; mission->posAssigned = true; mission->finalDate = Date_Add(ccs.date, Date_Random(minMissionDelay, missionDelay)); /* ufo becomes invisible on geoscape, but don't remove it from ufo global array (may reappear)*/ if (mission->ufo) CP_UFORemoveFromGeoscape(mission, false); /* mission appear on geoscape, player can go there */ CP_MissionAddToGeoscape(mission, false); }
/** * @brief Start Subverting Mission. * @note Build Base mission -- Stage 2 */ static void CP_BuildBaseSubvertGovernment (mission_t* mission) { const date_t minMissionDelay = {3, 0}; const date_t missionDelay = {5, 0}; assert(mission->ufo); mission->stage = STAGE_SUBVERT_GOV; /* mission appear on geoscape, player can go there */ CP_MissionAddToGeoscape(mission, false); mission->finalDate = Date_Add(ccs.date, Date_Random(minMissionDelay, missionDelay)); /* ufo becomes invisible on geoscape, but don't remove it from ufo global array (may reappear)*/ CP_UFORemoveFromGeoscape(mission, false); }
/** * @brief Start Harvesting mission. * @note Harvesting mission -- Stage 2 */ static void CP_HarvestMissionStart (mission_t* mission) { const date_t minMissionDelay = {2, 0}; const date_t missionDelay = {3, 0}; mission->stage = STAGE_HARVEST; if (mission->ufo) { mission->finalDate = Date_Add(ccs.date, Date_Random(minMissionDelay, missionDelay)); /* ufo becomes invisible on geoscape, but don't remove it from ufo global array (may reappear)*/ CP_UFORemoveFromGeoscape(mission, false); } else { /* Go to next stage on next frame */ mission->finalDate = ccs.date; } /* mission appear on geoscape, player can go there */ CP_MissionAddToGeoscape(mission, false); }
/** * @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)); }
/** * @brief UFO arrived on new base destination: build base. * @param[in,out] mission Pointer to the mission * @note Build Base mission -- Stage 2 */ static void CP_BuildBaseSetUpBase (mission_t* mission) { alienBase_t* base; const date_t minBuildingTime = {5, 0}; /**< Minimum time needed to start a new base construction */ const date_t buildingTime = {10, 0}; /**< Maximum time needed to start a new base construction */ assert(mission->ufo); mission->stage = STAGE_BUILD_BASE; mission->finalDate = Date_Add(ccs.date, Date_Random(minBuildingTime, buildingTime)); base = AB_BuildBase(mission->pos); if (!base) { Com_DPrintf(DEBUG_CLIENT, "CP_BuildBaseSetUpBase: could not create alien base\n"); CP_MissionRemove(mission); return; } mission->data.alienBase = base; /* ufo becomes invisible on geoscape */ CP_UFORemoveFromGeoscape(mission, false); }