예제 #1
0
static void
unit_list(struct emp_qelem *unit_list)
{
    struct emp_qelem *qp;
    struct emp_qelem *next;
    struct ulist *ulp;
    int type, npln, nch, nxl;
    struct empobj *unit;
    struct lndstr *lnd;
    struct shpstr *shp;

    if (CANT_HAPPEN(QEMPTY(unit_list)))
	return;
    qp = unit_list->q_back;
    ulp = (struct ulist *)qp;
    type = ulp->unit.gen.ef_type;
    if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP))
	return;

    if (type == EF_LAND)
	pr("lnd#     land type       x,y    a  eff mil  sh gun xl ln  mu tech retr\n");
    else
	pr("shp#     ship type       x,y   fl  eff mil  sh gun pn he xl ln mob tech\n");

    for (; qp != unit_list; qp = next) {
	next = qp->q_back;
	ulp = (struct ulist *)qp;
	lnd = &ulp->unit.land;
	shp = &ulp->unit.ship;
	unit = &ulp->unit.gen;
	if (CANT_HAPPEN(type != unit->ef_type))
	    continue;
	pr("%4d ", unit->uid);
	pr("%-16.16s ", empobj_chr_name(unit));
	prxy("%4d,%-4d ", unit->x, unit->y);
	pr("%1.1s", &unit->group);
	pr("%4d%%", unit->effic);
	if (type == EF_LAND) {
	    pr("%4d", lnd->lnd_item[I_MILIT]);
	    pr("%4d", lnd->lnd_item[I_SHELL]);
	    pr("%4d", lnd->lnd_item[I_GUN]);
	    pr("%3d%3d", lnd_nxlight(lnd), lnd_nland(lnd));
	} else {
	    pr("%4d", shp->shp_item[I_MILIT]);
	    pr("%4d", shp->shp_item[I_SHELL]);
	    pr("%4d", shp->shp_item[I_GUN]);
	    npln = shp_nplane(shp, &nch, &nxl, NULL);
	    pr("%3d%3d%3d", npln - nch - nxl, nch, nxl);
	    pr("%3d", shp_nland(shp));
	}
	pr("%4d", unit->mobil);
	pr("%4d", unit->tech);
	if (type == EF_LAND) {
	    pr("%4d%%", lnd->lnd_retreat);
	}
	pr("\n");
    }
}
예제 #2
0
int
navi(void)
{
    struct nstr_item ni_ship;
    struct emp_qelem ship_list;

    if (!snxtitem(&ni_ship, EF_SHIP, player->argp[1], NULL))
	return RET_SYN;
    shp_sel(&ni_ship, &ship_list);
    if (QEMPTY(&ship_list)) {
	pr("No ships\n");
	return RET_FAIL;
    }
    return unit_move(&ship_list);
}
예제 #3
0
int
march(void)
{
    struct nstr_item ni_land;
    struct emp_qelem land_list;

    if (!snxtitem(&ni_land, EF_LAND, player->argp[1], NULL))
	return RET_SYN;
    lnd_sel(&ni_land, &land_list);
    if (QEMPTY(&land_list)) {
	pr("No lands\n");
	return RET_FAIL;
    }
    return unit_move(&land_list);
}
예제 #4
0
static void
switch_leader(struct emp_qelem *list, char *arg)
{
    int uid = arg ? atoi(arg) : -1;

    struct emp_qelem *qp, *save;
    struct ulist *ulp;

    if (QEMPTY(list))
	return;

    save = qp = list->q_back;
    do {
	emp_remque(qp);
	emp_insque(qp, list);
	qp = list->q_back;
	ulp = (struct ulist *)qp;
	if (ulp->unit.gen.uid == uid || uid == -1)
	    break;
    } while (list->q_back != save);
}
예제 #5
0
int
unit_move(struct emp_qelem *list)
{
    struct empobj *leader = get_leader(list);
    int leader_uid = leader->uid;
    int type = leader->ef_type;
    int moved, suppress_map, dir, stopping;
    char *cp;
    char path[1024];

    unit_rad_map_set(list);

    pr("%s is %s\n",
	type == EF_SHIP ? "Flagship" : "Leader",
	unit_nameof(leader));

    cp = "";
    if (player->argp[2]) {
	strcpy(path, player->argp[2]);
	cp = unit_move_route(leader, path, sizeof(path));
	if (!cp)
	    cp = "";
    }

    moved = suppress_map = 0;
    for (;;) {
	/*
	 * Invariants:
	 * - shp_may_nav() true for all ships
	 * - lnd_may_mar() true for all land units
	 * - leader is up-to-date
	 * Implies all are in the same sector
	 */
	if (!*cp) {
	    cp = unit_move_getpath(list, suppress_map, path);
	    if (!cp) {
		if (type == EF_SHIP) {
		    shp_nav_stay_behind(list, player->cnum);
		    shp_nav_put(list, player->cnum);
		} else {
		    lnd_mar_stay_behind(list, player->cnum);
		    lnd_mar_put(list, player->cnum);
		}
		return RET_FAIL;
	    }
	    cp = unit_move_route(leader, path, sizeof(path));
	    if (!cp || !*cp)
		cp = "h";
	    suppress_map = 0;
	} else if ((dir = chkdir(*cp, DIR_STOP, DIR_LAST)) >= 0) {
	    cp++;
	    if (type == EF_SHIP)
		stopping = shp_nav_dir(list, dir, player->cnum)
		    || shp_nav_gauntlet(list, 1, player->cnum);
	    else {
		if (!moved && !lnd_abandon_askyn(list)) {
		    lnd_mar_put(list, player->cnum);
		    return RET_FAIL;
		}
		stopping = lnd_mar_dir(list, dir, player->cnum)
		    || lnd_mar_gauntlet(list, 1, player->cnum);
	    }
	    if (dir == DIR_STOP) {
		CANT_HAPPEN(!QEMPTY(list));
		return RET_OK;
	    }
	    moved = 1;
	    if (stopping)
		cp = "";
	} else {
	    cp = unit_move_non_dir(list, cp, &suppress_map);
	    if (!cp) {
		direrr("`%c' to stop", ", `%c' to view", NULL);
		pr(", `i' to list %s, `f' to change %s,\n",
		   type == EF_SHIP ? "ships" : "units",
		   type == EF_SHIP ? "flagship" : "leader");
		pr("`r' to radar, %s`l' to look, `M' to map, `B' to bmap,\n",
		   type == EF_SHIP ? "`s' to sonar, " : "");
		pr("`d' to drop mines, and `m' to minesweep\n");
		cp = "";
	    }
	}

	if (type == EF_SHIP)
	    shp_nav_stay_behind(list, player->cnum);
	else
	    lnd_mar_stay_behind(list, player->cnum);

	if (QEMPTY(list)) {
	    pr("No %s left\n", type == EF_SHIP ? "ships" : "lands");
	    return RET_OK;
	}

	leader = get_leader(list);
	if (leader->uid != leader_uid) {
	    leader_uid = leader->uid;
	    pr("Changing %s to %s\n",
	       leader->ef_type == EF_SHIP ? "flagship" : "leader",
	       unit_nameof(leader));
	}
	unit_rad_map_set(list);
    }
}
예제 #6
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;
}
예제 #7
0
int
assa(void)
{
    struct combat off[1];	/* assaulting ship */
    struct combat def[1];	/* defending sector */
    int fort_sup, ship_sup, land_sup, plane_sup;
    struct emp_qelem olist;	/* assaulting units */
    struct emp_qelem dlist;	/* defending units */
    int ototal;			/* total assaulting strength */
    int a_engineer = 0;		/* assaulter engineers are present */
    int a_spy = 0;		/* the best assaulter scout */
    double osupport = 1.0;	/* assault support */
    double dsupport = 1.0;	/* defense support */
    char *p;
    char buf[1024];
    int n;
    int ourtotal;
    struct emp_qelem *qp, *next;
    struct ulist *llp;
    int rel;

    att_combat_init(off, EF_SHIP);
    att_combat_init(def, EF_SECTOR);
    /*
     * Collect input from the assaulter
     */

    /* What are we assaulting? */

    if (!(p = getstarg(player->argp[1], "Sector :  ", buf)))
	return RET_SYN;
    if (!sarg_xy(p, &def->x, &def->y))
	return RET_SYN;
    if (att_abort(A_ASSAULT, NULL, def))
	return RET_FAIL;

    /*
     * Ask the assaulter what he wants to assault with
     */

    if ((off->shp_uid =
	 onearg(player->argp[2], "Assault from ship # ")) < 0) {
	pr("You may only assault from one ship!\n");
	return RET_FAIL;
    }
    if (att_abort(A_ASSAULT, off, def)) {
	pr("Assault aborted\n");
	return RET_OK;
    }

    /* Show what we're assaulting */
    att_show(def);

    /* Ask about offensive support */

    att_ask_support(3, &fort_sup, &ship_sup, &land_sup, &plane_sup);
    if (att_abort(A_ASSAULT, off, def)) {
	att_empty_attack(A_ASSAULT, 0, def);
	return RET_OK;
    }

    /* Ask the player what he wants to assault with */

    att_ask_offense(A_ASSAULT, off, def, &olist, &a_spy, &a_engineer);
    if (att_abort(A_ASSAULT, off, def)) {
	pr("Assault aborted\n");
	att_empty_attack(A_ASSAULT, 0, def);
	return att_free_lists(&olist, NULL);
    }

    /* If we're assaulting our own sector, end here */
    if (def->own == player->cnum) {
	if (off->troops)
	    pr("You reinforce %s with %d troops\n",
	       xyas(def->x, def->y, player->cnum), off->troops);
	if (off->troops || !QEMPTY(&olist))
	    att_move_in_off(A_ASSAULT, off, &olist, def);
	return RET_OK;
    }

    ototal = att_get_offense(A_ASSAULT, off, &olist, def);
    if (att_abort(A_ASSAULT, off, def)) {
	pr("Assault aborted\n");
	att_empty_attack(A_ASSAULT, 0, def);
	return att_free_lists(&olist, NULL);
    }

    /*
     * We have now got all the answers from the assaulter.  From this point
     * forward, we can assume that this battle is the _only_ thing
     * happening in the game.
     */

    /* First, we check to see if the only thing we have are spies
     * assaulting.  If so, we try to sneak them on land.  If they
     * make it, the defenders don't see a thing.  If they fail, well,
     * the spies die, and the defenders see them. */

    ourtotal = 0;
    for (n = 0; n <= off->last; n++) {
	if (off[n].type == EF_BAD)
	    continue;
	ourtotal += off[n].troops * att_combat_eff(off + n);
    }
    for (qp = olist.q_forw; qp != &olist; qp = next) {
	next = qp->q_forw;
	llp = (struct ulist *)qp;
	if (lchr[(int)llp->unit.land.lnd_type].l_flags & L_SPY)
	    continue;
	ourtotal++;
    }

    /* If no attacking forces (i.e. we got here with only spies)
     * then try to sneak on-land. */

    if (!ourtotal) {
	pr("Trying to sneak on shore...\n");

	for (qp = olist.q_forw; qp != &olist; qp = next) {
	    next = qp->q_forw;
	    llp = (struct ulist *)qp;
	    rel = relations_with(def->own, player->cnum);
	    if (chance(0.10) || rel == ALLIED || !def->own) {
		pr("%s made it on shore safely.\n", prland(&llp->unit.land));
		llp->unit.land.lnd_x = def->x;
		llp->unit.land.lnd_y = def->y;
		llp->unit.land.lnd_ship = -1;
		putland(llp->unit.land.lnd_uid, &llp->unit.land);
	    } else {
		pr("%s was spotted", prland(&llp->unit.land));
		if (rel <= HOSTILE) {
		    wu(0, def->own, "%s spy shot and killed in %s.\n",
		       cname(player->cnum), xyas(def->x, def->y,
						 def->own));
		    pr(" and was killed in the attempt.\n");
		    llp->unit.land.lnd_effic = 0;
		    putland(llp->unit.land.lnd_uid, &llp->unit.land);
		    lnd_put_one(llp);
		} else {
		    wu(0, def->own, "%s spy spotted in %s.\n",
		       cname(player->cnum), xyas(def->x, def->y,
						 def->own));
		    pr(" but made it ok.\n");
		    llp->unit.land.lnd_x = def->x;
		    llp->unit.land.lnd_y = def->y;
		    llp->unit.land.lnd_ship = -1;
		    putland(llp->unit.land.lnd_uid, &llp->unit.land);
		}
	    }
	}
	return RET_OK;
    }

    /* Get the real defense */

    att_get_defense(&olist, def, &dlist, a_spy, ototal);

    /* Get assaulter and defender support */

    att_get_support(A_ASSAULT, fort_sup, ship_sup, land_sup, plane_sup,
		    &olist, off, &dlist, def, &osupport, &dsupport,
		    a_engineer);
    if (att_abort(A_ASSAULT, off, def)) {
	pr("Assault aborted\n");
	att_empty_attack(A_ASSAULT, 0, def);
	return att_free_lists(&olist, &dlist);
    }

    /*
     * Death, carnage, and destruction.
     */

    att_fight(A_ASSAULT, off, &olist, osupport, def, &dlist, dsupport);

    return RET_OK;
}
예제 #8
0
int
fly(void)
{
    coord tx, ty;
    coord ax, ay;
    int ap_to_target;
    struct ichrstr *ip;
    char flightpath[MAX_PATH_LEN];
    int cno;
    struct nstr_item ni_bomb;
    struct nstr_item ni_esc;
    union empobj_storage target;
    struct emp_qelem bomb_list;
    struct emp_qelem esc_list;
    int wantflags;
    struct sctstr ap_sect;
    char buf[1024];

    wantflags = 0;
    if (get_planes(&ni_bomb, &ni_esc, player->argp[1], player->argp[2]) < 0)
	return RET_SYN;
    if (!get_assembly_point(player->argp[3], &ap_sect, buf))
	return RET_SYN;
    ax = ap_sect.sct_x;
    ay = ap_sect.sct_y;
    if (!getpath(flightpath, player->argp[4], ax, ay, 0, 0, MOB_FLY))
	return RET_SYN;
    tx = ax;
    ty = ay;
    (void)pathtoxy(flightpath, &tx, &ty, fcost);
    pr("Ending sector is %s\n", xyas(tx, ty, player->cnum));
    ip = whatitem(player->argp[5], "transport what? ");
    if (player->aborted)
	return RET_SYN;

    if (pln_where_to_land(tx, ty, &target, &wantflags) < 0)
	return RET_SYN;
    cno = target.gen.ef_type == EF_SHIP ? target.gen.uid : -1;

    if (ip && ip->i_uid == I_CIVIL) {
	if (target.gen.own != player->cnum) {
	    pr("Your civilians refuse to board a flight abroad!\n");
	    return RET_FAIL;
	}
	if (target.gen.ef_type == EF_SECTOR
	    && target.sect.sct_own != target.sect.sct_oldown) {
	    pr("Can't fly civilians into occupied sectors.\n");
	    return RET_FAIL;
	}
    }

    ap_to_target = strlen(flightpath);
    pr("range to target is %d\n", ap_to_target);
    /*
     * select planes within range
     */
    pln_sel(&ni_bomb, &bomb_list, &ap_sect, ap_to_target, 1,
	    wantflags, P_M | P_O);
    pln_sel(&ni_esc, &esc_list, &ap_sect, ap_to_target, 1,
	    wantflags | P_ESC | P_F, P_M | P_O);
    if (cno >= 0
	&& !pln_can_land_on_carrier(&bomb_list, &esc_list, &target.ship)) {
	pr("Not enough room on ship #%d!\n", cno);
	return RET_FAIL;
    }
    /*
     * now arm and equip the bombers, transports, whatever.
     */
    pln_arm(&bomb_list, ap_to_target, 't', ip);
    if (QEMPTY(&bomb_list)) {
	pr("No planes could be equipped for the mission.\n");
	return RET_FAIL;
    }
    pln_arm(&esc_list, ap_to_target, 'e', NULL);
    ac_encounter(&bomb_list, &esc_list, ax, ay, flightpath, 0);
    if (QEMPTY(&bomb_list)) {
	pr("No planes got through fighter defenses\n");
    } else {
	pln_dropoff(&bomb_list, ip, tx, ty, cno);
	pln_newlanding(&bomb_list, tx, ty, cno);
	pln_newlanding(&esc_list, tx, ty, cno);
    }
    pln_put(&bomb_list);
    pln_put(&esc_list);
    return RET_OK;
}
예제 #9
0
파일: drop.c 프로젝트: fstltna/empserver
int
drop(void)
{
    coord tx, ty;
    coord ax, ay;
    int ap_to_target;
    struct ichrstr *ip;
    char flightpath[MAX_PATH_LEN];
    struct nstr_item ni_bomb;
    struct nstr_item ni_esc;
    struct sctstr target;
    struct emp_qelem bomb_list;
    struct emp_qelem esc_list;
    int wantflags;
    struct sctstr ap_sect;
    char buf[1024];

    if (get_planes(&ni_bomb, &ni_esc, player->argp[1], player->argp[2]) < 0)
	return RET_SYN;
    if (!get_assembly_point(player->argp[3], &ap_sect, buf))
	return RET_SYN;
    ax = ap_sect.sct_x;
    ay = ap_sect.sct_y;
    if (!getpath(flightpath, player->argp[4], ax, ay, 0, 0, MOB_FLY))
	return RET_SYN;
    tx = ax;
    ty = ay;
    (void)pathtoxy(flightpath, &tx, &ty, fcost);
    pr("target is %s\n", xyas(tx, ty, player->cnum));
    if (!(ip = whatitem(player->argp[5], "Drop off what? ")))
	return RET_SYN;
    getsect(tx, ty, &target);

    if (relations_with(target.sct_own, player->cnum) == ALLIED) {
	/* own or allied sector: cargo drop */
	if (ip->i_uid == I_CIVIL) {
	    if (target.sct_own != player->cnum) {
		pr("Your civilians refuse to board a flight abroad!\n");
		return RET_FAIL;
	    }
	    if (target.sct_own != target.sct_oldown) {
		pr("Can't drop civilians into occupied sectors.\n");
		return RET_FAIL;
	    }
	}
	wantflags = P_C;
    } else {
	/* into the unknown... */
	if (ip->i_uid != I_SHELL) {
	    pr("You don't own %s!\n", xyas(tx, ty, player->cnum));
	    return RET_FAIL;
	}
	/* mine drop */
	wantflags = P_MINE;
    }

    ap_to_target = strlen(flightpath);
    if (flightpath[ap_to_target - 1] == 'h')
	ap_to_target--;
    pr("range to target is %d\n", ap_to_target);
    /*
     * select planes within range
     */
    pln_sel(&ni_bomb, &bomb_list, &ap_sect, ap_to_target, 2,
	    wantflags, P_M | P_O);
    pln_sel(&ni_esc, &esc_list, &ap_sect, ap_to_target, 2,
	    P_ESC | P_F, P_M | P_O);
    /*
     * now arm and equip the bombers, transports, whatever.
     */
    pln_arm(&bomb_list, 2 * ap_to_target,
	    wantflags & P_MINE ? 'm' : 'd',
	    ip);
    if (QEMPTY(&bomb_list)) {
	pr("No planes could be equipped for the mission.\n");
	return RET_FAIL;
    }
    pln_arm(&esc_list, 2 * ap_to_target, 'e', NULL);
    ac_encounter(&bomb_list, &esc_list, ax, ay, flightpath, 0);
    if (QEMPTY(&bomb_list)) {
	pr("No planes got through fighter defenses\n");
    } else {
	if (wantflags & P_MINE)
	    pln_mine(&bomb_list, tx, ty);
	else
	    pln_dropoff(&bomb_list, ip, tx, ty, -1);
    }
    pln_put(&bomb_list);
    pln_put(&esc_list);
    return RET_OK;
}