1 /**
2  * @file
3  * @brief Campaign mission
4  */
5 
6 /*
7 Copyright (C) 2002-2013 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23 
24 */
25 
26 #include "../../../cl_shared.h"
27 #include "../../../ui/ui_dataids.h"
28 #include "../cp_campaign.h"
29 #include "../cp_geoscape.h"
30 #include "../cp_ufo.h"
31 #include "../cp_missions.h"
32 #include "../cp_time.h"
33 #include "../cp_xvi.h"
34 #include "../cp_alien_interest.h"
35 
CP_GetCarrierMission(void)36 static mission_t* CP_GetCarrierMission (void)
37 {
38 	MIS_Foreach(mission) {
39 		if (mission->category == INTERESTCATEGORY_UFOCARRIER)
40 			return mission;
41 	}
42 
43 	return nullptr;
44 }
45 
46 /**
47  * @brief Start UFO-Carrier mission.
48  */
CP_UFOCarrierMissionStart(mission_t * mission)49 static void CP_UFOCarrierMissionStart (mission_t* mission)
50 {
51 	mission->idx = ++ccs.campaignStats.missions;
52 	mission->finalDate = ccs.date;
53 	mission->stage = STAGE_RECON_AIR;
54 }
55 
CP_UFOCarrierMissionUpdate(mission_t * mission)56 static void CP_UFOCarrierMissionUpdate (mission_t* mission)
57 {
58 	/* delay the next update for some time */
59 	const date_t delay = {2, 0};
60 	mission->finalDate = Date_Add(ccs.date, delay);
61 
62 	if (INS_HasType(INSTALLATION_ORBIT)) {
63 		cgi->UI_PopupButton(_("UFO-Carrier"), _("The Carrier UFO is in range. Should we launch the payload?"),
64 			"ui_pop;", _("Wait"), _("Don't attack the UFO-Carrier yet"),
65 			"cp_attack_ufocarrier;ui_pop;", _("Launch"), _("Attack the UFO-Carrier now"),
66 			nullptr, nullptr, nullptr);
67 	}
68 }
69 
70 /**
71  * @brief Determine what action should be performed when a UFOCarriering mission stage ends.
72  * @param[in] mission Pointer to the mission which stage ended.
73  */
CP_UFOCarrierNextStage(mission_t * mission)74 void CP_UFOCarrierNextStage (mission_t* mission)
75 {
76 	switch (mission->stage) {
77 	case STAGE_NOT_ACTIVE:
78 		CP_UFOCarrierMissionStart(mission);
79 		break;
80 	default:
81 		CP_UFOCarrierMissionUpdate(mission);
82 		break;
83 	}
84 }
85 
86 /**
87  * @brief Spawns a UFO-Carrier mission
88  */
CP_SpawnUFOCarrier_f(void)89 void CP_SpawnUFOCarrier_f (void)
90 {
91 	/* only one carrier missions is allowed */
92 	if (CP_GetCarrierMission() != nullptr)
93 		return;
94 
95 	const installationTemplate_t* installationTemplate = INS_GetInstallationTemplateByType(INSTALLATION_ORBIT);
96 	if (!installationTemplate)
97 		return;
98 
99 	if (cgi->Cmd_Argc() == 3) {
100 		const vec2_t pos = Vector2FromInt(atof(cgi->Cmd_Argv(1)), atof(cgi->Cmd_Argv(2)));
101 		if (!MapIsWater(GEO_GetColor(pos, MAPTYPE_TERRAIN, nullptr))) {
102 			INS_Build(installationTemplate, pos, _(installationTemplate->name));
103 			GEO_CenterPosition(pos);
104 			CL_EventAddMail("ufocarrier");
105 		}
106 	}
107 
108 	CP_CreateNewMission(INTERESTCATEGORY_UFOCARRIER, true);
109 }
110 
111 /**
112  * @brief Decide whether you hit and destroyed the carrier and spawns a new
113  * carrier crash site mission
114  */
CP_AttackUFOCarrier_f(void)115 void CP_AttackUFOCarrier_f (void)
116 {
117 	mission_t* mission = CP_GetCarrierMission();
118 	if (mission == nullptr)
119 		return;
120 
121 	if (!INS_HasType(INSTALLATION_ORBIT))
122 		return;
123 
124 #if 1
125 	/** @todo until we have the carrier mission fully implemented, this is the campaign end */
126 	cgi->UI_RegisterText(TEXT_STANDARD, "*msgid:campaignwin");
127 	CP_EndCampaign(true);
128 #else
129 	/* check max amount - we can't win if we can't add the ufo */
130 	if (ccs.numUFOs >= MAX_UFOONGEOSCAPE)
131 		return;
132 
133 	const aircraft_t* ufoTemplate = UFO_GetTemplate(UFO_CARRIER);
134 	aircraft_t* ufo = UFO_CreateFromTemplate(ufoTemplate);
135 	if (ufo == nullptr) {
136 		cgi->Com_Error(ERR_DROP, "Could not add UFO-Carrier to geoscape");
137 		return;
138 	}
139 	ufo->mission = mission;
140 	mission->ufo = ufo;
141 	CP_GetRandomPosOnGeoscape(ufo->pos, true);
142 	CP_SpawnCrashSiteMission(ufo);
143 	if (mission->mapDef != nullptr) {
144 		Com_Printf("spawned mapdef: %s\n", mission->mapDef->id);
145 	}
146 #endif
147 }
148