Example #1
0
void
pln_mine(struct emp_qelem *list, coord tx, coord ty)
{
    struct emp_qelem *qp;
    struct plist *plp;
    int amt;
    struct sctstr sect;

    amt = 0;
    for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
	plp = (struct plist *)qp;
	amt += plp->load;

    }
    if (amt > 0) {
	getsect(tx, ty, &sect);
	if (sect.sct_type != SCT_WATER) {
	    pr("Your seamines have no effect here.\n");
	    return;
	}
	sect.sct_mines = MIN(sect.sct_mines + amt, MINES_MAX);
	pr("%d mines laid in %s.\n", amt, xyas(tx, ty, player->cnum));
	if (map_set(player->cnum, tx, ty, 'X', 0))
	    writemap(player->cnum);
	putsect(&sect);
    }
}
Example #2
0
void
bsanct(void)
{
    int count;
    struct sctstr s;
    struct nstr_sect nstr;

    if (player->god)
	return;
    count = 0;
    snxtsct_all(&nstr);
    while (nxtsct(&nstr, &s)) {
	if (!player->owner)
	    continue;
	if (s.sct_type != SCT_SANCT)
	    continue;
	pr("%s is no longer a sanctuary.\n",
	   xyas(s.sct_x, s.sct_y, player->cnum));
	if (s.sct_newtype == SCT_SANCT)
	    s.sct_newtype = SCT_CAPIT;
	s.sct_type = s.sct_newtype;
	game_tick_to_now(&s.sct_access);
	(void)putsect(&s);
	count++;
    }
    if (count > 0) {
	game_note_bsanct();
	nreport(player->cnum, N_BROKE_SANCT, 0, 1);
    }
}
Example #3
0
/*
 * threshold <COMM> <SECTS> <THRESH>
 */
