/** * @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 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 Base Attack. * @param[in] mission Pointer to the baseattack mission */ void CP_BaseAttackStartMission (mission_t* mission) { base_t* base = mission->data.base; int soldiers; assert(base); mission->stage = STAGE_BASE_ATTACK; CP_MissionDisableTimeLimit(mission); if (mission->ufo) { /* ufo becomes invisible on geoscape, but don't remove it from ufo global array (may reappear)*/ CP_UFORemoveFromGeoscape(mission, false); } /* we always need at least one command centre in the base - because the * phalanx soldiers have their starting positions here. * There should also always be an entrance - the aliens start there * but we don't need to check that as entrance can't be destroyed */ if (!B_GetNumberOfBuildingsInBaseByBuildingType(base, B_COMMAND)) { /** @todo handle command centre properly */ cgi->Com_DPrintf(DEBUG_CLIENT, "CP_BaseAttackStartMission: Base '%s' has no Command Center: it can't defend itself. Destroy base.\n", base->name); CP_BaseAttackMissionDestroyBase(mission); return; } MSO_CheckAddNewMessage(NT_BASE_ATTACK, _("Base attack"), va(_("Base '%s' is under attack!"), base->name), MSG_BASEATTACK); base->baseStatus = BASE_UNDER_ATTACK; ccs.campaignStats.basesAttacked++; soldiers = 0; E_Foreach(EMPL_SOLDIER, employee) { if (!employee->isHiredInBase(base)) continue; if (employee->isAwayFromBase()) continue; soldiers++; } if (soldiers == 0) { cgi->Com_DPrintf(DEBUG_CLIENT, "CP_BaseAttackStartMission: Base '%s' has no soldiers at home: it can't defend itself. Destroy base.\n", base->name); CP_BaseAttackMissionDestroyBase(mission); return; } CP_BaseAttackPrepareBattle(mission); }
/** * @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 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); }
/** * @brief Start Base Attack. * @note Base attack mission -- Stage 2 */ void CP_BaseAttackStartMission (mission_t *mission) { base_t *base = mission->data.base; linkedList_t *hiredSoldiersInBase = NULL; employee_t *employee; assert(base); mission->stage = STAGE_BASE_ATTACK; CP_MissionDisableTimeLimit(mission); if (mission->ufo) { /* ufo becomes invisible on geoscape, but don't remove it from ufo global array (may reappear)*/ CP_UFORemoveFromGeoscape(mission, qfalse); } /* we always need at least one command centre in the base - because the * phalanx soldiers have their starting positions here. * There should also always be an entrance - the aliens start there * but we don't need to check that as entrance can't be destroyed */ if (!B_GetNumberOfBuildingsInBaseByBuildingType(base, B_COMMAND)) { /** @todo handle command centre properly */ Com_DPrintf(DEBUG_CLIENT, "CP_BaseAttackStartMission: Base '%s' has no Command Center: it can't defend itself. Destroy base.\n", base->name); CP_BaseAttackMissionDestroyBase(mission); return; } base->baseStatus = BASE_UNDER_ATTACK; ccs.campaignStats.basesAttacked++; #if 0 /** @todo implement onattack: add it to basemanagement.ufo and implement functions */ if (base->onAttack[0] != '\0') /* execute next frame */ Cbuf_AddText(va("%s %i", base->onAttack, base->id)); #endif MAP_SelectMission(mission); mission->active = qtrue; ccs.mapAction = MA_BASEATTACK; Com_DPrintf(DEBUG_CLIENT, "Base attack: %s at %.0f:%.0f\n", mission->id, mission->pos[0], mission->pos[1]); /** @todo EMPL_ROBOT */ E_GetHiredEmployees(base, EMPL_SOLDIER, &hiredSoldiersInBase); /* Fill the fake aircraft */ OBJZERO(baseAttackFakeAircraft); baseAttackFakeAircraft.homebase = base; /* needed for transfer of alien corpses */ VectorCopy(base->pos, baseAttackFakeAircraft.pos); #if 0 /** @todo active this once more than 8 soldiers are working */ /* needed to spawn soldiers on map */ baseAttackFakeAircraft.maxTeamSize = LIST_Count(hiredSoldiersInBase); #else baseAttackFakeAircraft.maxTeamSize = MAX_ACTIVETEAM; #endif if (!hiredSoldiersInBase) { Com_DPrintf(DEBUG_CLIENT, "CP_BaseAttackStartMission: Base '%s' has no soldiers: it can't defend itself. Destroy base.\n", base->name); CP_BaseAttackMissionDestroyBase(mission); return; } LIST_Foreach(hiredSoldiersInBase, employee_t, employee) { if (E_IsAwayFromBase(employee)) continue; AIR_AddToAircraftTeam(&baseAttackFakeAircraft, employee); } if (AIR_GetTeamSize(&baseAttackFakeAircraft) == 0) { Com_DPrintf(DEBUG_CLIENT, "CP_BaseAttackStartMission: Base '%s' has no soldiers at home: it can't defend itself. Destroy base.\n", base->name); CP_BaseAttackMissionDestroyBase(mission); return; } #if 0 /** @todo active this once more than 8 soldiers are working */ /* all soldiers in the base should get used */ baseAttackFakeAircraft.maxTeamSize = AIR_GetTeamSize(&baseAttackFakeAircraft); #endif LIST_Delete(&hiredSoldiersInBase); base->aircraftCurrent = &baseAttackFakeAircraft; MAP_SetMissionAircraft(&baseAttackFakeAircraft); /** @todo remove me - this is not needed because we are using the base->aircraftCurrent * pointer for resolving the aircraft - only CL_GameAutoGo needs this */ MAP_SetInterceptorAircraft(&baseAttackFakeAircraft); /* needed for updating soldier stats sa CL_UpdateCharacterStats*/ B_SetCurrentSelectedBase(base); /* needed for equipment menu */ Com_sprintf(popupText, sizeof(popupText), _("Base '%s' is under attack! What to do ?"), base->name); UI_RegisterText(TEXT_POPUP, popupText); CL_GameTimeStop(); UI_PushWindow("popup_baseattack", NULL, NULL); }