示例#1
0
/*
 * Get assembly point argument.
 * If INPUT is not empty, use it, else prompt for more input using PROMPT.
 * If this yields a valid assembly point, read it into *AP_SECT and
 * return AP_SECT.
 * Else complain and return NULL.
 * *AP_SECT and BUF[1024] may be modified in either case.
 */
struct sctstr *
get_assembly_point(char *input, struct sctstr *ap_sect, char *buf)
{
    char *p;
    coord x, y;
    struct nstr_item ni;
    struct shpstr ship;

    p = getstarg(input, "assembly point? ", buf);
    if (!p || *p == 0)
	return NULL;
    if (!sarg_xy(p, &x, &y) || !getsect(x, y, ap_sect))
	return NULL;

    /* over own or allied sector is fine */
    if (relations_with(ap_sect->sct_own, player->cnum) == ALLIED)
	return ap_sect;

    /* over own or allied ship is fine */
    snxtitem_xy(&ni, EF_SHIP, x, y);
    while (nxtitem(&ni, &ship)) {
	if (ship.shp_effic < SHIP_MINEFF || ship.shp_own == 0)
	    continue;
	if (relations_with(ship.shp_own, player->cnum) == ALLIED)
	    return ap_sect;
    }

    pr("Assembly point not owned by you or an ally!\n");
    return NULL;
}
示例#2
0
/*
 * Find out whether planes can fly one-way to X,Y.
 * Offer the player any carriers there.  If he chooses one, read it
 * into TARGET->ship.  Else read the target sector into TARGET->sect.
 * If planes can land there, set required plane flags in *FLAGSP, and
 * return 0.  Else return -1.
 */
int
pln_where_to_land(coord x, coord y,
		  union empobj_storage *target, int *flagsp)
{
    int nships;
    int cno;
    int fl;
    char buf[1024];
    char *p;

    /* offer carriers */
    nships = carriersatxy(x, y, player->cnum);
    if (nships) {
	for (;;) {
	    p = getstring("Carrier #? ", buf);
	    if (!p)
		return -1;
	    if (!*p)
		break;
	    cno = atoi(p);
	    if (!getship(cno, &target->ship)
		|| (!player->owner
		    && (relations_with(target->ship.shp_own, player->cnum)
			!= ALLIED))) {
		pr("Not yours\n");
		continue;
	    }
	    if (target->ship.shp_x != x || target->ship.shp_y != y) {
		pr("Ship #%d not in %s\n", cno, xyas(x, y, player->cnum));
		continue;
	    }
	    fl = carrier_planes(&target->ship, 0);
	    if (fl == 0) {
		pr("Can't land on %s.\n", prship(&target->ship));
		continue;
	    }
	    /* clear to land on ship#CNO */
	    pr("landing on carrier %d\n", cno);
	    *flagsp |= fl;
	    return 0;
	}
    }