int
thre(void)
{
    struct sctstr sect;
    struct nstr_sect nstr;
    int val;
    struct ichrstr *ip;
    char *p;
    int thresh;
    i_type type;
    char prompt[128];
    char buf[128];

    if (!(ip = whatitem(player->argp[1], "What commodity? ")))
	return RET_SYN;
    if (!snxtsct(&nstr, player->argp[2]))
	return RET_SYN;
    type = ip->i_uid;
    while (nxtsct(&nstr, &sect)) {
	if (!player->owner)
	    continue;
	val = sect.sct_dist[type];
	if (val > 0)
	    sprintf(prompt, "%s %s  old threshold %d new? ",
		    xyas(nstr.x, nstr.y, player->cnum),
		    dchr[sect.sct_type].d_name, val);
	else
	    sprintf(prompt, "%s %s  threshold? ",
		    xyas(nstr.x, nstr.y, player->cnum),
		    dchr[sect.sct_type].d_name);
	if (!(p = getstarg(player->argp[3], prompt, buf)))
	    return RET_FAIL;
	if (!*p)
	    continue;
	if (!check_sect_ok(&sect))
	    return RET_FAIL;
	thresh = atoi(p);
	if (thresh < 0)
	    return RET_FAIL;
	if (thresh > ITEM_MAX)
	    thresh = ITEM_MAX;
	if ((val > 0) && (val == thresh)) {
	    pr("%s threshold unchanged (left at %d)\n",
	       xyas(nstr.x, nstr.y, player->cnum), val);
	    continue;
	}
	if (val > 0 && player->argp[3] && *player->argp[3])
	    pr("%s old threshold %d\n",
	       xyas(nstr.x, nstr.y, player->cnum), val);
	sect.sct_dist[type] = thresh;
	putsect(&sect);
    }
    return RET_OK;
}
Example #4
0
static int
coastal_land_to_sea(coord x, coord y)
{
    int n;
    struct sctstr sect;

    for (n = 1; n <= 6; ++n) {	/* Directions */
	getsect(x + diroff[n][0], y + diroff[n][1], &sect);
	if (!sect.sct_coastal) {
	    sect.sct_coastal = 1;
	    putsect(&sect);
	}
    }

    return 1;
}
Example #5
0
static int
coastal_sea_to_land(coord x, coord y)
{
    int n, c;
    struct sctstr sect;

    for (n = 1; n <= 6; n++) {	/* Directions */
	getsect(x + diroff[n][0], y + diroff[n][1], &sect);
	c = update_coastal_flag(sect.sct_x, sect.sct_y, x, y);
	if (!sect.sct_coastal != !c) {
	    sect.sct_coastal = c;
	    putsect(&sect);
	}
    }

    return update_coastal_flag(x, y, x, y);
}
Example #6
0
int
wipe(void)
{
    struct sctstr sect;
    struct nstr_sect nstr;

    if (!snxtsct(&nstr, player->argp[1]))
	return RET_SYN;
    while (nxtsct(&nstr, &sect)) {
	if (!player->owner)
	    continue;
	memset(sect.sct_dist, 0, sizeof(sect.sct_dist));
	pr("Distribution thresholds wiped from %s\n",
	   xyas(nstr.x, nstr.y, player->cnum));
	putsect(&sect);
    }
    return RET_OK;
}
Example #7
0
void
bridgefall(struct sctstr *sp)
{
    int i;
    struct sctstr sect;
    int nx;
    int ny;

    for (i = 1; i <= 6; i++) {
	nx = sp->sct_x + diroff[i][0];
	ny = sp->sct_y + diroff[i][1];
	getsect(nx, ny, &sect);
	if (sect.sct_type == SCT_BSPAN
	    && !bridge_support_at(&sect, DIR_BACK(i))) {
	    knockdown(&sect);
	    putsect(&sect);
	}
    }
}
Example #8
0
void
plane_sweep(struct emp_qelem *plane_list, coord x, coord y)
{
    struct plnstr *pp;
    struct plchrstr *pcp;
    struct emp_qelem *qp;
    struct emp_qelem *next;
    struct plist *ip;
    struct sctstr sect;
    int mines_there;
    int found = 0;

    getsect(x, y, &sect);
    mines_there = sect.sct_mines;

    if (mines_there == 0)
	return;

    if (sect.sct_type != SCT_WATER)
	return;

    for (qp = plane_list->q_forw; ((qp != plane_list) && (mines_there));
	 qp = next) {
	next = qp->q_forw;
	ip = (struct plist *)qp;
	pp = &ip->plane;
	pcp = ip->pcp;
	if (!(pcp->pl_flags & P_SWEEP))	/* if it isn't an sweep plane */
	    continue;

	if (chance((100.0 - pln_acc(pp)) / 100.0)) {
	    pr("Sweep! in %s\n",
	       xyas(sect.sct_x, sect.sct_y, player->cnum));
	    mines_there--;
	    found = 1;
	}
    }

    if (found && map_set(player->cnum, sect.sct_x, sect.sct_y, 'X', 0))
	writemap(player->cnum);
    sect.sct_mines = mines_there;
    putsect(&sect);
}
Example #9
0
static int
verify_sectors(int may_put)
{
    int i;
    struct sctstr *sp;
    coord x, y;

    /* laziness: assumes sector file is EFF_MEM */
    for (i = 0; (sp = getsectid(i)); i++) {
	sctoff2xy(&x, &y, sp->sct_uid);
	if (sp->sct_x != x || sp->sct_y != y) {
	    sp->sct_x = x;
	    sp->sct_y = y;
	    if (may_put)
		putsect(sp);
	    verify_fail(EF_SECTOR, i, NULL, 0, "bogus coordinates (fixed)");
	}
    }
    return 0;
}
Example #10
0
int
check_lmines(coord x, coord y, double weight)
{
    struct sctstr sect;
    int dam = 0;

    getsect(x, y, &sect);
    if (SCT_LANDMINES(&sect) > 0 &&
	sect.sct_oldown != player->cnum &&
	chance(DMINE_LHITCHANCE(sect.sct_mines)) && chance(weight / 100.0)) {
	pr_beep();
	pr("Blammo! Landmines detected! in %s  ",
	   xyas(sect.sct_x, sect.sct_y, player->cnum));
	dam = roll(20);
	--sect.sct_mines;
	putsect(&sect);
	pr("%d damage sustained.\n", dam);
    }
    return dam;
}
Example #11
0
void
bridgefall(struct sctstr *sp)
{
    int i;
    int j;
    struct sctstr sect;
    struct sctstr bh_sect;
    int nx;
    int ny;
    int nnx;
    int nny;

    if (CANT_HAPPEN(opt_EASY_BRIDGES))
	return;

    for (i = 1; i <= 6; i++) {
	nx = sp->sct_x + diroff[i][0];
	ny = sp->sct_y + diroff[i][1];
	getsect(nx, ny, &sect);
	if (sect.sct_type != SCT_BSPAN)
	    continue;
	for (j = 1; j <= 6; j++) {
	    nnx = nx + diroff[j][0];
	    nny = ny + diroff[j][1];
	    if (nnx == sp->sct_x && nny == sp->sct_y)
		continue;
	    getsect(nnx, nny, &bh_sect);
	    if (bh_sect.sct_type == SCT_BHEAD &&
		bh_sect.sct_newtype == SCT_BHEAD)
		break;
	    if (bh_sect.sct_type == SCT_BTOWER)
		break;
	}
	if (j > 6) {
	    knockdown(&sect);
	    putsect(&sect);
	}
    }
}
Example #12
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;
}
Example #13
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;
}
Example #14
0
int
sabo(void)
{
    struct nstr_item ni;
    struct lndstr land, tmp;
    struct sctstr sect;
    double odds;
    int dam;

    if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL))
	return RET_SYN;

    while (nxtitem(&ni, &land)) {
	if (!player->owner)
	    continue;
	if (!(lchr[(int)land.lnd_type].l_flags & L_SPY)) {
	    pr("%s is not a spy.\n", prland(&land));
	    continue;
	}
	if (land.lnd_ship >= 0) {
	    pr("%s is on ship %d.\n", prland(&land), land.lnd_ship);
	    continue;
	}
	if (land.lnd_land >= 0) {
	    pr("%s is on unit %d.\n", prland(&land), land.lnd_land);
	    continue;
	}
	if (!getsect(land.lnd_x, land.lnd_y, &sect))
	    continue;
	if (land.lnd_item[I_SHELL] == 0) {
	    pr("%s has no shells.\n", prland(&land));
	    continue;
	}

	odds = LND_SPY_DETECT_CHANCE(land.lnd_effic);
	if (chance(odds)) {
	    wu(0, sect.sct_own,
	       "%s spy shot in %s during sabotage attempt.\n",
	       cname(player->cnum),
	       xyas(sect.sct_x, sect.sct_y, sect.sct_own));
	    pr("%s was shot and killed.\n", prland(&land));
	    land.lnd_effic = 0;
	    putland(land.lnd_uid, &land);
	    continue;
	}

	dam = lnd_sabo(&land, sect.sct_item);
	if (dam < 0)
	    continue;

	pr("Explosion in %s causes %d damage.\n",
	   xyas(land.lnd_x, land.lnd_y, player->cnum), dam);
	if (sect.sct_own) {
	    wu(0, sect.sct_own,
	       "Sabotage in sector %s caused %d damage.\n",
	       xyas(sect.sct_x, sect.sct_y, sect.sct_own), dam);
	}

	/* hack: hide the spy so it don't gets blasted by sectdamage() */
	tmp = land;
	tmp.lnd_own = 0;
	putland(land.lnd_uid, &tmp);
	land.lnd_seqno = tmp.lnd_seqno;

	sectdamage(&sect, dam);
	putsect(&sect);

	if (chance(odds)) {
	    pr("%s dies in explosion.\n", prland(&land));
	    land.lnd_effic = 0;
	}
	putland(land.lnd_uid, &land);
    }
    return RET_OK;
}
Example #15
0
int
desi(void)
{
    int n;
    char *p;
    int des;
    struct nstr_sect nstr;
    struct sctstr sect;
    struct natstr *natp;
    char prompt[128];
    char buf[1024];
    int changed = 0;
    int rc = RET_OK;

    if (!snxtsct(&nstr, player->argp[1]))
	return RET_SYN;
    natp = getnatp(player->cnum);
    while (nxtsct(&nstr, &sect)) {
	if (!player->owner)
	    continue;
	if (!player->god && dchr[sect.sct_type].d_cost < 0)
	    continue;
	sprintf(prompt, "%s %d%% %s  desig? ",
		xyas(sect.sct_x, sect.sct_y, player->cnum),
		sect.sct_effic, dchr[sect.sct_type].d_name);
	if (!(p = getstarg(player->argp[2], prompt, buf))) {
	    rc = RET_FAIL;
	    break;
	}

	if (!check_sect_ok(&sect))
	    continue;

	des = sct_typematch(p);
	if (des < 0) {
	    pr("No such designation\n"
	       "See \"info Sector-types\" for possible designations\n");
	    rc = RET_FAIL;
	    break;
	}
	if (!player->god) {
	    if (des == SCT_WASTE) {
		pr("Only a nuclear device (or %s) can make a %s!\n",
		   cname(0), dchr[des].d_name);
		rc = RET_FAIL;
		break;
	    }
	    if (dchr[des].d_cost < 0) {
		pr("Only %s can designate a %s!\n",
		   cname(0), dchr[des].d_name);
		rc = RET_FAIL;
		break;
	    }
	    if (dchr[des].d_terrain != dchr[sect.sct_type].d_terrain) {
		pr("You can't change a %s into a %s\n",
		   dchr[sect.sct_type].d_name, dchr[des].d_name);
		continue;
	    }
	}
	if (sect.sct_type == des && sect.sct_newtype == des)
	    continue;
	if ((des == SCT_HARBR || des == SCT_BHEAD) && !sect.sct_coastal) {
	    pr("%s does not border on water.\n",
	       xyas(nstr.x, nstr.y, player->cnum));
	    if (player->god)
		pr("But if it's what you want ...\n");
	    else
		continue;
	}
	if (sect.sct_type == SCT_SANCT && !player->god)
	    continue;
	n = sect.sct_type;
	if ((sect.sct_newtype != des) && (sect.sct_type != des)
	    && dchr[des].d_cost > 0) {
	    if (natp->nat_money < player->dolcost + dchr[des].d_cost) {
		pr("You can't afford a %s!\n", dchr[des].d_name);
		rc = RET_FAIL;
		break;
	    }
	    player->dolcost += dchr[des].d_cost;
	}
	if (sect.sct_type != des && (sect.sct_effic < 5 || player->god)) {
	    if (player->god)
		set_coastal(&sect, sect.sct_type, des);
	    sect.sct_type = des;
	    sect.sct_effic = 0;
	    changed += map_set(player->cnum, sect.sct_x, sect.sct_y,
			       dchr[des].d_mnem, 0);
	}
	sect.sct_newtype = des;
	putsect(&sect);
	if (!player->god
	    && sect.sct_x == natp->nat_xcap && sect.sct_y == natp->nat_ycap
	    && des != SCT_CAPIT && des != SCT_SANCT && des != SCT_MOUNT)
	    pr("You have redesignated your capital!\n");
	if (opt_EASY_BRIDGES == 0) {	/* may cause a bridge fall */
	    if (n != SCT_BHEAD)
		continue;
	    bridgefall(&sect);
	}
    }
    if (changed)
	writemap(player->cnum);
    return rc;
}
Example #16
0
/*
 * Actually get the commod
 *
 * First, try to forage in the sector
 * Second look for a warehouse or headquarters to leech
 * Third, look for a ship we own in a harbor
 * Fourth, look for supplies in a supply unit we own
 *		(one good reason to do this last is that the supply
 *		 unit will then call resupply, taking more time)
 *
 * May want to put code to resupply with SAMs here, later --ts
 */
