00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <config.h>
00036
00037 #include "commands.h"
00038 #include "empobj.h"
00039 #include "mission.h"
00040 #include "optlist.h"
00041 #include "path.h"
00042
00043
00044
00045
00046 int
00047 mission(void)
00048 {
00049 static int ef_with_missions[] = { EF_SHIP, EF_LAND, EF_PLANE, EF_BAD };
00050 char *p;
00051 int type;
00052 int mission;
00053 coord x, y;
00054 int desired_radius, radius;
00055 struct sctstr opsect;
00056 union empobj_storage item;
00057 struct empobj *gp;
00058 int num = 0, mobmax, mobused, dist;
00059 struct nstr_item ni;
00060 char prompt[128];
00061 char buf[1024];
00062
00063 if ((p =
00064 getstarg(player->argp[1], "Ship, plane or land unit (p,sh,la)? ",
00065 buf)) == 0)
00066 return RET_SYN;
00067 type = ef_byname_from(p, ef_with_missions);
00068 if (type < 0) {
00069 pr("Ships, land units or planes only! (s, l, p)\n");
00070 return RET_SYN;
00071 }
00072 sprintf(prompt, "%s(s)? ", ef_nameof(type));
00073 p = getstarg(player->argp[2], prompt, buf);
00074 if (!snxtitem(&ni, type, p))
00075 return RET_SYN;
00076
00077 if ((p =
00078 getstarg(player->argp[3],
00079 "Mission (int, sup, osup, dsup, esc, res, air, query, clear)? ",
00080 buf)) == 0)
00081 return RET_SYN;
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 switch (*p) {
00093 case 'I':
00094 case 'i':
00095 mission = MI_INTERDICT;
00096 break;
00097 case 'O':
00098 case 'o':
00099 mission = MI_OSUPPORT;
00100 break;
00101 case 'D':
00102 case 'd':
00103 mission = MI_DSUPPORT;
00104 break;
00105 case 'S':
00106 case 's':
00107 mission = MI_SUPPORT;
00108 break;
00109 case 'C':
00110 case 'c':
00111 mission = 0;
00112 break;
00113 case 'E':
00114 case 'e':
00115 mission = MI_ESCORT;
00116 break;
00117 case 'R':
00118 case 'r':
00119 mission = MI_RESERVE;
00120 break;
00121 case 'A':
00122 case 'a':
00123 mission = MI_AIR_DEFENSE;
00124 break;
00125 case 'q':
00126 show_mission(type, &ni);
00127 return RET_OK;
00128 default:
00129 pr("bad condition\n");
00130 pr("i\tinterdiction (any)\n");
00131 pr("s\tsupport (tactical planes only)\n");
00132 pr("o\toffensive support (tactical planes only)\n");
00133 pr("d\tdefensive support (tactical planes only)\n");
00134 pr("r\treserve (land units only)\n");
00135 pr("e\tescort (tactical or escort planes only)\n");
00136 pr("a\tair defense (intercept planes only)\n");
00137 pr("c\tclear mission\n");
00138 pr("q\tquery\n");
00139 return RET_SYN;
00140 }
00141
00142 if (mission && !cando(mission, type)) {
00143 pr("A %s cannot do that mission!\n", ef_nameof(type));
00144 pr("i\tinterdiction (any)\n");
00145 pr("s\tsupport (planes only)\n");
00146 pr("o\toffensive support (planes only)\n");
00147 pr("d\tdefensive support (planes only)\n");
00148 pr("r\treserve (land units only)\n");
00149 pr("e\tescort (planes only)\n");
00150 pr("a\tair defense (planes only)\n");
00151 return RET_FAIL;
00152 }
00153
00154 if (mission && ((mission != MI_RESERVE) && (mission != MI_ESCORT))) {
00155 if ((p = getstarg(player->argp[4], "operations point? ", buf)) == 0
00156 || *p == 0)
00157 return RET_SYN;
00158
00159 if (*p != '.') {
00160 if (!sarg_xy(p, &x, &y))
00161 return RET_SYN;
00162
00163 if (!getsect(x, y, &opsect))
00164 return RET_FAIL;
00165 }
00166 } else {
00167 x = 0;
00168 y = 0;
00169 }
00170
00171 if (player->argp[5] != NULL) {
00172 desired_radius = atoi(player->argp[5]);
00173 if (desired_radius < 0) {
00174 pr("Radius must be greater than zero!\n");
00175 return RET_FAIL;
00176 }
00177 } else {
00178 desired_radius = 9999;
00179 }
00180
00181 if ((mobmax = get_empobj_mob_max(type)) == -1)
00182 return RET_FAIL;
00183
00184 mobused = ldround(mission_mob_cost * (double)mobmax, 1);
00185
00186 while (nxtitem(&ni, &item)) {
00187 gp = (struct empobj *)&item;
00188
00189 if (!player->owner || gp->own == 0)
00190 continue;
00191
00192 if ((mission && (gp->mobil < mobused)) && mission_mob_cost) {
00193 pr("%s: not enough mobility! (needs %d)\n",
00194 obj_nameof(gp), mobused);
00195 continue;
00196 }
00197 if (mission == MI_RESERVE && !lnd_can_attack((struct lndstr *)gp)) {
00198 pr("%s is not designed to fight ground troops\n",
00199 obj_nameof(gp));
00200 continue;
00201 }
00202 if (*p == '.') {
00203 x = gp->x;
00204 y = gp->y;
00205 if (!getsect(x, y, &opsect))
00206 return RET_FAIL;
00207 }
00208
00209 dist = mapdist(gp->x, gp->y, x, y);
00210 radius = 999;
00211 if ((mission == MI_INTERDICT || mission == MI_SUPPORT ||
00212 mission == MI_OSUPPORT || mission == MI_DSUPPORT ||
00213 mission == MI_AIR_DEFENSE) &&
00214 (oprange(gp, &radius) < dist)) {
00215 pr("%s: out of range! (range %d)\n",
00216 obj_nameof(gp), oprange(gp, &radius));
00217 continue;
00218 }
00219
00220 if (radius > desired_radius)
00221 radius = desired_radius;
00222
00223 if ((mission == MI_INTERDICT) && (type == EF_SHIP))
00224 if (mchr[(int)gp->type].m_frnge < 1) {
00225 pr("%s: cannot fire at range!\n", obj_nameof(gp));
00226 continue;
00227 }
00228
00229 if ((mission == MI_INTERDICT) && (type == EF_LAND))
00230 if (lchr[(int)gp->type].l_frg < 1) {
00231 pr("%s: cannot fire at range!\n", obj_nameof(gp));
00232 continue;
00233 }
00234
00235 if ((mission == MI_INTERDICT) && (type == EF_PLANE)) {
00236 struct plchrstr *pcp;
00237
00238 pcp = &plchr[(int)gp->type];
00239 if (!(pcp->pl_flags & P_T)) {
00240 pr("Only planes with the tactical ability can interdict.\n"
00241 "%s #%d is ineligible\n",
00242 pcp->pl_name, gp->uid);
00243 continue;
00244 }
00245 }
00246
00247 if ((mission == MI_AIR_DEFENSE) && (type == EF_PLANE)) {
00248 struct plchrstr *pcp;
00249
00250 pcp = &plchr[(int)gp->type];
00251 if (!(pcp->pl_flags & P_F)) {
00252 pr("Only planes with the intercept abilities can perform air defense.\n"
00253 "%s #%d is ineligible\n",
00254 pcp->pl_name, gp->uid);
00255 continue;
00256 }
00257 }
00258
00259 if ((mission == MI_ESCORT) && (type == EF_PLANE)) {
00260 struct plchrstr *pcp;
00261
00262 pcp = &plchr[(int)gp->type];
00263 if (!(pcp->pl_flags & P_ESC) && !(pcp->pl_flags & P_F)) {
00264 pr("Only planes with the escort or intercept abilities can escort.\n"
00265 "%s #%d is ineligible\n",
00266 pcp->pl_name, gp->uid);
00267 continue;
00268 }
00269 }
00270
00271 if ((mission == MI_SUPPORT || mission == MI_OSUPPORT ||
00272 mission == MI_DSUPPORT) && (type == EF_PLANE)) {
00273 struct plchrstr *pcp;
00274
00275 pcp = &plchr[(int)gp->type];
00276 if (!(pcp->pl_flags & P_T)) {
00277 pr("Only planes with the tactical ability can support.\n"
00278 "%s #%d is ineligible\n",
00279 pcp->pl_name, gp->uid);
00280 continue;
00281 }
00282 }
00283
00284 num++;
00285
00286 if (mission == MI_INTERDICT || mission == MI_SUPPORT ||
00287 mission == MI_OSUPPORT || mission == MI_DSUPPORT ||
00288 mission == MI_AIR_DEFENSE)
00289 gp->radius = radius;
00290 else
00291 gp->radius = 0;
00292
00293 if (mission == MI_SUPPORT || mission == MI_OSUPPORT ||
00294 mission == MI_DSUPPORT || mission == MI_INTERDICT ||
00295 mission == MI_AIR_DEFENSE) {
00296 pr("%s on %s mission, centered on %s, radius %d\n",
00297 obj_nameof(gp), mission_name(mission),
00298 xyas(x, y, player->cnum), gp->radius);
00299 } else if (mission == MI_RESERVE) {
00300 int plus = 2;
00301
00302 if (((struct lndstr *)gp)->lnd_rad_max == 0) {
00303 plus = 0;
00304 } else {
00305 getsect(gp->x, gp->y, &opsect);
00306 if ((opsect.sct_type == SCT_HEADQ)
00307 && (opsect.sct_effic >= 60))
00308 plus++;
00309 plus += ((struct lndstr *)gp)->lnd_rad_max;
00310 }
00311
00312 pr("%s on %s mission with maximum reaction radius %d\n",
00313 obj_nameof(gp), mission_name(mission), plus);
00314 } else if (mission) {
00315 pr("%s on %s mission\n", obj_nameof(gp),
00316 mission_name(mission));
00317 }
00318
00319 if (mission)
00320 gp->mobil -= mobused;
00321 gp->mission = mission;
00322 gp->opx = x;
00323 gp->opy = y;
00324 put_empobj(gp);
00325 }
00326 if (num == 0) {
00327 pr("No %s%s\n", ef_nameof(type), splur(num));
00328 return RET_FAIL;
00329 }
00330 pr("%d %s%s\n", num, ef_nameof(type), splur(num));
00331 return RET_OK;
00332 }