Ejemplo n.º 1
0
int
msl_launch(struct plnstr *pp, int type, char *what, coord x, coord y,
	   natid victim, int *sublaunchp)
{
    struct shpstr ship;
    struct nukstr nuke;
    int sublaunch = 0;
    char *base, *in_or_at, *from;

    mpr(pp->pln_own, "Preparing to launch %s at %s %s %s%s\n",
	prplane(pp),
	cname(victim),
	what,
	type != EF_SECTOR ? "in " : "",
	xyas(x, y, pp->pln_own));
    if (pp->pln_ship >= 0) {
	getship(pp->pln_ship, &ship);
	base = prship(&ship);
	in_or_at = " in ";
	if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
	    sublaunch = 1;
	    from = "in hatch";
	} else
	    from = "on deck";
    } else {
	if (pp->pln_harden > 0) {
	    base = "missile silo";
	    in_or_at = " at ";
	    from = "in silo";
	} else {
	    base = in_or_at = "";
	    from = "on launch pad";
	}
    }
    mpr(pp->pln_own, "\tLaunching from %s%s%s\n",
	base, in_or_at, xyas(pp->pln_x, pp->pln_y, pp->pln_own));

    CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED);
    pp->pln_flags |= PLN_LAUNCHED;
    putplane(pp->pln_uid, pp);

    if (chance((0.05 + (100 - pp->pln_effic) / 100.0)
	       * (1 - techfact(pp->pln_tech, 1.0)))) {
	mpr(pp->pln_own, "KABOOOOM!  Missile explodes %s!\n", from);
	if (getnuke(nuk_on_plane(pp), &nuke)) {
	    mpr(pp->pln_own, "%s lost!\n", prnuke(&nuke));
	    nuke.nuk_effic = 0;
	    putnuke(nuke.nuk_uid, &nuke);
	}
#if 0
	/*
	 * Disabled for now, because it breaks callers that call
	 * msl_launch() for each member of a list of planes, created
	 * by msl_sel() or perform_mission().  Damage to the base can
	 * damage other planes.  Any copies of them in the list become
	 * stale.  When msl_launch() modifies and writes back such a
	 * stale copy, the damage gets wiped out, triggering a seqno
	 * oops.
	 */
	if (chance(0.33)) {
	    struct sctstr sect;
	    int dam;

	    dam = pln_damage(pp, 'p', NULL) / 2;
	    if (pp->pln_ship >= 0) {
		shipdamage(&ship, dam);
		putship(ship.shp_uid, &ship);
	    } else {
		mpr(pp->pln_own, "Explosion damages %s %d%%\n",
		    xyas(pp->pln_x, pp->pln_y, pp->pln_own), dam);
		getsect(pp->pln_x, pp->pln_y, &sect);
		sectdamage(&sect, dam);
		putsect(&sect);
	    }
	}
#endif
	return -1;
    }

    mpr(pp->pln_own, "\tSHWOOOOOSH!  Missile launched!\n");

    if (type != EF_PLANE)
	mpr(victim, "Incoming %s missile sighted at %s...\n",
	    sublaunch ? "sub-launched" : cname(pp->pln_own),
	    xyas(x, y, victim));

    if (type == EF_SECTOR || type == EF_LAND) {
	if (msl_abm_intercept(pp, x, y, sublaunch))
	    return -1;
    }
    if (type == EF_SHIP) {
	if (shp_missile_defense(x, y, pp->pln_own, pln_def(pp))) {
	    return -1;
	}
    }

    if (sublaunchp)
	*sublaunchp = sublaunch;
    return 0;
}
Ejemplo n.º 2
0
int
pdump(void)
{
    int nplanes;
    struct nstr_item np;
    struct plnstr plane;
    struct nukstr nuke;
    int field[128];
    struct natstr *natp;
    int n, i;
    time_t now;

    if (!snxtitem(&np, EF_PLANE, player->argp[1], NULL))
	return RET_SYN;
    prdate();

    if (!player->argp[2]) {
	for (n = 1; n <= 32; n++)
	    field[n - 1] = n;
	field[n - 1] = 0;
    } else {
	n = 2;
	i = 0;
	while (player->argp[n]) {

	    if (!strcmp("type", player->argp[n])) {
		field[i++] = 1;
	    } else if (!strcmp("x", player->argp[n])) {
		field[i++] = 2;
	    } else if (!strcmp("y", player->argp[n])) {
		field[i++] = 3;
	    } else if (!strcmp("wing", player->argp[n])) {
		field[i++] = 4;
	    } else if (!strcmp("eff", player->argp[n])) {
		field[i++] = 5;
	    } else if (!strcmp("mob", player->argp[n])) {
		field[i++] = 6;
	    } else if (!strcmp("tech", player->argp[n])) {
		field[i++] = 7;
	    } else if (!strcmp("att", player->argp[n])) {
		field[i++] = 8;
	    } else if (!strcmp("def", player->argp[n])) {
		field[i++] = 9;
	    } else if (!strcmp("acc", player->argp[n])) {
		field[i++] = 10;
	    } else if (!strcmp("react", player->argp[n])) {
		field[i++] = 11;
	    } else if (!strcmp("range", player->argp[n])) {
		field[i++] = 12;
	    } else if (!strcmp("load", player->argp[n])) {
		field[i++] = 13;
	    } else if (!strcmp("fuel", player->argp[n])) {
		field[i++] = 14;
	    } else if (!strcmp("hard", player->argp[n])) {
		field[i++] = 15;
	    } else if (!strcmp("ship", player->argp[n])) {
		field[i++] = 16;
	    } else if (!strcmp("land", player->argp[n])) {
		field[i++] = 17;
	    } else if (!strcmp("laun", player->argp[n])) {
		field[i++] = 18;
	    } else if (!strcmp("orb", player->argp[n])) {
		field[i++] = 19;
	    } else if (!strcmp("nuke", player->argp[n])) {
		field[i++] = 20;
	    } else if (!strcmp("grd", player->argp[n])) {
		field[i++] = 21;
	    } else {
		pr("Unrecognized field %s\n", player->argp[n]);
	    }
	    if (n++ > 100) {
		pr("Too many fields\n");
		return RET_FAIL;
	    }
	}
	field[i] = 0;
    }

    if (player->god)
	pr("   ");
    time(&now);
    pr("DUMP PLANES %ld\n", (long)now);
    if (player->god)
	pr("own ");
    pr("id");
    n = 0;
    while (field[n]) {
	switch (field[n]) {
	case 1:
	    pr(" type");
	    break;
	case 2:
	    pr(" x");
	    break;
	case 3:
	    pr(" y");
	    break;
	case 4:
	    pr(" wing");
	    break;
	case 5:
	    pr(" eff");
	    break;
	case 6:
	    pr(" mob");
	    break;
	case 7:
	    pr(" tech");
	    break;
	case 8:
	    pr(" att");
	    break;
	case 9:
	    pr(" def");
	    break;
	case 10:
	    pr(" acc");
	    break;
	case 11:
	    pr(" react");
	    break;
	case 12:
	    pr(" range");
	    break;
	case 13:
	    pr(" load");
	    break;
	case 14:
	    pr(" fuel");
	    break;
	case 15:
	    pr(" hard");
	    break;
	case 16:
	    pr(" ship");
	    break;
	case 17:
	    pr(" land");
	    break;
	case 18:
	    pr(" laun");
	    break;
	case 19:
	    pr(" orb");
	    break;
	case 20:
	    pr(" nuke");
	    break;
	case 21:
	    pr(" grd");
	    break;
	}
	n++;
    }
    pr("\n");

    nplanes = 0;
    natp = getnatp(player->cnum);
    while (nxtitem(&np, &plane)) {
	if (!player->owner || plane.pln_own == 0)
	    continue;
	nplanes++;
	if (player->god)
	    pr("%d ", plane.pln_own);
	pr("%d", np.cur);
	n = 0;
	while (field[n]) {
	    switch (field[n++]) {
	    case 1:
		pr(" %.4s", plchr[(int)plane.pln_type].pl_name);
		break;
	    case 2:
		pr(" %d", xrel(natp, plane.pln_x));
		break;
	    case 3:
		pr(" %d", yrel(natp, plane.pln_y));
		break;
	    case 4:
		pr(" %c", plane.pln_wing ? plane.pln_wing : '~');
		break;
	    case 5:
		pr(" %d", plane.pln_effic);
		break;
	    case 6:
		pr(" %d", plane.pln_mobil);
		break;
	    case 7:
		pr(" %d", plane.pln_tech);
		break;
	    case 8:
		pr(" %d", pln_att(&plane));
		break;
	    case 9:
		pr(" %d", pln_def(&plane));
		break;
	    case 10:
		pr(" %d", pln_acc(&plane));
		break;
	    case 11:
		pr(" %d", plane.pln_range);
		break;
	    case 12:
		pr(" %d", pln_range_max(&plane));
		break;
	    case 13:
		pr(" %d", pln_load(&plane));
		break;
	    case 14:
		pr(" %d", plchr[(int)plane.pln_type].pl_fuel);
		break;
	    case 15:
		pr(" %d", plane.pln_harden);
		break;
	    case 16:
		pr(" %d", plane.pln_ship);
		break;
	    case 17:
		pr(" %d", plane.pln_land);
		break;
	    case 18:
		pr(pln_is_in_orbit(&plane) ? " Y" : " N");
		break;
	    case 19:
		pr(pln_is_in_orbit(&plane)
		   && (plane.pln_flags & PLN_SYNCHRONOUS)
		   ? " Y" : " N");
		break;
	    case 20:
		if (getnuke(nuk_on_plane(&plane), &nuke)) {
		    pr(" %.5s", nchr[nuke.nuk_type].n_name);
		    break;
		} else
		    pr(" N/A");
		break;
	    case 21:
		pr(" %c", plane.pln_flags & PLN_AIRBURST ? 'A' : 'G');
		break;
	    }
	}
	pr("\n");
    }
    if (nplanes == 0) {
	if (player->argp[1])
	    pr("%s: No plane(s)\n", player->argp[1]);
	else
	    pr("%s: No plane(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d plane%s\n", nplanes, splur(nplanes));

    return RET_OK;
}
Ejemplo n.º 3
0
static int
msl_intercept(struct plnstr *msl, struct sctstr *sp, int sublaunch,
	      struct emp_qelem *irvlist, char *att_name, char *def_name,
	      int news_item)
{
    struct plnstr *pp;
    struct emp_qelem *intlist;
    struct emp_qelem intfoo;
    struct emp_qelem *qp;
    struct emp_qelem *next;
    struct plist *ip;
    int icount = 0;
    short destroyed;
    char *who = sublaunch ? "" : cname(msl->pln_own);

    intlist = &intfoo;
    emp_initque(intlist);
    /* First choose interceptors belonging to the target sector */
    /* only allow two defense missiles per missile attack */
    for (qp = irvlist->q_forw; qp != irvlist && icount < 2; qp = next) {
	next = qp->q_forw;
	ip = (struct plist *)qp;
	pp = &ip->plane;
	if (pp->pln_own != sp->sct_own)
	    continue;
	if (mission_pln_equip(ip, NULL, 'i') < 0) {
	    emp_remque(qp);
	    free(qp);
	    continue;
	}
	/* got one interceptor, delete from irv_list and
	 * add to  int_list.
	 */
	emp_remque(qp);
	emp_insque(qp, intlist);
	putplane(pp->pln_uid, pp);
	icount++;
    }
    /* only allow two defense missiles per missile attack */
    for (qp = irvlist->q_forw; qp != irvlist && icount < 2; qp = next) {
	next = qp->q_forw;
	ip = (struct plist *)qp;
	pp = &ip->plane;
	if (mission_pln_equip(ip, NULL, 'i') < 0) {
	    emp_remque(qp);
	    free(qp);
	    continue;
	}
	/* got one interceptor, delete from irv_list and
	 * add to  int_list.
	 */
	emp_remque(qp);
	emp_insque(qp, intlist);
	putplane(pp->pln_uid, pp);
	icount++;
    }
    /* Now, clean out the queue */
    while (!QEMPTY(irvlist)) {
	qp = irvlist->q_forw;
	emp_remque(qp);
	free(qp);
    }
    if (icount == 0) {
	mpr(sp->sct_own, "No %ss launched to intercept.\n", def_name);
	return 0;
    }

    /* attempt to destroy incoming missile */

    destroyed = 0;
    while (!destroyed && !QEMPTY(intlist)) {
	qp = intlist->q_forw;
	ip = (struct plist *)qp;
	pp = &ip->plane;

	mpr(msl->pln_own, "%s %s launched in defense!\n",
	    cname(pp->pln_own), def_name);
	if (sp->sct_own == pp->pln_own) {
	    mpr(sp->sct_own, "%s launched to intercept %s %s!\n",
		def_name, who, att_name);
	} else {
	    mpr(sp->sct_own,
		"%s launched an %s to intercept the %s %s!\n",
		cname(pp->pln_own), def_name, who, att_name);
	    mpr(pp->pln_own,
		"%s launched to intercept %s %s arcing towards %s territory!\n",
		def_name, who, att_name, cname(sp->sct_own));
	}

	if (msl_launch(pp, EF_PLANE, att_name, sp->sct_x, sp->sct_y,
		       msl->pln_own, NULL) >= 0
	    && msl_hit(pp, pln_def(msl), EF_PLANE, 0, 0, 0, msl->pln_own)) {
	    mpr(msl->pln_own, "%s destroyed by %s %s!\n",
		att_name, cname(pp->pln_own), def_name);
	    mpr(sp->sct_own, "%s %s intercepted!\n", who, att_name);
	    if (sp->sct_own != pp->pln_own)
		mpr(pp->pln_own, "%s %s intercepted!\n", who, att_name);
	    if (sublaunch)
		nreport(pp->pln_own, news_item, 0, 1);
	    else
		nreport(pp->pln_own, news_item, msl->pln_own, 1);
	    destroyed = 1;
	}
	/* zap the missile */
	pp->pln_effic = 0;
	putplane(pp->pln_uid, pp);
	emp_remque(qp);
	free(qp);
    }
    /* Clean out what is left in the list */
    while (!QEMPTY(intlist)) {
	qp = intlist->q_forw;
	emp_remque(qp);
	free(qp);
    }
    if (destroyed)
	return 1;
    if (icount) {
	mpr(msl->pln_own, "%s made it through %s defenses!\n",
	    att_name, def_name);
	mpr(sp->sct_own, "%s made it through %s defenses!\n",
	    att_name, def_name);
    }
    return 0;
}