static int
s_commod(struct empobj *sink, short *vec,
	 i_type type, int wanted, int limit, int actually_doit)
{
    natid own = sink->own;
    coord x = sink->x;
    coord y = sink->y;
    int lookrange;
    struct sctstr sect;
    struct nstr_sect ns;
    struct nstr_item ni;
    struct lchrstr *lcp;
    struct shpstr ship;
    struct lndstr land;
    /* leave at least 1 military in sectors/ships */
    int minimum = 0;
    int can_move;
    double move_cost, weight, mobcost;
    int packing;
    struct dchrstr *dp;
    struct ichrstr *ip;

    if (wanted > limit)
	wanted = limit;
    if (wanted <= vec[type])
	return 1;
    wanted -= vec[type];

    /* try to get it from sector we're in */
    if (sink->ef_type != EF_SECTOR) {
	getsect(x, y, &sect);
	if (sect.sct_own == own) {
	    if (!opt_NOFOOD && type == I_FOOD)
		minimum = 1 + (int)ceil(food_needed(sect.sct_item,
						    etu_per_update));
	    if (sect.sct_item[type] - wanted >= minimum) {
		sect.sct_item[type] -= wanted;
		if (actually_doit) {
		    vec[type] += wanted;
		    putsect(&sect);
		    put_empobj(sink->ef_type, sink->uid, sink);
		}
		return 1;
	    } else if (sect.sct_item[type] - minimum > 0) {
		wanted -= sect.sct_item[type] - minimum;
		sect.sct_item[type] = minimum;
		if (actually_doit) {
		    vec[type] += sect.sct_item[type] - minimum;
		    putsect(&sect);
		}
	    }
	}
    }

    /* look for a headquarters or warehouse */
    lookrange = tfact(own, 10.0);
    snxtsct_dist(&ns, x, y, lookrange);
    while (nxtsct(&ns, &sect) && wanted) {
	if (ns.curdist == 0)
	    continue;
	if (sect.sct_own != own)
	    continue;
	if ((sect.sct_type != SCT_WAREH) &&
	    (sect.sct_type != SCT_HEADQ) && (sect.sct_type != SCT_HARBR))
	    continue;
	if ((sect.sct_type == SCT_HEADQ) &&
	    (sect.sct_dist_x == sect.sct_x) &&
	    (sect.sct_dist_y == sect.sct_y))
	    continue;
	if (sect.sct_effic < 60)
	    continue;
	move_cost = path_find(sect.sct_x, sect.sct_y, x, y, own, MOB_MOVE);
	if (move_cost < 0)
	    continue;
	if (!opt_NOFOOD && type == I_FOOD)
	    minimum = 1 + (int)ceil(food_needed(sect.sct_item,
						etu_per_update));
	if (sect.sct_item[type] <= minimum)
	    continue;
	ip = &ichr[type];
	dp = &dchr[sect.sct_type];
	packing = ip->i_pkg[dp->d_pkg];
	if (packing > 1 && sect.sct_effic < 60)
	    packing = 1;
	weight = (double)ip->i_lbs / packing;
	mobcost = move_cost * weight;
	if (mobcost > 0)
	    can_move = (double)sect.sct_mobil / mobcost;
	else
	    can_move = sect.sct_item[type] - minimum;
	if (can_move > sect.sct_item[type] - minimum)
	    can_move = sect.sct_item[type] - minimum;

	if (can_move >= wanted) {
	    int n;

	    sect.sct_item[type] -= wanted;

	    /* take off mobility for delivering sect */
	    n = roundavg(wanted * weight * move_cost);
	    sect.sct_mobil -= LIMIT_TO(n, 0, sect.sct_mobil);
	    if (actually_doit) {
		vec[type] += wanted;
		putsect(&sect);
		put_empobj(sink->ef_type, sink->uid, sink);
	    }
	    return 1;
	} else if (can_move > 0) {
	    int n;
	    wanted -= can_move;
	    sect.sct_item[type] -= can_move;

	    /* take off mobility for delivering sect */
	    n = roundavg(can_move * weight * move_cost);
	    sect.sct_mobil -= LIMIT_TO(n, 0, sect.sct_mobil);
	    if (actually_doit) {
		vec[type] += can_move;
		putsect(&sect);
	    }
	}
    }

    /* look for an owned ship in a harbor */
    snxtitem_dist(&ni, EF_SHIP, x, y, lookrange);
    while (nxtitem(&ni, &ship) && wanted) {
	if (sink->ef_type == EF_SHIP && sink->uid == ship.shp_uid)
	    continue;
	if (ship.shp_own != own)
	    continue;
	if (!(mchr[(int)ship.shp_type].m_flags & M_SUPPLY))
	    continue;
	getsect(ship.shp_x, ship.shp_y, &sect);
	if (sect.sct_type != SCT_HARBR)
	    continue;
	if (sect.sct_effic < 2)
	    continue;
	move_cost = path_find(sect.sct_x, sect.sct_y, x, y, own, MOB_MOVE);
	if (move_cost < 0)
	    continue;
	if (!opt_NOFOOD && type == I_FOOD)
	    minimum = 1 + (int)ceil(food_needed(ship.shp_item,
						etu_per_update));
	if (ship.shp_item[type] <= minimum)
	    continue;
	ip = &ichr[type];
	dp = &dchr[sect.sct_type];
	packing = ip->i_pkg[dp->d_pkg];
	if (packing > 1 && sect.sct_effic < 60)
	    packing = 1;
	weight = (double)ip->i_lbs / packing;
	mobcost = move_cost * weight;
	if (mobcost > 0)
	    can_move = (double)sect.sct_mobil / mobcost;
	else
	    can_move = ship.shp_item[type] - minimum;
	if (can_move > ship.shp_item[type] - minimum)
	    can_move = ship.shp_item[type] - minimum;
	if (can_move >= wanted) {
	    int n;
	    ship.shp_item[type] -= wanted;

	    n = roundavg(wanted * weight * move_cost);
	    sect.sct_mobil -= LIMIT_TO(n, 0, sect.sct_mobil);
	    if (actually_doit) {
		vec[type] += can_move;
		putship(ship.shp_uid, &ship);
		if (n)
		    putsect(&sect);
		put_empobj(sink->ef_type, sink->uid, sink);
	    }
	    return 1;
	} else if (can_move > 0) {
	    int n;
	    wanted -= can_move;
	    ship.shp_item[type] -= can_move;

	    n = roundavg(can_move * weight * move_cost);
	    sect.sct_mobil -= LIMIT_TO(n, 0, sect.sct_mobil);
	    if (actually_doit) {
		vec[type] += can_move;
		putship(ship.shp_uid, &ship);
		if (n)
		    putsect(&sect);
	    }
	}
    }

    /* look for an owned supply unit */
    snxtitem_dist(&ni, EF_LAND, x, y, lookrange);
    while (nxtitem(&ni, &land) && wanted) {
	int min;

	if (sink->ef_type == EF_LAND && sink->uid == land.lnd_uid)
	    continue;
	if (land.lnd_own != own)
	    continue;

	lcp = &lchr[(int)land.lnd_type];
	if (!(lcp->l_flags & L_SUPPLY))
	    continue;

	if (land.lnd_item[type] <= get_minimum(&land, type))
	    continue;

	if (land.lnd_ship >= 0) {
	    getsect(land.lnd_x, land.lnd_y, &sect);
	    if (sect.sct_type != SCT_HARBR || sect.sct_effic < 2)
		continue;
	}

	move_cost = path_find(land.lnd_x, land.lnd_y, x, y, own, MOB_MOVE);
	if (move_cost < 0)
	    continue;

#if 0
	/*
	 * Recursive supply is disabled for now.  It can introduce
	 * cycles into the "resupplies from" relation.  The code below
	 * attempts to break these cycles by temporarily zapping the
	 * commodity being supplied.  That puts the land file in a
	 * funny state temporarily, risking loss of supplies when
	 * something goes wrong on the way.  Worse, it increases
	 * lnd_seqno even when !actually_doit, which can lead to
	 * spurious seqno mismatch oopses in users of
	 * lnd_could_be_supplied().  I can't be bothered to clean up
	 * this mess right now, because recursive resupply is too dumb
	 * to be really useful anyway: each step uses the first source
	 * it finds, without consideration of mobility cost.  If you
	 * re-enable it, don't forget to uncomment its documentation
	 * in supply.t as well.
	 */
	if (land.lnd_item[type] - wanted < get_minimum(&land, type)) {
	    struct lndstr save;

	    /*
	     * Temporarily zap this unit's store, so the recursion
	     * avoids it.
	     */
	    save = land;
	    land.lnd_item[type] = 0;
	    putland(land.lnd_uid, &land);
	    save.lnd_seqno = land.lnd_seqno;

	    s_commod((struct empobj *)&land, land.lnd_item, type, wanted,
		     lchr[land.lnd_type].l_item[type] - wanted,
		     actually_doit);
	    land.lnd_item[type] += save.lnd_item[type];

	    if (actually_doit)
		putland(land.lnd_uid, &land);
	    else
		putland(save.lnd_uid, &save);
	}
#endif

	min = get_minimum(&land, type);
	ip = &ichr[type];
	weight = ip->i_lbs;
	mobcost = move_cost * weight;
	if (mobcost > 0)
	    can_move = (double)land.lnd_mobil / mobcost;
	else
	    can_move = land.lnd_item[type] - min;
	if (can_move > land.lnd_item[type] - min)
	    can_move = land.lnd_item[type] - min;

	if (can_move >= wanted) {
	    land.lnd_item[type] -= wanted;
	    land.lnd_mobil -= roundavg(wanted * weight * move_cost);
	    if (actually_doit) {
		vec[type] += wanted;
		putland(land.lnd_uid, &land);
		put_empobj(sink->ef_type, sink->uid, sink);
	    }
	    return 1;
	} else if (can_move > 0) {
	    wanted -= can_move;
	    land.lnd_item[type] -= can_move;
	    land.lnd_mobil -= roundavg(can_move * weight * move_cost);
	    if (actually_doit) {
		vec[type] += can_move;
		putland(land.lnd_uid, &land);
	    }
	}
    }

    if (actually_doit)
	put_empobj(sink->ef_type, sink->uid, sink);
    return 0;
}
Example #17
0
int
coll(void)
{
    int arg;
    time_t now;
    char *p;
    struct lonstr loan;
    struct sctstr sect;
    struct natstr *lonee_np;
    coord x, y;
    double owed;
    double pay;
    char buf[1024];

    if (!opt_LOANS) {
	pr("Loans are not enabled.\n");
	return RET_FAIL;
    }
    if ((arg = onearg(player->argp[1], "Collect on loan # ")) < 0)
	return RET_SYN;
    /* Check if it's a valid loan.  That means, is it a valid loan,
       owed to this player, with a valid duration and it's been signed. */
    if (!getloan(arg, &loan) || (loan.l_loner != player->cnum) ||
	(loan.l_ldur == 0) || (loan.l_status != LS_SIGNED)) {
	pr("You aren't owed anything on that loan...\n");
	return RET_FAIL;
    }
    /* If we got here, we check to see if it's been defaulted on.  We
       already know it's owed to this player. */
    owed = loan_owed(&loan, time(&now));
    if (now <= loan.l_duedate) {
	pr("There has been no default on loan %d\n", arg);
	return RET_FAIL;
    }

    lonee_np = getnatp(loan.l_lonee);
    pr("You are owed $%.2f on that loan.\n", owed);
    p = getstarg(player->argp[2],
		 "What sector do you wish to confiscate? ", buf);
    if (!p)
	return RET_SYN;
    if (!check_loan_ok(&loan))
	return RET_FAIL;
    if (!sarg_xy(p, &x, &y) || !getsect(x, y, &sect))
	return RET_SYN;
    if (!neigh(x, y, player->cnum)) {
	pr("You are not adjacent to %s\n", xyas(x, y, player->cnum));
	return RET_FAIL;
    }
    if (sect.sct_own != loan.l_lonee) {
	pr("%s is not owned by %s.\n",
	   xyas(x, y, player->cnum), cname(loan.l_lonee));
	return RET_FAIL;
    }
    pay = appraise_sect(&sect);
    if (pay > owed * 1.2) {
	pr("That sector (and its contents) is valued at more than %.2f.\n",
	   owed);
	return RET_FAIL;
    }
    if (!influx(lonee_np)
	&& sect.sct_x == lonee_np->nat_xcap
	&& sect.sct_y == lonee_np->nat_ycap) {
	pr("%s's capital cannot be confiscated.\n", cname(loan.l_lonee));
	return RET_FAIL;
    }
    pr("That sector (and its contents) is valued at $%.2f\n", pay);

    sect.sct_item[I_MILIT] = 1;	/* FIXME now where did this guy come from? */

    /*
     * Used to call takeover() here a long time ago, but that does
     * unwanted things, like generate che.
     */
    sect.sct_own = player->cnum;
    memset(sect.sct_dist, 0, sizeof(sect.sct_dist));
    memset(sect.sct_del, 0, sizeof(sect.sct_del));
    sect.sct_off = 1;
    sect.sct_dist_x = sect.sct_x;
    sect.sct_dist_y = sect.sct_y;
    putsect(&sect);
    nreport(player->cnum, N_SEIZE_SECT, loan.l_lonee, 1);
    owed = loan_owed(&loan, time(&now));
    if (pay >= owed) {
	loan.l_status = LS_FREE;
	loan.l_ldur = 0;
	nreport(loan.l_lonee, N_REPAY_LOAN, player->cnum, 1);
	wu(0, loan.l_lonee,
	   "%s seized %s to satisfy loan #%d\n",
	   cname(player->cnum),
	   xyas(sect.sct_x, sect.sct_y, loan.l_lonee), arg);
	pr("That loan is now considered repaid.\n");
    } else {
	(void)time(&loan.l_lastpay);
	owed -= pay;
	loan.l_amtdue = (int)owed;
	pay += loan.l_amtpaid;
	loan.l_amtpaid = (int)pay;
	wu(0, loan.l_lonee,
	   "%s seized %s in partial payment of loan %d.\n",
	   cname(player->cnum),
	   xyas(sect.sct_x, sect.sct_y, loan.l_lonee), arg);
	pr("You are still owed $%.2f on loan %d.\n", owed, arg);
    }
    putloan(arg, &loan);
    return RET_OK;
}
Example #18
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;
}
Example #19
0
int
check_market(void)
{
    struct comstr comm;
    struct sctstr *sect;
    struct natstr *natp;
    int m;
    int n;
    time_t now;
    double gain;
    double price;

    for (n = 0; getcomm(n, &comm); n++) {
	if (comm.com_maxbidder == comm.com_owner || comm.com_owner == 0)
	    continue;
	(void)time(&now);
	if (comm.com_markettime + MARK_DELAY > now)
	    continue;
	if (CANT_HAPPEN(comm.com_type <= I_NONE || comm.com_type > I_MAX))
	    continue;
	sect = getsectp(comm.com_x, comm.com_y);
	m = sect->sct_item[comm.com_type];

	price = comm.com_price * comm.com_amount * buytax;
	gain = comm.com_price * comm.com_amount;

	natp = getnatp(comm.com_maxbidder);
	if (natp->nat_money < price) {
	    nreport(comm.com_maxbidder, N_WELCH_DEAL, comm.com_owner, 1);
	    wu(0, comm.com_maxbidder,
	       "You didn't have enough cash to cover the cost.\n");
	    wu(0, comm.com_owner,
	       "Sale #%d fell through.  Goods remain on the market.\n", n);
	    comm.com_maxbidder = comm.com_owner;
	} else if (sect->sct_type != SCT_WAREH
		   && sect->sct_type != SCT_HARBR) {
	    wu(0, comm.com_maxbidder,
	       "Sector not a warehouse now, sale #%d fell though.\n", n);
	    wu(0, comm.com_owner,
	       "Sale #%d fell through.  Goods remain on the market.\n", n);
	    comm.com_maxbidder = comm.com_owner;
	} else if (m + comm.com_amount > ITEM_MAX) {
	    wu(0, comm.com_maxbidder,
	       "Warehouse full,  sale #%d fell though.\n", n);
	    wu(0, comm.com_owner,
	       "Sale #%d fell through.  Goods remain on the market.\n", n);
	    comm.com_maxbidder = comm.com_owner;
	} else {
	    sect->sct_item[comm.com_type] = m + comm.com_amount;
	    putsect(sect);
	    nreport(comm.com_owner, N_MAKE_SALE, comm.com_maxbidder, 1);
	    wu(0, comm.com_owner, "%s bought %d %s from you for $%.2f\n",
	       cname(comm.com_maxbidder), comm.com_amount,
	       ichr[comm.com_type].i_name, gain);
	    wu(0, comm.com_maxbidder,
	       "You just bought %d %s from %s for $%.2f\n",
	       comm.com_amount, ichr[comm.com_type].i_name,
	       cname(comm.com_owner), price);
	    natp->nat_money -= roundavg(price);
	    putnat(natp);
	    natp = getnatp(comm.com_owner);
	    natp->nat_money += roundavg(gain);
	    putnat(natp);
	    comm.com_owner = 0;
	}
	comm.com_owner = 0;
	putcomm(n, &comm);
    }
    return RET_OK;
}
Example #20
0
int
enli(void)
{
    struct nstr_sect nstr;
    struct sctstr sect;
    struct natstr *natp;
    int civ;
    int mil;
    int newmil;
    int milwant;
    int totalmil;
    int reserve;
    char *p;
    int quota;
    char prompt[128];
    char buf[1024];

    if (!snxtsct(&nstr, player->argp[1]))
	return RET_SYN;
    natp = getnatp(player->cnum);
    newmil = 500;
    sprintf(prompt, "Number to enlist (max %d) : ", newmil);
    if (!(p = getstarg(player->argp[2], prompt, buf)))
	return RET_SYN;
    if ((milwant = atoi(p)) > newmil)
	milwant = newmil;
    if (0 != (quota = (milwant < 0)))
	milwant = -milwant;
    totalmil = 0;
    reserve = natp->nat_reserve;
    if (reserve <= 0) {
	pr("No military reserves left\n");
	return RET_OK;
    }
    while (nxtsct(&nstr, &sect)) {
	if (!player->owner)
	    continue;
	if (sect.sct_oldown != player->cnum)
	    continue;
	civ = sect.sct_item[I_CIVIL];
	if (civ == 0)
	    continue;
	if (sect.sct_loyal > 70) {
	    pr("civilians refuse to report in %s!\n",
	       xyas(sect.sct_x, sect.sct_y, player->cnum));
	    continue;
	}
	if (sect.sct_mobil <= 0) {
	    pr("%s is out of mobility!\n",
	       xyas(sect.sct_x, sect.sct_y, player->cnum));
	}
	mil = sect.sct_item[I_MILIT];
	newmil = civ * 0.5;
	if (quota) {
	    if (newmil > milwant - mil)
		newmil = milwant - mil;
	    if (newmil > 500)
		newmil = 500;
	} else if (newmil > milwant)
	    newmil = milwant;
	if (newmil > 999 - mil)
	    newmil = 999 - mil;
	if (newmil <= 0)
	    continue;
	if (newmil > reserve)
	    newmil = reserve;
	sect.sct_item[I_MILIT] = newmil + mil;
	reserve -= newmil;
	totalmil += newmil;
	sect.sct_item[I_CIVIL] = civ - newmil;
	pr("%3d enlisted in %s (%d)\n", newmil,
	   xyas(sect.sct_x, sect.sct_y, player->cnum), mil + newmil);
	if (sect.sct_mobil > 0)
	    sect.sct_mobil *= 1.0 - (double)newmil / (double)civ;
	putsect(&sect);
	if (totalmil >= 10000) {
	    pr("Rioting in induction center interrupts enlistment\n");
	    break;
	}
	if (reserve == 0) {
	    pr("Military reserve exhausted\n");
	    break;
	}
    }
    pr("Total new enlistment : %d\n", totalmil);
    pr("Military reserves stand at %d\n", reserve);
    if (totalmil) {
	natp->nat_reserve -= totalmil;
	putnat(natp);
    }
    if ((player->btused += roundavg(totalmil * 0.02)) > 0)
	pr("Paperwork at recruiting stations ... %d\n", player->btused);
    return RET_OK;
}
Example #21
0
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;
}
Example #22
0
int
grin(void)
{
    struct nstr_sect nstr;
    struct sctstr sect;
    char *p;
    int prd, i, n, qty;
    char buf[1024];
    double grind_eff = 0.8;
    struct pchrstr *pp;
    i_type ctype;
    unsigned camt;

    prd = dchr[SCT_BANK].d_prd;
    if (prd < 0 || pchr[prd].p_type < 0) {
	pr("Grinding is disabled.\n");
	return RET_FAIL;
    }
    pp = &pchr[prd];

    if (!(p = getstarg(player->argp[1], "Sectors? ", buf)))
	return RET_SYN;
    if (!snxtsct(&nstr, p))
	return RET_SYN;
    p = getstarg(player->argp[2], "amount :  ", buf);
    if (!p || !*p)
	return RET_SYN;
    qty = atoi(p);
    if (qty < 0)
	return RET_SYN;

    while (nxtsct(&nstr, &sect)) {
	if (!player->owner)
	    continue;
	if (sect.sct_effic < 60 || sect.sct_own != player->cnum)
	    continue;

	/* materials limit */
	n = MIN(qty, sect.sct_item[pp->p_type]);
	/* work limit */
	n = MIN(n, sect.sct_avail / 5);
	/* space limit */
	for (i = 0; i < MAXPRCON; i++) {
	    ctype = pp->p_ctype[i];
	    camt = pp->p_camt[i];
	    if (!camt)
		continue;
	    if (CANT_HAPPEN(ctype <= I_NONE || ctype > I_MAX))
		continue;
	    n = MIN(n,
		    (double)(ITEM_MAX - sect.sct_item[ctype])
		    / (camt * grind_eff));
	}

	if (n > 0) {
	    pr("%d bars ground up in %s\n", n,
	       xyas(sect.sct_x, sect.sct_y, player->cnum));
	    sect.sct_item[I_BAR] -= n;
	    for (i = 0; i < MAXPRCON; i++) {
		ctype = pp->p_ctype[i];
		camt = pp->p_camt[i];
		if (!camt)
		    continue;
		if (CANT_HAPPEN(ctype <= I_NONE || ctype > I_MAX))
		    continue;
		sect.sct_item[ctype] += n * camt * grind_eff;
	    }
	    sect.sct_avail -= n * 5;
	    putsect(&sect);
	}
    }
    return RET_OK;
}
Example #23
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;
}
Example #24
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;
}
Example #25
0
int
work(void)
{
    int nunits;
    struct nstr_item ni;
    struct sctstr sect;
    struct lndstr land;
    int work_amt, eff_amt, w;
    char *p;
    char buf[1024];
    double cost;
    struct natstr *natp = getnatp(player->cnum);

    if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL))
	return RET_SYN;
    p = getstarg(player->argp[2], "Amount: ", buf);
    if (!p || !*p)
	return RET_SYN;
    work_amt = atoi(p);
    if ((work_amt < 0) || (work_amt > land_mob_max)) {
	pr("Mobility used must be from 0 to %d\n", land_mob_max);
	return RET_FAIL;
    }
    nunits = 0;
    while (nxtitem(&ni, &land)) {
	if (!player->owner || land.lnd_own == 0)
	    continue;
	if (!(lchr[(int)land.lnd_type].l_flags & L_ENGINEER))
	    continue;
	if (land.lnd_mobil <= 0) {
	    pr("%s has no mobility!\n", prland(&land));
	    continue;
	}
	getsect(land.lnd_x, land.lnd_y, &sect);
	if (sect.sct_effic >= 100 && sect.sct_type == sect.sct_newtype) {
	    pr("Nothing to do for %s in %s\n",
	       prland(&land), xyas(sect.sct_x, sect.sct_y, player->cnum));
	    continue;
	}
	eff_amt = MIN(land.lnd_mobil, work_amt);
	w = (eff_amt * land.lnd_effic) / 600;
	if (w < 1) {
	    pr("%s doesn't work enough to change efficiency (try increasing amount)\n",
	       prland(&land));
	    continue;
	}
	cost = 0.0;
	w = buildeff(&sect, w, &cost);
	if (w == 0) {
	    pr("%s can't change efficiency in %s\n",
	       prland(&land), xyas(land.lnd_x, land.lnd_y, player->cnum));
	    continue;
	}
	if (player->dolcost + cost > natp->nat_money) {
	    pr("You can't afford to work that much in %s!\n",
	       xyas(land.lnd_x, land.lnd_y, player->cnum));
	    break;
	}
	player->dolcost += cost;
	land.lnd_mission = 0;
	land.lnd_mobil -= roundavg(w * 600.0 / land.lnd_effic);
	nunits++;
	pr("%s %s efficiency at %s to %d\n",
	   prland(&land),
	   sect.sct_type == sect.sct_newtype ? "raised" : "lowered",
	   xyas(land.lnd_x, land.lnd_y, player->cnum),
	   sect.sct_effic);
	putland(land.lnd_uid, &land);
	putsect(&sect);
    }
    if (nunits == 0) {
	if (player->argp[1])
	    pr("%s: No unit(s)\n", player->argp[1]);
	else
	    pr("%s: No unit(s)\n", "");
	return RET_FAIL;
    } else
	pr("%d unit%s\n", nunits, splur(nunits));
    return RET_OK;
}
Example #26
0
int
pln_equip(struct plist *plp, struct ichrstr *ip, char mission)
{
    struct plchrstr *pcp;
    struct plnstr *pp;
    int load, needed;
    struct lndstr land;
    struct shpstr ship;
    struct sctstr sect;
    i_type itype;
    short *item;
    int own;
    int abandon_needed;

    pp = &plp->plane;
    pcp = plp->pcp;
    if (pp->pln_ship >= 0) {
	getship(pp->pln_ship, &ship);
	plp->pstage = ship.shp_pstage;
	item = ship.shp_item;
	own = ship.shp_own;
    } else if (pp->pln_land >= 0) {
	getland(pp->pln_land, &land);
	plp->pstage = land.lnd_pstage;
	item = land.lnd_item;
	own = land.lnd_own;
    } else {
	getsect(pp->pln_x, pp->pln_y, &sect);
	plp->pstage = sect.sct_pstage;
	item = sect.sct_item;
	own = sect.sct_oldown;
    }
    if (pcp->pl_fuel > item[I_PETROL]) {
	pr("%s not enough petrol there!\n", prplane(pp));
	return -1;
    }
    item[I_PETROL] -= pcp->pl_fuel;
    load = pln_load(pp);
    itype = I_NONE;
    switch (mission) {
    case 's':		/* strategic bomb */
    case 'p':		/* pinpoint bomb */
	itype = I_SHELL;
	break;
    case 't':		/* transport */
	if (!(pcp->pl_flags & P_C) || !ip)
	    break;
	itype = ip->i_uid;
	load *= 2;
	break;
    case 'm':		/* mine */
	if ((pcp->pl_flags & P_MINE) == 0)
	    break;
	itype = I_SHELL;
	load *= 2;
	break;
    case 'd':		/* drop */
	if (!(pcp->pl_flags & P_C) || CANT_HAPPEN(!ip))
	    break;
	itype = ip->i_uid;
	if (pcp->pl_flags & P_V)
	    load *= 2;
	break;
    case 'a':		/* paradrop */
	if (!(pcp->pl_flags & P_P))
	    break;
	itype = I_MILIT;
	if (pcp->pl_flags & P_V)
	    load *= 2;
	break;
    case 'r':		/* reconnaissance */
    case 'e':		/* escort */
	load = 0;
	break;
    case 'i':		/* missile interception */
	if (CANT_HAPPEN(!(pcp->pl_flags & P_M)
			|| !(pcp->pl_flags & (P_N | P_O))))
	    break;
	if (load)
	    itype = I_SHELL;
	break;
    default:
	CANT_REACH();
	load = 0;
    }

    if (itype != I_NONE) {
	needed = load / ichr[itype].i_lbs;
	if (needed <= 0) {
	    pr("%s can't contribute to mission\n", prplane(pp));
	    return -1;
	}
	if (nuk_on_plane(pp) >= 0) {
	    if (mission == 's' || mission == 't')
		needed = 0;
	    else {
		pr("%s can't fly this mission"
		   " while it is carrying a nuclear weapon",
		   prplane(pp));
		return -1;
	    }
	}
	if (itype == I_CIVIL && pp->pln_own != own) {
	    pr("You don't control those civilians!\n");
	    return -1;
	}
#if 0
	/* Supply is broken somewhere, so don't use it for now */
	if (itype == I_SHELL && item[itype] < needed)
	    item[itype] += supply_commod(plp->plane.pln_own,
					 plp->plane.pln_x,
					 plp->plane.pln_y,
					 I_SHELL, needed);
#endif
	if (pp->pln_ship >= 0 || pp->pln_land >= 0)
	    abandon_needed = 0;
	else
	    abandon_needed = !!would_abandon(&sect, itype, needed, NULL);
	if (item[itype] < needed + abandon_needed) {
	    pr("Not enough %s for %s\n", ichr[itype].i_name, prplane(pp));
	    return -1;
	}
	item[itype] -= needed;
	plp->load = needed;
    }

    if (pp->pln_ship >= 0) {
	if (pp->pln_own != ship.shp_own) {
	    wu(0, ship.shp_own,
	       "%s %s prepares for takeoff from ship %s\n",
	       cname(pp->pln_own), prplane(pp), prship(&ship));
	}
	putship(ship.shp_uid, &ship);
    } else if (pp->pln_land >= 0) {
	if (pp->pln_own != land.lnd_own) {
	    wu(0, land.lnd_own,
	       "%s %s prepares for takeoff from unit %s\n",
	       cname(pp->pln_own), prplane(pp), prland(&land));
	}
	putland(land.lnd_uid, &land);
    } else {
	if (pp->pln_own != sect.sct_own) {
	    wu(0, sect.sct_own, "%s %s prepares for takeoff from %s\n",
	       cname(pp->pln_own), prplane(pp),
	       xyas(sect.sct_x, sect.sct_y, sect.sct_own));
	}
	putsect(&sect);
    }
    return 0;
}
Example #27
0
void jump(unsigned short addr)
{
        if (swtpc) {
                pc = addr;
                return;
        } else {
                switch (addr) {
/* Too many programs access ACIA directly */
#if 0
                        case 0xF9CF: case 0xF9DC: /* Output a character */ {
                                term_out(acca);
                                /* putchar(acca); fflush(stdout); */
                                c_flag = 0; /* Carry is error status */
                                break;
                        }
#endif
                        case 0xFA8B: /* Input a character */ {
                                acca = term_in();
                                if (!mem[0xFF53]) { /* Echo */
                                        term_out(acca);
                                        /* putchar(c);
                                        fflush(stdout); */
                                } else {
                                        mem[0xFF53] = 0;
                                }
                                c_flag = 0; /* No error */
                                break;
                        }
                        case 0xE800: /* OSLOAD (no modified parms) */ {
                                printf("\nOSLOAD...\n");
                                getsect(0, 0x0020, 23, 128);
                                getsect(0, 0x0020 + 0x0080, 24, 128);
                                pc = 0x0020;
                                sp = 0x00FF;
                                return;
                        } case 0xE822: /* FDINIT (no modified parms) */ {
                                c_flag = 0;
                                break;
                        } 
#if 0
                          case 0xF853: /* CHKERR */ {
                                break;
                        } case 0xE85A: /* PRNTER */ {
                                break;
                        } 
#endif
                          case 0xE869: /* READSC (read full sectors) */ {
                                mem[LSCTLN] = 128;
                        } case 0xE86D: /* READPS (read partial sectors) (FDSTAT, carry, sides) */ {
                                int x;
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                int num = (mem[NUMSCT] << 8) + mem[NUMSCT + 1];
                                int addr = (mem[CURADR] << 8) + mem[CURADR + 1];
                                int last = mem[LSCTLN];
                                if (trace_disk) printf("Read sectors: drive=%d, first=%d, number=%d, addr=%x, size of last=%d\n", n, first, num,
                                       addr, last);
                                if (check_drive(n))
                                        break;
                                for (x = 0; x != num; ++x) {
                                        if (check_sect(n, first + x))
                                                goto oops;
                                        getsect(n, addr + 128 * x, first + x, ((x + 1 == num) ? mem[LSCTLN] : 128));
                                }
                                mem[FDSTAT] = ER_NON;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                c_flag = 0;
                                oops: break;
                        } case 0xE86F: /* RDCRC */ {
                                if (trace_disk) printf("RDCRC\n");
                                int x;
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                int num = (mem[NUMSCT] << 8) + mem[NUMSCT + 1];
                                int addr = (mem[CURADR] << 8) + mem[CURADR + 1];
                                int last = mem[LSCTLN];
                                if (trace_disk) printf("RDCRC: drive=%d, first=%d, number=%d, addr=%x, size of last=%d\n", n, first, num,
                                       addr, last);
                                if (check_drive(n))
                                        break;
                                for (x = 0; x != num; ++x) {
                                        if (check_sect(n, first + x))
                                                goto oops;
                                }
                                mem[FDSTAT] = ER_NON;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                c_flag = 0;
                                break;
                        } case 0xE875: /* RESTOR */ {
                                int n = mem[CURDRV];
                                if (trace_disk) printf("RESTOR\n");
                                if (check_drive(n))
                                        break;
                                mem[FDSTAT] = ER_NON;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                c_flag = 0;
                                break;
                        } case 0xE878: /* SEEK */ {
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                if (trace_disk) printf("SEEK\n");
                                if (check_drive(n))
                                        break;
                                if (check_sect(n, first))
                                        break;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                c_flag = 0;
                                break;
                        } case 0xE872: /* RWTEST */ {
                                if (trace_disk) printf("RWTEST\n");
                        } case 0xE87B: /* WRTEST */ {
                                unsigned char buf[128];
                                int x;
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                int num = (mem[NUMSCT] << 8) + mem[NUMSCT + 1];
                                int addr = (mem[CURADR] << 8) + mem[CURADR + 1];
                                int last = mem[LSCTLN];
                                if (trace_disk) printf("WRTEST\n");
                                if (check_drive(n))
                                        break;
                                for (x = 0; x != 128; x += 2) {
                                        buf[x] = mem[addr];
                                        buf[x + 1] = mem[addr + 1];
                                }
                                for(x=0; x != num; ++x) {
                                        if (check_sect(n, first + x))
                                                goto oops;
                                        if (trace_disk) printf("Wrtest sector %d drive %d\n", first + x, n);
                                        fseek(drive[n].f, (first + x) * 128, SEEK_SET);
                                        fwrite(buf, 128, 1, drive[n].f);
                                        fflush(drive[n].f);
                                }
                                c_flag = 0;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                mem[FDSTAT] = ER_NON;
                                break;
                        } case 0xE87E: /* WRDDAM */ {
                                int n = mem[CURDRV];
                                printf("\r\nFloppy error: we do not support WRDDAM\n");
                                c_flag = 1;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                mem[FDSTAT] = ER_WRT;
                                break;
                        } case 0xE884: /* WRITSC */ {
                                if (trace_disk) printf("WRITSC\n");
                        } case 0xE881: /* WRVERF */ {
                                int x;
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                int num = (mem[NUMSCT] << 8) + mem[NUMSCT + 1];
                                int addr = (mem[CURADR] << 8) + mem[CURADR + 1];
                                int last = mem[LSCTLN];
                                if (trace_disk) printf("WRVERF: drive=%d, first=%d, number=%d, addr=%x, size of last=%d\n", n, first, num,
                                       addr, last);
                                if (check_drive(n))
                                        break;
                                for(x=0; x != num; ++x) {
                                        if (check_sect(n, first + x))
                                                goto oops;
                                        putsect(n, addr + 128 * x, first + x, 128);
                                }
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                mem[FDSTAT] = ER_NON;
                                c_flag = 0;
                                break;
                        } case 0xE887: /* CLOCK */ {
                                printf("Floppy: Someone called CLOCK?\n");
                                c_flag = 0;
                                break;
                        } case 0xEBC0: /* LPINIT */ {
                                if (trace_disk) printf("LPINIT\n");
                                c_flag = 0;
                                break;
                        } case 0xEBCC: /* LIST */ {
                                if (trace_disk) printf("LIST\n");
                                term_out(acca);
                                /* putchar(acca); fflush(stdout); */
                                c_flag = 0;
                                break;
                        } case 0xEBE4: /* LDATA */ {
                                if (trace_disk)printf("LDATA\n");
                                while (mem[ix] != 4) {
                                        term_out(mem[ix]);
                                        /* putchar(mem[ix]); */
                                        ++ix;
                                }
                                term_out('\r');
                                term_out('\n');
                                /* printf("\n"); */
                                c_flag = 0;
                                break;
                        } case 0xEBF2: /* LDATA1 */ {
                                if (trace_disk) printf("LDATA1\n");
                                while (mem[ix] != 4) {
                                        /* putchar(mem[ix]); */
                                        term_out(mem[ix]);
                                        ++ix;
                                }
                                /* fflush(stdout); */
                                c_flag = 0;
                                break;
                        } default: {
                                pc = addr;
                                return;
                        }
                }
                simulated(addr);
                addr = pull2();
                jump(addr);
        }
}
Example #28
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);
    }
}
Example #29
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;
}
Example #30
0
int
detonate(struct nukstr *np, coord x, coord y, int airburst)
{
    int nuketype = np->nuk_type;
    struct nchrstr *ncp;
    struct plnstr plane;
    struct sctstr sect;
    struct shpstr ship;
    struct lndstr land;
    struct nukstr nuke;
    natid own;
    int type;
    int damage;
    int fallout;
    int rad;
    struct nstr_sect ns;
    struct nstr_item ni;
    int changed = 0;

    pr("Releasing RV's for %s detonation...\n",
       airburst ? "airburst" : "groundburst");

    getsect(x, y, &sect);
    ncp = &nchr[nuketype];
    kaboom(x, y, ncp->n_blast);
    rad = ncp->n_blast;
    if (!airburst)
        rad = rad * 2 / 3;
    if (sect.sct_type == SCT_WATER)
        rad = 0;     /* Nukes falling on water affect only 1 sector */
    np->nuk_effic = 0;
    putnuke(np->nuk_uid, np);

    snxtsct_dist(&ns, x, y, rad);
    while (nxtsct(&ns, &sect)) {
        own = sect.sct_own;
        type = sect.sct_type;
        if ((damage = nukedamage(ncp, ns.curdist, airburst)) <= 0)
            continue;
        if (type == SCT_SANCT) {
            pr("bounced off %s\n", xyas(ns.x, ns.y, player->cnum));
            mpr(own, "%s nuclear device bounced off %s\n",
                cname(player->cnum), xyas(ns.x, ns.y, own));
            nreport(player->cnum, N_NUKE, own, 1);
            continue;
        }
        sect_damage(&sect, damage);
        if (opt_FALLOUT) {
            fallout = sect.sct_fallout;
            if (ncp->n_flags & N_NEUT)
                fallout += damage * 30;
            else
                fallout += damage * 3;
            sect.sct_fallout = MIN(fallout, FALLOUT_MAX);
        }
        if (damage > 100) {
            sect.sct_oldown = 0;
            sect.sct_own = 0;
            if (type == SCT_WATER || type == SCT_BSPAN ||
                    type == SCT_BTOWER) {
                if (type != SCT_WATER) {
                    pr("left nothing but water in %s\n",
                       xyas(ns.x, ns.y, player->cnum));
                    if (own != player->cnum)
                        mpr(own,
                            "%s nuclear device left nothing but water in %s\n",
                            cname(player->cnum), xyas(ns.x, ns.y, own));
                    sect.sct_newtype = SCT_WATER;
                    sect.sct_type = SCT_WATER;
                }
            } else {
                sect.sct_newtype = SCT_WASTE;
                sect.sct_type = SCT_WASTE;
                pr("turned %s into a radioactive wasteland\n",
                   xyas(ns.x, ns.y, player->cnum));
                if (own != player->cnum)
                    mpr(own,
                        "%s nuclear device turned %s into a radioactive wasteland\n",
                        cname(player->cnum), xyas(ns.x, ns.y, own));
            }
            changed |= map_set(player->cnum, sect.sct_x, sect.sct_y,
                               dchr[sect.sct_type].d_mnem, 0);
        } else {
            pr("did %d%% damage in %s\n",
               damage, xyas(ns.x, ns.y, player->cnum));
            if (own != player->cnum)
                mpr(own, "%s nuclear device did %d%% damage in %s\n",
                    cname(player->cnum), damage, xyas(ns.x, ns.y, own));
        }
        (void)putsect(&sect);
        if (type != SCT_WATER)
            nreport(player->cnum, N_NUKE, own, 1);
    }

    if (changed)
        writebmap(player->cnum);

    snxtitem_dist(&ni, EF_PLANE, x, y, rad);
    while (nxtitem(&ni, &plane)) {
        if ((own = plane.pln_own) == 0)
            continue;
        if (plane.pln_flags & PLN_LAUNCHED)
            continue;
        damage = nukedamage(ncp, ni.curdist, airburst) - plane.pln_harden;
        if (damage <= 0)
            continue;
        if (plane.pln_ship >= 0) {
            /* Are we on a sub? */
            getship(plane.pln_ship, &ship);

            if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
                struct sctstr sect1;

                /* Should we damage this sub? */
                getsect(ship.shp_x, ship.shp_y, &sect1);

                if (sect1.sct_type == SCT_BSPAN ||
                        sect1.sct_type == SCT_BTOWER ||
                        sect1.sct_type == SCT_WATER) {
                    /* Ok, we're not in a harbor or trapped
                       inland.  Now, did we get pasted
                       directly? */
                    if (ship.shp_x != x || ship.shp_y != y) {
                        /* Nope, so don't mess with it */
                        continue;
                    }
                }
            }
        }
        planedamage(&plane, damage);
        if (own == player->cnum) {
            pr("%s at %s reports %d%% damage\n",
               prplane(&plane),
               xyas(plane.pln_x, plane.pln_y, player->cnum), damage);
        } else {
            mpr(own, "%s nuclear device did %d%% damage to %s at %s\n",
                cname(player->cnum), damage,
                prplane(&plane), xyas(plane.pln_x, plane.pln_y, own));
        }
        putplane(ni.cur, &plane);
    }

    snxtitem_dist(&ni, EF_LAND, x, y, rad);
    while (nxtitem(&ni, &land)) {
        if ((own = land.lnd_own) == 0)
            continue;
        if ((damage = nukedamage(ncp, ni.curdist, airburst)) <= 0)
            continue;

        if (land.lnd_ship >= 0) {
            /* Are we on a sub? */
            getship(land.lnd_ship, &ship);

            if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
                struct sctstr sect1;

                /* Should we damage this sub? */
                getsect(ship.shp_x, ship.shp_y, &sect1);

                if (sect1.sct_type == SCT_BSPAN ||
                        sect1.sct_type == SCT_BTOWER ||
                        sect1.sct_type == SCT_WATER) {
                    /* Ok, we're not in a harbor or trapped
                       inland.  Now, did we get pasted
                       directly? */
                    if (ship.shp_x != x || ship.shp_y != y) {
                        /* Nope, so don't mess with it */
                        continue;
                    }
                }
            }
        }
        land_damage(&land, damage);
        if (own == player->cnum) {
            pr("%s at %s reports %d%% damage\n",
               prland(&land), xyas(land.lnd_x, land.lnd_y, player->cnum),
               damage);
        } else {
            mpr(own, "%s nuclear device did %d%% damage to %s at %s\n",
                cname(player->cnum), damage,
                prland(&land), xyas(land.lnd_x, land.lnd_y, own));
        }
        putland(land.lnd_uid, &land);
    }

    snxtitem_dist(&ni, EF_SHIP, x, y, rad);
    while (nxtitem(&ni, &ship)) {
        if ((own = ship.shp_own) == 0)
            continue;
        if ((damage = nukedamage(ncp, ni.curdist, airburst)) <= 0)
            continue;
        if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
            struct sctstr sect1;

            /* Should we damage this sub? */
            getsect(ship.shp_x, ship.shp_y, &sect1);

            if (sect1.sct_type == SCT_BSPAN ||
                    sect1.sct_type == SCT_BTOWER ||
                    sect1.sct_type == SCT_WATER) {
                /* Ok, we're not in a harbor or trapped
                   inland.  Now, did we get pasted
                   directly? */
                if (ship.shp_x != x || ship.shp_y != y) {
                    /* Nope, so don't mess with it */
                    continue;
                }
            }
        }
        ship_damage(&ship, damage);
        if (own == player->cnum) {
            pr("%s at %s reports %d%% damage\n",
               prship(&ship), xyas(ship.shp_x, ship.shp_y, player->cnum),
               damage);
        } else {
            mpr(own, "%s nuclear device did %d%% damage to %s at %s\n",
                cname(player->cnum), damage, prship(&ship),
                xyas(ship.shp_x, ship.shp_y, own));
        }
        putship(ship.shp_uid, &ship);
    }

    snxtitem_dist(&ni, EF_NUKE, x, y, rad);
    while (nxtitem(&ni, &nuke)) {
        if ((own = nuke.nuk_own) == 0)
            continue;
        if ((damage = nukedamage(ncp, ni.curdist, airburst)) <= 0)
            continue;
        if (!pct_chance(damage))
            continue;
        nuke.nuk_effic = 0;
        if (own == player->cnum) {
            pr("%s at %s destroyed\n",
               prnuke(&nuke), xyas(nuke.nuk_x, nuke.nuk_y, player->cnum));
        } else {
            mpr(own, "%s nuclear device destroyed %s at %s\n",
                cname(player->cnum), prnuke(&nuke),
                xyas(nuke.nuk_x, nuke.nuk_y, own));
        }
        putnuke(ni.cur, &nuke);
    }

    return nukedamage(ncp, 0, airburst);
}