    /* try to land at sector */
    getsect(x, y, &target->sect);
    if (relations_with(target->sect.sct_own, player->cnum) != ALLIED) {
	pr("Nowhere to land at sector %s!\n", xyas(x, y, player->cnum));
	return -1;
    }
    if (target->sect.sct_type == SCT_MOUNT) {
	pr("Nowhere to land at sector %s!\n", xyas(x, y, player->cnum));
	return -1;
    }
    /* clear to land at sector */
    if (target->sect.sct_type != SCT_AIRPT || target->sect.sct_effic < 60)
	*flagsp |= P_V;
    return 0;
}
示例#3
0
void
msl_sel(struct emp_qelem *list, coord x, coord y, natid victim,
	int wantflags, int nowantflags, int mission)
{
    struct plchrstr *pcp;
    struct plnstr plane;
    struct plist *irv;
    struct nstr_item ni;

    emp_initque(list);
    snxtitem_all(&ni, EF_PLANE);
    while (nxtitem(&ni, &plane)) {
	if (!plane.pln_own)
	    continue;

	pcp = &plchr[(int)plane.pln_type];
	if (!(pcp->pl_flags & P_M))
	    continue;
	if (wantflags && (pcp->pl_flags & wantflags) != wantflags)
	    continue;
	if (nowantflags && pcp->pl_flags & nowantflags)
	    continue;
	if (mission && plane.pln_mission != mission)
	    continue;
	if (mission &&
	    plane.pln_radius < mapdist(x, y, plane.pln_opx, plane.pln_opy))
	    continue;
	if (relations_with(plane.pln_own, victim) >= NEUTRAL)
	    continue;
	/* missiles go one way, so we can use all the range */
	if (plane.pln_range < mapdist(x, y, plane.pln_x, plane.pln_y))
	    continue;
	if (plane.pln_mobil <= 0)
	    continue;
	if (plane.pln_effic < 100)
	    continue;
	if (opt_MARKET) {
	    if (ontradingblock(EF_PLANE, &plane))
		continue;
	}
	if (!pln_airbase_ok(&plane, 1, 0))
	    continue;
	/* got a valid interceptor */
	irv = malloc(sizeof(*irv));
	irv->load = 0;
	irv->pstage = PLG_HEALTHY;
	irv->pcp = &plchr[(int)plane.pln_type];
	irv->plane = plane;
	emp_insque(&irv->queue, list);
    }
}
示例#4
0
static void
coun_list(struct natstr *natp)
{
    char *status;
    natid cn = natp->nat_cnum;

    pr("%3d  ", cn);

    if (getplayer(cn)
	&& (player->god
	    || natp->nat_stat == STAT_GOD
	    || relations_with(cn, player->cnum) == ALLIED))
	pr(" Now logged on                     ");
    else if (player->god) {
	if (natp->nat_last_login == 0)
	    pr(" Never logged on                   ");
	else {
	    pr("%.16s - ", ctime(&natp->nat_last_login));
	    pr("%-16.16s",
	       natp->nat_last_login <= natp->nat_last_logout
	       ? ctime(&natp->nat_last_logout) : "?");
	}
    } else
	pr(" Unknown                           ");

    if (player->god)
	pr(" %4d", natp->nat_btu);

    if (natp->nat_stat == STAT_GOD)
	status = "DEITY";
    else if (natp->nat_stat == STAT_NEW)
	status = "New";
    else if (natp->nat_stat == STAT_SANCT)
	status = "Sanctuary";
    else if (natp->nat_stat == STAT_ACTIVE) {
	status = "Active";
	if (!opt_HIDDEN || player->god) {
	    if (influx(natp))
		status = "In flux";
	    else if (natp->nat_money < 0)
		status = "Broke";
	}
    } else {
	status = "Visitor";
    }
    pr("  %-9.9s  %s\n", status, natp->nat_cnam);
}
示例#5
0
文件: orig.c 项目: gefla/empserver
int
orig(void)
{
    char *p;
    coord x, y;
    char buf[1024];
    int cnum;
    struct natstr *np;

    p = getstarg(player->argp[1], "New origin (sector or country) : ", buf);
    if (!p || !*p)
        return RET_SYN;
    if (!isalpha(*p) && strchr(p, ',')) {
        /* sector */
        if (!sarg_xy(p, &x, &y)) {
            pr("Bad sector designation.\n");
            return RET_SYN;
        }
    } else if (*p == '~') {
        /* reset */
        if (!player->god) {
            pr("Only deities can reset their origin.\n");
            return RET_FAIL;
        }
        x = y = 0;
    } else {
        /* country */
        cnum = natarg(p, NULL);
        if (!(np = getnatp(cnum)))
            return RET_SYN;
        if (!player->god && relations_with(cnum, player->cnum) != ALLIED) {
            pr("Country %s is not allied with you!\n", np->nat_cnam);
            return RET_FAIL;
        }
        x = np->nat_xorg;
        y = np->nat_yorg;
    }
    pr("Origin at %s (old system) is now at 0,0 (new system).\n",
       xyas(x, y, player->cnum));
    np = getnatp(player->cnum);
    np->nat_xorg = x;
    np->nat_yorg = y;
    putnat(np);
    return RET_OK;
}
示例#6
0
文件: tend.c 项目: fstltna/empserver
int
tend(void)
{
    struct nstr_item targets;
    struct nstr_item tenders;
    struct shpstr tender;
    struct shpstr target;
    struct ichrstr *ip;
    struct mchrstr *vbase;
    int amt;
    int retval;
    int ontender;
    int ontarget;
    int maxtender;
    int maxtarget;
    int transfer;
    int total;
    int type;
    char *p;
    char prompt[512];
    char buf[1024];

    p = getstarg(player->argp[1], "Tend what commodity (or 'land')? ",
		 buf);
    if (!p || !*p)
	return RET_SYN;

    if (!strncmp(p, "land", 4))
	type = EF_LAND;
    else if (NULL != (ip = item_by_name(p)))
	type = EF_SECTOR;
    else {
	pr("Can't tend '%s'\n", p);
	return RET_SYN;
    }

    if (!snxtitem(&tenders, EF_SHIP, player->argp[2], "Tender(s)? "))
	return RET_SYN;

    while (nxtitem(&tenders, &tender)) {
	if (!player->owner)
	    continue;
	if (type == EF_LAND) {
	    sprintf(prompt, "Land unit(s) to tend from %s? ",
		    prship(&tender));
	    p = getstarg(player->argp[3], prompt, buf);
	    if (!p)
		return RET_FAIL;
	    if (!*p)
		continue;
	    if (!check_ship_ok(&tender))
		return RET_SYN;
	    if (0 != (retval = tend_land(&tender, p)))
		return retval;
	    continue;
	}
	sprintf(prompt, "Number of %s to tend from %s? ",
		ip->i_name, prship(&tender));
	p = getstarg(player->argp[3], prompt, buf);
	if (!p)
	    return RET_FAIL;
	if (!*p)
	    continue;
	if (!check_ship_ok(&tender))
	    return RET_SYN;
	if (!(amt = atoi(p))) {
	    pr("Amount must be non-zero!\n");
	    return RET_SYN;
	}
	ontender = tender.shp_item[ip->i_uid];
	if (ontender == 0 && amt > 0) {
	    pr("No %s on %s\n", ip->i_name, prship(&tender));
	    return RET_FAIL;
	}
	vbase = &mchr[(int)tender.shp_type];
	maxtender = vbase->m_item[ip->i_uid];
	if (maxtender == 0) {
	    pr("A %s cannot hold any %s\n",
	       mchr[(int)tender.shp_type].m_name, ip->i_name);
	    break;
	}
	if (!snxtitem(&targets, EF_SHIP,
		      player->argp[4], "Ships to be tended? "))
	    return RET_FAIL;
	if (!check_ship_ok(&tender))
	    return RET_SYN;
	total = 0;
	while (nxtitem(&targets, &target)) {
	    if (!player->owner
		&& relations_with(target.shp_own, player->cnum) < FRIENDLY)
		continue;
	    if (target.shp_uid == tender.shp_uid)
		continue;
	    if (tender.shp_x != target.shp_x ||
		tender.shp_y != target.shp_y)
		continue;
	    if (ip->i_uid == I_CIVIL && tender.shp_own != target.shp_own)
		continue;
	    ontarget = target.shp_item[ip->i_uid];
	    vbase = &mchr[(int)target.shp_type];
	    maxtarget = vbase->m_item[ip->i_uid];
	    if (amt < 0) {
		/* take from target and give to tender */
		if (!player->owner)
		    continue;
		if (ontarget == 0) {
		    pr("No %s on %s\n", ip->i_name, prship(&target));
		    continue;
		}
		transfer = MIN(ontarget, -amt);
		transfer = MIN(maxtender - ontender, transfer);
		if (transfer == 0)
		    continue;
		target.shp_item[ip->i_uid] = ontarget - transfer;
		ontender += transfer;
		total += transfer;
	    } else {
		/* give to target from tender */
		transfer = MIN(ontender, amt);
		transfer = MIN(transfer, maxtarget - ontarget);
		if (transfer == 0)
		    continue;
		target.shp_item[ip->i_uid] = ontarget + transfer;
		ontender -= transfer;
		total += transfer;
		if (transfer && target.shp_own != player->cnum) {
		    wu(0, target.shp_own, "%s tended %d %s to %s\n",
		       cname(player->cnum), total, ip->i_name,
		       prship(&target));
		}
	    }
	    expose_ship(&tender, &target);
	    putship(target.shp_uid, &target);
	    if (amt > 0 && ontender == 0) {
		pr("%s out of %s\n", prship(&tender), ip->i_name);
		break;
	    }
	}
	pr("%d total %s transferred %s %s\n",
	   total, ip->i_name, (amt > 0) ? "off of" : "to",
	   prship(&tender));
	tender.shp_item[ip->i_uid] = ontender;
	tender.shp_mission = 0;
	putship(tender.shp_uid, &tender);
    }
    return RET_OK;
}
示例#7
0
文件: tend.c 项目: fstltna/empserver
static int
tend_land(struct shpstr *tenderp, char *units)
{
    struct nstr_item lni;
    struct nstr_item targets;
    struct shpstr target;
    struct lndstr land;
    char buf[1024];

    if (!snxtitem(&lni, EF_LAND, units, NULL))
	return RET_SYN;

    while (nxtitem(&lni, &land)) {
	if (!player->owner)
	    continue;
	if (land.lnd_ship != tenderp->shp_uid) {
	    pr("%s is not on %s!\n", prland(&land), prship(tenderp));
	    continue;
	}
	if (!(lchr[(int)land.lnd_type].l_flags & L_ASSAULT)) {
	    pr("%s does not have \"assault\" capability and can't be tended\n",
	       prland(&land));
	    continue;
	}
	if (!snxtitem(&targets, EF_SHIP,
		      player->argp[4], "Ship to be tended? "))
	    return RET_FAIL;
	if (!check_ship_ok(tenderp) || !check_land_ok(&land))
	    return RET_SYN;
	while (nxtitem(&targets, &target)) {
	    if (!player->owner
		&& relations_with(target.shp_own, player->cnum) < FRIENDLY)
		continue;
	    if (target.shp_uid == tenderp->shp_uid)
		continue;
	    if (tenderp->shp_x != target.shp_x ||
		tenderp->shp_y != target.shp_y)
		continue;

	    /* Fit unit on ship */
	    getship(target.shp_uid, &target);

	    if ((!(lchr[(int)land.lnd_type].l_flags & L_LIGHT)) &&
		(!((mchr[(int)target.shp_type].m_flags & M_SUPPLY) &&
		   (!(mchr[(int)target.shp_type].m_flags & M_SUB))))) {
		pr("You can only load light units onto ships,\n"
		   "unless the ship is a non-sub supply ship\n"
		   "%s not tended\n", prland(&land));
		continue;
	    }

	    if ((mchr[(int)target.shp_type].m_flags & M_SUB) &&
		(lchr[(int)land.lnd_type].l_flags & L_SPY) &&
		!mchr[(int)target.shp_type].m_nland) {
		if (shp_nland(&target) > 1) {
		    pr("%s doesn't have room for more than two spy units!\n",
		       prship(&target));
		    continue;
		}
	    } else if (shp_nland(&target) >= mchr[target.shp_type].m_nland) {
		if (mchr[(int)target.shp_type].m_nland)
		    pr("%s doesn't have room for any more land units!\n",
		       prship(&target));
		else
		    pr("%s doesn't carry land units!\n", prship(&target));
		continue;
	    }
	    pr("%s transferred from %s to %s\n",
	       prland(&land), prship(tenderp), prship(&target));
	    sprintf(buf, "loaded on your %s at %s",
		    prship(&target), xyas(target.shp_x, target.shp_y,
					  target.shp_own));
	    gift(target.shp_own, player->cnum, &land, buf);
	    land.lnd_ship = target.shp_uid;
	    land.lnd_harden = 0;
	    putland(land.lnd_uid, &land);
	    expose_ship(tenderp, &target);
	    putship(target.shp_uid, &target);
	    putship(tenderp->shp_uid, tenderp);
	}
    }
    return 0;
}
示例#8
0
文件: scra.c 项目: gefla/empserver
int
scra(void)
{
    struct nstr_item ni;
    union empobj_storage item;
    int type, n;
    struct sctstr sect;
    struct mchrstr *mp;
    struct plchrstr *pp;
    struct lchrstr *lp;
    char *p;
    i_type i;
    char prompt[128];
    char buf[1024];
    float eff;
    short *mvec;
    int amt;

    if (!(p = getstarg(player->argp[1], "Ship, land, or plane? ", buf)))
	return RET_SYN;
    switch (*p) {
    case 's':
	type = EF_SHIP;
	break;
    case 'p':
	type = EF_PLANE;
	break;
    case 'l':
	type = EF_LAND;
	break;
    default:
	pr("Ships, land units, or planes only! (s, l, p)\n");
	return RET_SYN;
    }

    if (!snxtitem(&ni, type, player->argp[2], NULL))
	return RET_SYN;
    n = 0;
    while (nxtitem(&ni, &item)) {
	if (!player->owner)
	    continue;
	n++;
    }
    snprintf(prompt, sizeof(prompt), "Really scrap %d %s%s [n]? ",
			    n, ef_nameof(type), splur(n));
    if (!confirm(prompt))
	return RET_FAIL;

    snxtitem_rewind(&ni);
    while (nxtitem(&ni, &item)) {
	if (!player->owner)
	    continue;

	if (opt_MARKET) {
	    if (ontradingblock(type, &item.ship)) {
		pr("You cannot scrap an item on the trading block!\n");
		continue;
	    }
	}

	getsect(item.gen.x, item.gen.y, &sect);
	if (type == EF_SHIP) {
	    if (!player->owner
		&& relations_with(sect.sct_own, player->cnum) < FRIENDLY) {
		pr("%s is not in a friendly harbor!\n",
		   prship(&item.ship));
		continue;
	    }
	    if (sect.sct_type != SCT_HARBR || sect.sct_effic < 60) {
		pr("%s is not in a 60%% efficient harbor!\n",
		   prship(&item.ship));
		continue;
	    }
	    if (mchr[item.ship.shp_type].m_flags & M_TRADE) {
		pr("WARNING: You only collect money from trade ships if you \"scuttle\" them!\n");
		sprintf(prompt,
			"Are you really sure that you want to scrap %s (n)? ",
			prship(&item.ship));
		if (!confirm(prompt)) {
		    pr("%s not scrapped\n", prship(&item.ship));
		    continue;
		}
	    }
	} else {
	    if (!player->owner
		&& relations_with(sect.sct_own, player->cnum) != ALLIED) {
		pr("%s is not in an allied sector!\n",
		   unit_nameof(&item.gen));
		continue;
	    }
	    if (type == EF_PLANE
		&& (sect.sct_type != SCT_AIRPT || sect.sct_effic < 60)) {
		pr("%s is not in a 60%% efficient airfield!\n",
		   prplane(&item.plane));
		continue;
	    }
	}

	pr("%s scrapped in %s\n",
	   unit_nameof(&item.gen),
	   xyas(item.gen.x, item.gen.y, player->cnum));
	unit_drop_cargo(&item.gen, sect.sct_own);
	if (type == EF_SHIP) {
	    eff = item.ship.shp_effic / 100.0;
	    mp = &mchr[(int)item.ship.shp_type];
	    for (i = I_NONE + 1; i <= I_MAX; i++) {
		if (load_comm_ok(&sect, item.ship.shp_own, i,
				 -item.ship.shp_item[i]))
		    sect.sct_item[i] += item.ship.shp_item[i];
	    }
	    mvec = mp->m_mat;
	    if (item.ship.shp_pstage == PLG_INFECT
		&& sect.sct_pstage == PLG_HEALTHY)
		sect.sct_pstage = PLG_EXPOSED;
	} else if (type == EF_LAND) {
	    eff = item.land.lnd_effic / 100.0;
	    lp = &lchr[(int)item.land.lnd_type];
	    for (i = I_NONE + 1; i <= I_MAX; i++) {
		if (load_comm_ok(&sect, item.land.lnd_own, i,
				 -item.land.lnd_item[i]))
		    sect.sct_item[i] += item.land.lnd_item[i];
	    }
	    mvec = lp->l_mat;
	    if (item.land.lnd_pstage == PLG_INFECT
		&& sect.sct_pstage == PLG_HEALTHY)
		sect.sct_pstage = PLG_EXPOSED;
	} else {
	    eff = item.land.lnd_effic / 100.0;
	    pp = &plchr[(int)item.plane.pln_type];
	    mvec = pp->pl_mat;
	}
	item.gen.effic = 0;
	put_empobj(type, item.gen.uid, &item.gen);
	for (i = I_NONE + 1; i <= I_MAX; i++) {
	    if (i == I_CIVIL || i == I_MILIT || i == I_UW)
		amt = sect.sct_item[i] + mvec[i] * eff;
	    else
		amt = sect.sct_item[i] + mvec[i] * 2 / 3 * eff;
	    if (amt > ITEM_MAX)
		amt = ITEM_MAX;
	    sect.sct_item[i] = amt;
	}
	putsect(&sect);
    }
    return RET_OK;
}
示例#9
0
static int
lupgr(void)
{
    struct sctstr sect;
    struct natstr *natp;
    struct nstr_item ni;
    struct lndstr land;
    struct lchrstr *lp;
    int n;
    int tlev;
    int avail, cost;
    int cash;

    if (!snxtitem(&ni, EF_LAND, player->argp[2], NULL))
	return RET_SYN;
    natp = getnatp(player->cnum);
    cash = natp->nat_money;
    tlev = (int)natp->nat_level[NAT_TLEV];
    n = 0;
    while (nxtitem(&ni, &land)) {
	if (land.lnd_own == 0)
	    continue;
	getsect(land.lnd_x, land.lnd_y, &sect);
	if (sect.sct_own != player->cnum)
	    continue;
	if (sect.sct_type != SCT_HEADQ || sect.sct_effic < 60)
	    continue;
	if (relations_with(land.lnd_own, sect.sct_own) < FRIENDLY) {
	    pr("You are not on friendly terms with the owner of unit %d!\n",
	       land.lnd_uid);
	    continue;
	}
	n++;
	lp = &lchr[(int)land.lnd_type];
	avail = (LND_BLD_WORK(lp->l_lcm, lp->l_hcm) * UPGR_COST + 99) / 100;
	if (sect.sct_avail < avail) {
	    pr("Not enough available work in %s to upgrade a %s\n",
	       xyas(sect.sct_x, sect.sct_y, player->cnum), lp->l_name);
	    pr(" (%d available work required)\n", avail);
	    continue;
	}
	if (land.lnd_effic < 60) {
	    pr("%s is too damaged to upgrade!\n", prland(&land));
	    continue;
	}
	if (land.lnd_tech >= tlev) {
	    pr("%s tech: %d, yours is only %d\n",
	       prland(&land), land.lnd_tech, tlev);
	    continue;
	}
	cost = lp->l_cost * UPGR_COST / 100;
	if (cost + player->dolcost > cash) {
	    pr("You don't have enough money to upgrade %s!\n",
	       prland(&land));
	    continue;
	}

	sect.sct_avail -= avail;
	land.lnd_effic -= UPGR_EFF;
	lnd_set_tech(&land, tlev);
	land.lnd_harden = 0;
	land.lnd_mission = 0;

	putland(land.lnd_uid, &land);
	putsect(&sect);
	player->dolcost += cost;
	pr("%s upgraded to tech %d, at a cost of %d\n",
	   prland(&land), land.lnd_tech, cost);
	if (land.lnd_own != player->cnum)
	    wu(0, land.lnd_own,
	       "%s upgraded by %s to tech %d, at a cost of %d\n",
	       prland(&land), cname(player->cnum), land.lnd_tech, cost);
    }
    if (n == 0) {
	pr("No land units\n");
	return RET_SYN;
    }
    return RET_OK;
}
示例#10
0
int
sona(void)
{
    struct nstr_item ni, nit;
    struct sctstr sect;
    struct shpstr ship;
    struct shpstr targ;
    struct natstr *natp;
    struct mchrstr *mcp;
    struct mchrstr *tmcp;
    struct nstr_sect ns;
    int range;
    int visib, pingrange;
    int srange;
    int vrange;
    int dist;
    int x, y;
    int cx, cy;
    int changed = 0;
    int row;
    /* Where these are used are non-re-entrant, so we keep 'em around */
    static char **rad = NULL;
    static char *radbuf = NULL;
    static signed char **vis = NULL;
    static signed char *visbuf = NULL;

    if (!snxtitem(&ni, EF_SHIP, player->argp[1], NULL))
	return RET_SYN;
    if (!radbuf)
	radbuf = malloc(WORLD_Y * MAPWIDTH(1));
    if (!visbuf)
	visbuf = malloc(WORLD_Y * MAPWIDTH(1));
    if (!rad && radbuf) {
	rad = malloc(WORLD_Y * sizeof(char *));
	if (rad) {
	    for (x = 0; x < WORLD_Y; x++) {
		rad[x] = &radbuf[(WORLD_X + 1) * x];
	    }
	}
    }
    if (!vis && visbuf) {
	vis = malloc(WORLD_Y * sizeof(signed char *));
	if (vis) {
	    for (x = 0; x < WORLD_Y; x++) {
		vis[x] = &visbuf[(WORLD_X + 1) * x];
	    }
	}
    }
    if (!radbuf || !visbuf || !rad || !vis) {
	pr("Memory error, tell the deity.\n");
	logerror("malloc failed in sona\n");
	return RET_FAIL;
    }
    while (nxtitem(&ni, &ship)) {
	if (!player->owner)
	    continue;
	mcp = &mchr[(int)ship.shp_type];
	if (!(mcp->m_flags & M_SONAR))
	    continue;
	getsect(ship.shp_x, ship.shp_y, &sect);
	if (sect.sct_type != SCT_WATER)
	    continue;
	range = (int)techfact(ship.shp_tech, mcp->m_vrnge);
	srange = MIN(7, 7 * range * ship.shp_effic / 200);
	pr("%s at %s efficiency %d%%, max range %d\n",
	   prship(&ship),
	   xyas(ship.shp_x, ship.shp_y, player->cnum),
	   ship.shp_effic, srange);
	snxtsct_dist(&ns, ship.shp_x, ship.shp_y, srange);
	blankfill(radbuf, &ns.range, 1);
	while (nxtsct(&ns, &sect)) {
	    if (player->owner || sect.sct_type == SCT_WATER)
		rad[ns.dy][ns.dx] = dchr[sect.sct_type].d_mnem;
	    else {
		rad[ns.dy][ns.dx] = '?';
	    }
	}
	snxtsct_dist(&ns, ship.shp_x, ship.shp_y, srange);
	cx = deltx(&ns.range, ship.shp_x);
	cy = delty(&ns.range, ship.shp_y);
	while (nxtsct(&ns, &sect)) {
	    if (!line_of_sight(rad, cx, cy, ns.dx, ns.dy)) {
		rad[ns.dy][ns.dx] = ' ';
		continue;
	    }
	    if (ship.shp_tech >= 310 && sect.sct_type == SCT_WATER) {
		if (sect.sct_mines) {
		    pr("Sonar detects %d mines in %s!\n",
		       sect.sct_mines,
		       xyas(sect.sct_x, sect.sct_y, player->cnum));
		    rad[ns.dy][ns.dx] = 'X';
		}
	    }
	    changed |= map_set(player->cnum, sect.sct_x, sect.sct_y,
			       rad[ns.dy][ns.dx], 0);

	}
	memset(visbuf, 0, (WORLD_Y * (WORLD_X + 1)));
	snxtitem_dist(&nit, EF_SHIP, ship.shp_x, ship.shp_y, range);
	while (nxtitem(&nit, &targ)) {
	    if (targ.shp_own == player->cnum || targ.shp_own == 0)
		continue;
	    tmcp = &mchr[(int)targ.shp_type];
	    visib = shp_visib(&targ);
	    pingrange = MIN(7, MAX(visib, 10) * range / 10);
	    vrange = pingrange * ship.shp_effic / 200;
	    dist = mapdist(targ.shp_x, targ.shp_y, ship.shp_x, ship.shp_y);
	    pingrange = (MAX(pingrange, 2) * targ.shp_effic) / 100;
	    if (dist > pingrange)
		continue;
	    if (tmcp->m_flags & M_SONAR && targ.shp_own) {
		natp = getnatp(targ.shp_own);
		if (natp->nat_flags & NF_SONAR)
		    wu(0, targ.shp_own,
		       "Sonar ping from %s detected by %s!\n",
		       xyas(ship.shp_x, ship.shp_y,
			    targ.shp_own), prship(&targ));
		if (targ.shp_rflags & RET_SONARED)
		    retreat_ship(&targ, targ.shp_own, 's');
	    }
	    if (dist > vrange)
		continue;
	    x = deltx(&ns.range, (int)targ.shp_x);
	    y = delty(&ns.range, (int)targ.shp_y);
	    if (rad[y][x] != dchr[SCT_WATER].d_mnem && rad[y][x] != 'X')
		continue;
	    if (tmcp->m_flags & M_SUB &&
		relations_with(targ.shp_own, player->cnum) < FRIENDLY) {
		if (mcp->m_vrnge + visib < 8)
		    pr("Sonar detects sub #%d @ %s\n",
		       targ.shp_uid,
		       xyas(targ.shp_x, targ.shp_y, player->cnum));
		else if (mcp->m_vrnge + visib < 10)
		    pr("Sonar detects %s @ %s\n",
		       prship(&targ),
		       xyas(targ.shp_x, targ.shp_y, player->cnum));
		else
		    pr("Sonar detects %s %s @ %s\n",
		       cname(targ.shp_own), prship(&targ),
		       xyas(targ.shp_x, targ.shp_y, player->cnum));
	    } else
		pr("Sonar detects %s %s @ %s\n",
		   cname(targ.shp_own), prship(&targ),
		   xyas(targ.shp_x, targ.shp_y, player->cnum));

	    if (visib > vis[y][x]) {
		vis[y][x] = visib;
		/* &~0x20 makes it a cap letter */
		rad[y][x] = (*mchr[(int)targ.shp_type].m_name) & ~0x20;
	    }
	}
	if (!player->argp[2]) {
	    rad[cy][cx] = '0';
	    for (row = 0; row < ns.range.height; row++)
		if (!blankrow(rad[row]))
		    pr("%s\n", rad[row]);
	}
	pr("\n");

    }
    if (changed)
	writemap(player->cnum);
    return RET_OK;
}
示例#11
0
int
load(void)
{
    int noisy;
    int load_unload;
    int type;
    struct nstr_item nbst;
    struct ichrstr *ich;
    int nships;
    struct sctstr sect;
    struct shpstr ship;
    int retval;
    char *p;
    char buf[1024];

    p = getstarg(player->argp[1],
		 "What commodity (or 'plane' or 'land')? ", buf);
    if (!p || !*p)
	return RET_SYN;

    if (!strncmp(p, "plane", 5))
	type = EF_PLANE;
    else if (!strncmp(p, "land", 4))
	type = EF_LAND;
    else if (NULL != (ich = item_by_name(p)))
	type = EF_SECTOR;
    else {
	pr("Can't load '%s'\n", p);
	return RET_SYN;
    }

    p = getstarg(player->argp[2], "Ship(s): ", buf);
    if (!p || !*p)
	return RET_SYN;

    noisy = isdigit(*p);

    if (!snxtitem(&nbst, EF_SHIP, p, NULL))
	return RET_SYN;

    load_unload = **player->argp == 'l' ? LOAD : UNLOAD;

    nships = 0;
    while (nxtitem(&nbst, &ship)) {
	if (!ship.shp_own)
	    continue;
	if (!player->owner) {
	    if (load_unload == UNLOAD || !noisy)
		continue;
	    if (relations_with(ship.shp_own, player->cnum) < FRIENDLY)
		continue;
	}

	if (!getsect(ship.shp_x, ship.shp_y, &sect))	/* XXX */
	    continue;
	if (!sect.sct_own)
	    continue;
	if (!player->owner) {
	    if (ship.shp_own != player->cnum)
		continue;
	    if (!sect_has_dock(&sect))
		continue;
	    if (load_unload == LOAD) {
		if (noisy)
		    pr("You don't own %s\n",
		       xyas(sect.sct_x, sect.sct_y, player->cnum));
		continue;
	    }
	}
	if (!sect_has_dock(&sect)) {
	    if (noisy)
		pr("Sector %s is not a harbor or canal.\n",
		   xyas(sect.sct_x, sect.sct_y, player->cnum));
	    continue;
	}
	if (load_unload == UNLOAD
	    && !player->owner
	    && relations_with(sect.sct_own, player->cnum) < FRIENDLY) {
	    if (noisy)
		pr("You can't unload into an unfriendly %s\n",
		   dchr[sect.sct_type].d_name);
	    continue;
	}
	if (sect.sct_effic < 2) {
	    if (noisy)
		pr("The %s at %s is not 2%% efficient yet.\n",
		   dchr[sect.sct_type].d_name,
		   xyas(sect.sct_x, sect.sct_y, player->cnum));
	    continue;
	}

	if (opt_MARKET) {
	    if (ontradingblock(EF_SHIP, &ship)) {
		pr("You cannot load/unload an item on the trading block!\n");
		continue;
	    }
	}

	switch (type) {
	case EF_PLANE:
	    retval = load_plane_ship(&sect, &ship, noisy, load_unload,
				     &nships);
	    if (retval != 0)
		return retval;
	    break;
	case EF_LAND:
	    retval = load_land_ship(&sect, &ship, noisy, load_unload,
				    &nships);
	    if (retval != 0)
		return retval;
	    break;
	case EF_SECTOR:
	    retval = load_comm_ship(&sect, &ship, ich, load_unload,
				    &nships);
	    if (retval != 0)
		return retval;
	}
	/* load/unload plague */
	if (sect.sct_pstage == PLG_INFECT
	    && ship.shp_pstage == PLG_HEALTHY)
	    ship.shp_pstage = PLG_EXPOSED;
	if (ship.shp_pstage == PLG_INFECT
	    && sect.sct_pstage == PLG_HEALTHY)
	    sect.sct_pstage = PLG_EXPOSED;
	putsect(&sect);
	putship(ship.shp_uid, &ship);
    }
    if (!nships)
	pr("No ships affected\n");
    else
	pr("%d ship%s %sloaded\n", nships, splur(nships),
	   load_unload == UNLOAD ? "un" : "");
    return RET_OK;
}
示例#12
0
int
pln_airbase_ok(struct plnstr *pp, int oneway, int noisy)
{
    struct shpstr ship;
    struct lndstr land;
    struct sctstr sect;
    struct plchrstr *pcp = plchr + pp->pln_type;

    if (CANT_HAPPEN(noisy && pp->pln_own != player->cnum))
	noisy = 0;

    if (pp->pln_ship >= 0) {
	/* ship: needs to be own or allied, efficient */
	if (!getship(pp->pln_ship, &ship)) {
	    CANT_REACH();
	    return 0;
	}
	if (relations_with(ship.shp_own, pp->pln_own) != ALLIED) {
	    if (noisy)
		pr("(note) An ally does not own the ship %s is on\n",
		   prplane(pp));
	    return 0;
	}
	if (!(carrier_planes(&ship, pcp->pl_flags & P_M) & pcp->pl_flags))
	    return 0;

    } else if (pp->pln_land >= 0) {
	/* land: needs to be own or allied, efficient, not embarked */
	if (!getland(pp->pln_land, &land)) {
	    CANT_REACH();
	    return 0;
	}
	if (relations_with(land.lnd_own, pp->pln_own) != ALLIED) {
	    if (noisy)
		pr("(note) An ally does not own the unit %s is on\n",
		   prplane(pp));
	    return 0;
	}
	if (land.lnd_effic < LND_AIROPS_EFF || !(pcp->pl_flags & P_E))
	    return 0;
	if (land.lnd_ship >= 0 || land.lnd_land >= 0)
	    return 0;

    } else {
	/* sector: needs to be own or allied, efficient airfield */
	if (!getsect(pp->pln_x, pp->pln_y, &sect)) {
	    CANT_REACH();
	    return 0;
	}

	if (relations_with(sect.sct_own, pp->pln_own) != ALLIED) {
	    if (noisy)
		pr("(note) An ally does not own the sector %s is in\n",
		   prplane(pp));
	    return 0;
	}
	/* need airfield unless VTOL */
	if ((pcp->pl_flags & P_V) == 0) {
	    if (sect.sct_type != SCT_AIRPT) {
		if (noisy)
		    pr("%s not at airport\n", prplane(pp));
		return 0;
	    }
	    if (sect.sct_effic < 40) {
		if (noisy)
		    pr("%s is not 40%% efficient, %s can't take off from there.\n",
		       xyas(sect.sct_x, sect.sct_y, player->cnum),
		       prplane(pp));
		return 0;
	    }
	    if (!oneway && sect.sct_effic < 60) {
		if (noisy)
		    pr("%s is not 60%% efficient, %s can't land there.\n",
		       xyas(sect.sct_x, sect.sct_y, player->cnum),
		       prplane(pp));
		return 0;
	    }
	}
    }

    return 1;
}
示例#13
0
void
pln_dropoff(struct emp_qelem *list, struct ichrstr *ip, coord tx, coord ty,
	    int cno)
{
    struct emp_qelem *qp;
    struct plist *plp;
    int amt;
    struct sctstr sect;
    struct shpstr ship;
    int there;
    int max;
    int pstage;

    if (!ip)
	return;
    if (cno < 0) {
	getsect(tx, ty, &sect);
	if (!sect.sct_own) {
	    if (sect.sct_type == SCT_WATER)
		pr("Your %s sink like a rock!\n", ip->i_name);
	    else
		pr("Your %s vanish without a trace.\n", ip->i_name);
	    return;
	}
	if (relations_with(sect.sct_own, player->cnum) != ALLIED) {
	    pr("You don't own %s!  Cargo jettisoned...\n",
	       xyas(tx, ty, player->cnum));
	    return;
	}
	if (ip->i_uid == I_CIVIL && sect.sct_own != sect.sct_oldown) {
	    pr("%s is occupied.  Your civilians suffer from identity crisis and die.\n",
	       xyas(tx, ty, player->cnum));
	    return;
	}
	there = sect.sct_item[ip->i_uid];
	max = ITEM_MAX;
	pstage = sect.sct_pstage;
    } else {
	getship(cno, &ship);
	there = ship.shp_item[ip->i_uid];
	max = mchr[ship.shp_type].m_item[ip->i_uid];
	pstage = ship.shp_pstage;
    }

    amt = 0;
    for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
	plp = (struct plist *)qp;
	amt += plp->load;
	if (plp->load
	    && plp->pstage == PLG_INFECT && pstage == PLG_HEALTHY)
	    pstage = PLG_EXPOSED;
    }

    there += amt;
    if (there > max) {
	pr("%d excess %s discarded\n", there - max, ip->i_name);
	amt -= there - max;
	there = max;
    }
    pr("%d %s landed safely", amt, ip->i_name);
    if (cno < 0) {
	sect.sct_item[ip->i_uid] = there;
	sect.sct_pstage = pstage;
	if (sect.sct_own != player->cnum)
	    wu(0, sect.sct_own, "%s planes drop %d %s in %s\n",
	       cname(player->cnum), amt, ip->i_name,
	       xyas(tx, ty, sect.sct_own));
	pr(" at %s\n", xyas(tx, ty, player->cnum));
	putsect(&sect);
    } else {
	ship.shp_item[ip->i_uid] = there;
	ship.shp_pstage = pstage;
	if (ship.shp_own != player->cnum)
	    wu(0, ship.shp_own, "%s planes land %d %s on carrier %d\n",
	       cname(player->cnum), amt, ip->i_name, ship.shp_uid);
	pr(" on carrier #%d\n", ship.shp_uid);
	putship(ship.shp_uid, &ship);
    }
}
示例#14
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;
}
示例#15
0
文件: foll.c 项目: fstltna/empserver
int
foll(void)
{
    struct shpstr ship;
    char *cp;
    int good, leader, count = 0;
    coord x, y;
    struct nstr_item nstr;
    char buf[1024];

    if (!opt_SAIL) {
	pr("The SAIL option is not enabled, so this command is not valid.\n");
	return RET_FAIL;
    }
    if (!snxtitem(&nstr, EF_SHIP, player->argp[1], NULL))
	return RET_SYN;
    cp = getstarg(player->argp[2], "leader? ", buf);
    if (!cp)
	cp = "";
    good = sscanf(cp, "%d", &leader);
    if (!good)
	return RET_SYN;
    getship(leader, &ship);
    if (relations_with(ship.shp_own, player->cnum) < FRIENDLY) {
	pr("That ship won't let you follow.\n");
	return RET_FAIL;
    }
    x = ship.shp_x;
    y = ship.shp_y;
    while (nxtitem(&nstr, &ship)) {
	if (!player->owner)
	    continue;
	if (ship.shp_x != x || ship.shp_y != y) {
	    pr("Ship #%d not in same sector as #%d\n",
	       ship.shp_uid, leader);
	    continue;
	}
	if (ship.shp_uid == leader) {
	    pr("Ship #%d can't follow itself!\n", leader);
	    continue;
	}
	if ((ship.shp_autonav & AN_AUTONAV)
	    && !(ship.shp_autonav & AN_STANDBY)) {
	    pr("Ship #%d has other orders!\n", ship.shp_uid);
	    continue;
	}
	count++;
	ship.shp_mission = 0;
	*ship.shp_path = 'f';
	ship.shp_path[1] = 0;
	ship.shp_follow = leader;
	pr("Ship #%d follows #%d.\n", ship.shp_uid, leader);
	putship(ship.shp_uid, &ship);
    }
    if (count == 0) {
	if (player->argp[1])
	    pr("%s: No ship(s)\n", player->argp[1]);
	else
	    pr("%s: No ship(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d ship%s\n", count, splur(count));
    return RET_OK;
}
示例#16
0
void
setrel(natid us, natid them, int rel)
{
    struct natstr *mynp = getnatp(us);
    struct natstr *themnp = getnatp(them);
    int oldrel;
    char *whichway;
    int n_up = 0;
    int n_down = 0;
    char *addendum = NULL;

    if (CANT_HAPPEN(rel < AT_WAR))
	rel = AT_WAR;
    if (CANT_HAPPEN(rel > ALLIED))
	rel = ALLIED;
    if (CANT_HAPPEN(!mynp || !themnp))
	return;
    if (us == them)
	return;
    oldrel = relations_with(us, them);
    if (oldrel == rel)
	return;
    if (rel > oldrel)
	whichway = "upgraded";
    else
	whichway = "downgraded";
    if (rel == ALLIED) {
	addendum = "Congratulations!";
	n_up = N_DECL_ALLY;
    } else if (rel == FRIENDLY) {
	n_up = N_UP_FRIENDLY;
	n_down = N_DOWN_FRIENDLY;
    } else if (rel == NEUTRAL) {
	n_up = N_UP_NEUTRAL;
	n_down = N_DOWN_NEUTRAL;
    } else if (rel == HOSTILE) {
	addendum = "Another cold war...";
	n_up = N_UP_HOSTILE;
	n_down = N_DOWN_HOSTILE;
    } else if (rel < HOSTILE) {
	addendum = "Declaration made (give 'em hell).";
	n_down = N_DECL_WAR;
    }

    if (addendum && us == player->cnum && !update_running)
	pr("%s\n", addendum);
    mpr(us, "Diplomatic relations with %s %s to \"%s\".\n",
	cname(them), whichway, relates[rel]);
    if (!(getrejects(us, themnp) & REJ_TELE))
	mpr(them,
	    "Country %s has %s their relations with you to \"%s\"!\n",
	    prnat(mynp), whichway, relates[rel]);

    putrel(mynp, them, rel);
    putnat(mynp);

    if (!player->god) {
	if (oldrel == ALLIED)
	    nreport(us, N_DIS_ALLY, them, 1);
	else if (oldrel < HOSTILE && rel >= HOSTILE)
	    nreport(us, N_DIS_WAR, them, 1);
	if (rel > oldrel)
	    nreport(us, n_up, them, 1);
	else
	    nreport(us, n_down, them, 1);
    }
    if (opt_HIDDEN)
	setcont(them, us, FOUND_TELE);
}
示例#17
0
int
lload(void)
{
    int noisy;
    int load_unload;
    int type;
    struct nstr_item nbst;
    struct ichrstr *ich;
    int nunits;
    struct sctstr sect;
    struct lndstr land;
    int retval;
    char *p;
    char buf[1024];

    p = getstarg(player->argp[1],
		 "What commodity (or 'plane' or 'land')? ", buf);
    if (!p || !*p)
	return RET_SYN;
    if (!strncmp(p, "plane", 5))
	type = EF_PLANE;
    else if (!strncmp(p, "land", 4))
	type = EF_LAND;
    else if (NULL != (ich = item_by_name(p)))
	type = EF_SECTOR;
    else {
	pr("Can't load '%s'\n", p);
	return RET_SYN;
    }

    p = getstarg(player->argp[2], "Unit(s): ", buf);
    if (!p || !*p)
	return RET_SYN;

    noisy = isdigit(*p);

    if (!snxtitem(&nbst, EF_LAND, p, NULL))
	return RET_SYN;

    load_unload = player->argp[0][1] == 'l' ? LOAD : UNLOAD;

    nunits = 0;
    while (nxtitem(&nbst, &land)) {
	if (land.lnd_own == 0)
	    continue;
	if (!player->owner) {
	    if (load_unload == UNLOAD || !noisy)
		continue;
	    if (relations_with(land.lnd_own, player->cnum) != ALLIED)
		continue;
	}

	if (!getsect(land.lnd_x, land.lnd_y, &sect))	/* XXX */
	    continue;
	if (!player->owner) {
	    if (land.lnd_own != player->cnum)
		continue;
	    if (load_unload == LOAD) {
		if (noisy)
		    pr("Sector %s is not yours.\n",
		       xyas(sect.sct_x, sect.sct_y, player->cnum));
		continue;
	    }
	    if (relations_with(sect.sct_own, player->cnum) != ALLIED) {
		pr("Sector %s is not yours.\n",
		   xyas(sect.sct_x, sect.sct_y, player->cnum));
		continue;
	    }
	}

	if (opt_MARKET) {
	    if (ontradingblock(EF_LAND, &land)) {
		pr("You cannot load/unload an item on the trading block!\n");
		continue;
	    }
	}

	switch (type) {
	case EF_LAND:
	    retval = load_land_land(&sect, &land, noisy, load_unload,
				    &nunits);
	    if (retval != 0)
		return retval;
	    break;
	case EF_PLANE:
	    retval = load_plane_land(&sect, &land, noisy, load_unload,
				     &nunits);
	    if (retval != 0)
		return retval;
	    break;
	case EF_SECTOR:
	    retval = load_comm_land(&sect, &land, ich, load_unload,
				    &nunits);
	    if (retval != 0)
		return retval;
	}
	/* load/unload plague */
	if (sect.sct_pstage == PLG_INFECT
	    && land.lnd_pstage == PLG_HEALTHY)
	    land.lnd_pstage = PLG_EXPOSED;
	if (land.lnd_pstage == PLG_INFECT
	    && sect.sct_pstage == PLG_HEALTHY)
	    sect.sct_pstage = PLG_EXPOSED;

	putsect(&sect);
	putland(land.lnd_uid, &land);
    }
    if (nunits == 0)
	pr("No units affected\n");
    else
	pr("%d unit%s %sloaded\n", nunits, splur(nunits),
	   load_unload == UNLOAD ? "un" : "");
    return RET_OK;
}
示例#18
0
static int
supgr(void)
{
    struct sctstr sect;
    struct natstr *natp;
    struct nstr_item ni;
    struct shpstr ship;
    struct mchrstr *mp;
    int n;
    int tlev;
    int avail, cost;
    int cash;

    if (!snxtitem(&ni, EF_SHIP, player->argp[2], NULL))
	return RET_SYN;
    natp = getnatp(player->cnum);
    cash = natp->nat_money;
    tlev = (int)natp->nat_level[NAT_TLEV];
    n = 0;
    while (nxtitem(&ni, &ship)) {
	if (ship.shp_own == 0)
	    continue;
	getsect(ship.shp_x, ship.shp_y, &sect);
	if (sect.sct_own != player->cnum)
	    continue;
	if (sect.sct_type != SCT_HARBR || sect.sct_effic < 60)
	    continue;
	if (relations_with(ship.shp_own, sect.sct_own) < FRIENDLY) {
	    pr("You are not on friendly terms with the owner of ship %d!\n",
	       ship.shp_uid);
	    continue;
	}
	n++;
	mp = &mchr[(int)ship.shp_type];
	avail = (SHP_BLD_WORK(mp->m_lcm, mp->m_hcm) * UPGR_COST + 99) / 100;
	if (sect.sct_avail < avail) {
	    pr("Not enough available work in %s to upgrade a %s\n",
	       xyas(sect.sct_x, sect.sct_y, player->cnum), mp->m_name);
	    pr(" (%d available work required)\n", avail);
	    continue;
	}
	if (ship.shp_effic < 60) {
	    pr("%s is too damaged to upgrade!\n", prship(&ship));
	    continue;
	}
	if (ship.shp_tech >= tlev) {
	    pr("%s tech: %d, yours is only %d\n",
	       prship(&ship), ship.shp_tech, tlev);
	    continue;
	}
	cost = mp->m_cost * UPGR_COST / 100;
	if (cost + player->dolcost > cash) {
	    pr("You don't have enough money to upgrade %s!\n",
	       prship(&ship));
	    continue;
	}

	sect.sct_avail -= avail;
	ship.shp_effic -= UPGR_EFF;
	shp_set_tech(&ship, tlev);
	ship.shp_mission = 0;

	putship(ship.shp_uid, &ship);
	putsect(&sect);
	player->dolcost += cost;
	pr("%s upgraded to tech %d, at a cost of %d\n",
	   prship(&ship), ship.shp_tech, cost);
	if (ship.shp_own != player->cnum)
	    wu(0, ship.shp_own,
	       "%s upgraded by %s to tech %d, at a cost of %d\n",
	       prship(&ship), cname(player->cnum), ship.shp_tech, cost);
    }
    if (n == 0) {
	pr("No ships\n");
	return RET_SYN;
    }
    return RET_OK;
}
示例#19
0
void
plane_sona(struct emp_qelem *plane_list, int x, int y,
	   struct shiplist **head)
{
    struct plnstr *pp;
    struct plchrstr *pcp;
    struct mchrstr *tmcp;
    struct shpstr *targ, s;
    struct natstr *natp;
    struct emp_qelem *qp;
    struct emp_qelem *next;
    struct plist *ip;
    struct sctstr sect;
    int found = 0;
    int range, i, vis;
    int pingrange;
    int vrange;
    int dist;

    getsect(x, y, &sect);
    if ((sect.sct_type != SCT_WATER) && (sect.sct_type != SCT_HARBR))
	return;
    for (qp = plane_list->q_forw; qp != plane_list; qp = next) {
	next = qp->q_forw;
	ip = (struct plist *)qp;
	pp = &ip->plane;
	pcp = ip->pcp;
	if (!(pcp->pl_flags & P_A))	/* if it isn't an ASW plane */
	    continue;
	range = (int)techfact(pp->pln_tech, (100.0 - pln_acc(pp)) / 10.0);
	for (i = 0; getship(i, &s); i++) {
	    targ = &s;
	    if (targ->shp_own == pp->pln_own || targ->shp_own == 0)
		continue;
	    if (on_shiplist(targ->shp_uid, *head))
		continue;
	    tmcp = &mchr[(int)targ->shp_type];
	    if (!(tmcp->m_flags & M_SUB))
		continue;
	    if (!pct_chance(pln_identchance(pp, shp_hardtarget(targ),
					    EF_SHIP)))
		continue;
	    vis = shp_visib(targ);
	    pingrange = MAX(vis, 10) * range / 10;
	    vrange = pingrange * (pp->pln_effic / 200.0);
	    dist = mapdist(targ->shp_x, targ->shp_y, x, y);
	    pingrange = (MAX(pingrange, 2) * targ->shp_effic);
	    pingrange = roundavg(pingrange / 100.0);
	    if (dist > pingrange)
		continue;
	    if (tmcp->m_flags & M_SONAR && targ->shp_own) {
		natp = getnatp(targ->shp_own);
		if (natp->nat_flags & NF_SONAR)
		    wu(0, targ->shp_own,
		       "Sonar ping from %s detected by %s!\n",
		       xyas(x, y, targ->shp_own), prship(targ));
	    }
	    if ((dist > vrange))
		continue;
	    add_shiplist(targ->shp_uid, head);
	    if (!found) {
		pr("Sonar contact in %s\n", xyas(x, y, player->cnum));
		found = 1;
	    }
	    if (relations_with(targ->shp_own, pp->pln_own) < FRIENDLY &&
		!pct_chance(pln_identchance(pp, shp_hardtarget(targ),
					    EF_SHIP)))
		if (!pct_chance(pln_identchance(pp, shp_hardtarget(targ),
						EF_SHIP)))
		    pr("sub #%d %s\n", targ->shp_uid,
		       xyas(targ->shp_x, targ->shp_y, player->cnum));
		else
		    pr("%s %s\n", prship(targ),
		       xyas(targ->shp_x, targ->shp_y, player->cnum));
	    else
		pr("%s %s @ %s\n", cname(targ->shp_own), prship(targ),
		   xyas(targ->shp_x, targ->shp_y, player->cnum));
	}
    }
    if (found)
	pr("\n");
}
示例#20
0
static int
pupgr(void)
{
    struct sctstr sect;
    struct natstr *natp;
    struct nstr_item ni;
    struct plnstr plane;
    struct plchrstr *pp;
    int n;
    int tlev;
    int avail, cost;
    int cash;

    if (!snxtitem(&ni, EF_PLANE, player->argp[2], NULL))
	return RET_SYN;
    natp = getnatp(player->cnum);
    cash = natp->nat_money;
    tlev = (int)natp->nat_level[NAT_TLEV];
    n = 0;
    while (nxtitem(&ni, &plane)) {
	if (plane.pln_own == 0)
	    continue;
	getsect(plane.pln_x, plane.pln_y, &sect);
	if (sect.sct_own != player->cnum)
	    continue;
	if (sect.sct_type != SCT_AIRPT || sect.sct_effic < 60)
	    continue;
	if (relations_with(plane.pln_own, sect.sct_own) < FRIENDLY) {
	    pr("You are not on friendly terms with the owner of plane %d!\n",
	       plane.pln_uid);
	    continue;
	}
	if (pln_is_in_orbit(&plane)) {
	    pr("Plane %s is in orbit!\n", prplane(&plane));
	    continue;
	}
	if (plane.pln_flags & PLN_LAUNCHED)
	    continue;
	n++;
	pp = &plchr[(int)plane.pln_type];
	avail = (PLN_BLD_WORK(pp->pl_lcm, pp->pl_hcm) * UPGR_COST + 99) / 100;
	if (sect.sct_avail < avail) {
	    pr("Not enough available work in %s to upgrade a %s\n",
	       xyas(sect.sct_x, sect.sct_y, player->cnum), pp->pl_name);
	    pr(" (%d available work required)\n", avail);
	    continue;
	}
	if (plane.pln_effic < 60) {
	    pr("%s is too damaged to upgrade!\n", prplane(&plane));
	    continue;
	}
	if (plane.pln_tech >= tlev) {
	    pr("%s tech: %d, yours is only %d\n",
	       prplane(&plane), plane.pln_tech, tlev);
	    continue;
	}
	cost = pp->pl_cost * UPGR_COST / 100;
	if (cost + player->dolcost > cash) {
	    pr("You don't have enough money to upgrade %s!\n",
	       prplane(&plane));
	    continue;
	}

	sect.sct_avail -= avail;
	plane.pln_effic -= UPGR_EFF;
	pln_set_tech(&plane, tlev);
	plane.pln_harden = 0;
	plane.pln_mission = 0;

	putplane(plane.pln_uid, &plane);
	putsect(&sect);
	player->dolcost += cost;
	pr("%s upgraded to tech %d, at a cost of %d\n",
	   prplane(&plane), plane.pln_tech, cost);
	if (plane.pln_own != player->cnum)
	    wu(0, plane.pln_own,
	       "%s upgraded by %s to tech %d, at a cost of %d\n",
	       prplane(&plane), cname(player->cnum), plane.pln_tech, cost);
    }
    if (n == 0) {
	pr("No planes.\n");
	return RET_SYN;
    }
    return RET_OK;
}
示例#21
0
static void
planerepair(struct plnstr *pp, struct natstr *np, struct bp *bp, int etus)
{
    int build;
    int mvec[I_MAX + 1];
    struct shpstr *carrier;
    struct plchrstr *pcp = &plchr[(int)pp->pln_type];
    struct sctstr *sp = getsectp(pp->pln_x, pp->pln_y);
    int delta;
    int mult;
    int avail;
    int w_p_eff;
    int used;

    carrier = NULL;
    if (pp->pln_ship >= 0) {
	if (pp->pln_effic >= 80)
	    return;
	carrier = getshipp(pp->pln_ship);
	if (CANT_HAPPEN(!carrier))
	    return;
	if (carrier->shp_off)
	    return;
	if (relations_with(carrier->shp_own, pp->pln_own) != ALLIED)
	    return;
    } else {
	if (relations_with(sp->sct_own, pp->pln_own) != ALLIED)
	    return;
    }

    if (sp->sct_off)
	return;
    mult = 1;
    if (np->nat_level[NAT_TLEV] < pp->pln_tech * 0.85)
	mult = 2;

    if (pp->pln_effic == 100)
	return;

    if (!player->simulation)
	avail = sp->sct_avail * 100;
    else
	avail = bp_get_avail(bp, sp) * 100;
    if (carrier)
	avail += etus * carrier->shp_item[I_MILIT] / 2;

    w_p_eff = PLN_BLD_WORK(pcp->pl_lcm, pcp->pl_hcm);
    delta = roundavg((double)avail / w_p_eff);
    if (delta <= 0)
	return;
    if (delta > (int)((float)etus * plane_grow_scale))
	delta = (int)((float)etus * plane_grow_scale);
    if (delta > 100 - pp->pln_effic)
	delta = 100 - pp->pln_effic;

    memset(mvec, 0, sizeof(mvec));
    mvec[I_MILIT] = pcp->pl_crew;
    mvec[I_LCM] = pcp->pl_lcm;
    mvec[I_HCM] = pcp->pl_hcm;
    build = get_materials(sp, bp, mvec, delta);

    if (carrier)
	build = delta;

    used = build * w_p_eff;
    /*
     * I didn't use roundavg here, because I want to
     * penalize the player with a large number of planes.
     */
    if (!player->simulation)
	avail = (sp->sct_avail * 100 - used) / 100;
    else
	avail = (bp_get_avail(bp, sp) * 100 - used) / 100;

    if (avail < 0)
	avail = 0;
    if (!player->simulation)
	sp->sct_avail = avail;
    else
	bp_put_avail(bp, sp, avail);

    if (sp->sct_type != SCT_AIRPT)
	build /= 3;
    if (carrier) {
	if ((pp->pln_effic + build) > 80)
	    build = 80 - pp->pln_effic;
    }

    np->nat_money -= mult * build * pcp->pl_cost / 100.0;

    if (!player->simulation)
	pp->pln_effic += (signed char)build;
}
示例#22
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;
}