Esempio n. 1
0
int
msl_hit(struct plnstr *pp, int hardtarget, int type,
	int news_item, int snews_item, int sublaunch, natid victim)
{
    int hitchance, hit;

    if (nuk_on_plane(pp) >= 0) {
	mpr(pp->pln_own, "\tArming nuclear warheads...\n");
	hit = 1;
    } else {
	hitchance = pln_hitchance(pp, hardtarget, type);
	hit = pct_chance(hitchance);
	mpr(pp->pln_own, "\t%d%% hitchance...%s\n", hitchance,
	    hit ? "HIT!" : "miss");
    }

    if (type != EF_PLANE)
	mpr(victim, "...Incoming %s missile %s\n",
	    sublaunch ? "" : cname(pp->pln_own),
	    hit ? "HIT!\n" : "missed\n");
    if (hit && news_item) {
	if (sublaunch)
	    nreport(victim, snews_item, 0, 1);
	else
	    nreport(pp->pln_own, news_item, victim, 1);
    }
    return hit;
}
Esempio n. 2
0
static int
fire_torp(struct shpstr *sp, struct shpstr *targ, int ntargets)
{
    int range, erange, dam;

    if ((mchr[targ->shp_type].m_flags & M_SUB)
	&& (mchr[sp->shp_type].m_flags & M_SUBT) == 0)
	return 0;		/* need sub-torp to torpedo a sub */

    erange = roundrange(torprange(sp));
    range = mapdist(sp->shp_x, sp->shp_y, targ->shp_x, targ->shp_y);
    if (range > erange)
	return 0;

    if (!line_of_sight(NULL, sp->shp_x, sp->shp_y,
		       targ->shp_x, targ->shp_y))
	return 0;
    dam = shp_torp(sp, 1);
    putship(sp->shp_uid, sp);
    if (dam < 0)
	return 0;

    pr("Captain! Torpedoes sighted!\n");

    if (chance(shp_torp_hitchance(sp, range))) {
	pr("BOOM!...\n");
	if (!(mchr[targ->shp_type].m_flags & M_SUB)) {
	    if (mchr[sp->shp_type].m_flags & M_SUB)
		nreport(targ->shp_own, N_TORP_SHIP, 0, 1);
	    else
		nreport(targ->shp_own, N_SHIP_TORP, sp->shp_own, 1);
	}
	if (sp->shp_own != 0)
	    wu(0, sp->shp_own, "%s @ %s torpedoed %s\n",
	       prship(sp),
	       xyas(sp->shp_x, sp->shp_y, sp->shp_own), prsub(targ));
	if (ntargets > 2)
	    dam /= ntargets / 2;

	shipdamage(targ, dam);
	putship(targ->shp_uid, targ);

    } else {
	pr("Missed!\n");
	if (sp->shp_own != 0)
	    wu(0, sp->shp_own,
	       "%s missed %s with a torpedo at %s\n",
	       prship(sp), prsub(targ),
	       xyas(sp->shp_x, sp->shp_y, sp->shp_own));
    }

    return 1;
}
Esempio n. 3
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);
    }
}
Esempio n. 4
0
/*
 * Post-processing after successful acceptance of loan.
 * Notify the press, and the folks involved.
 * (Weird spelling is to avoid accept(2)).
 */
static void
accpt(struct ltcomstr *ltcp)
{
    switch (ltcp->type) {
    case EF_LOAN:
	nreport(ltcp->proposer, N_MAKE_LOAN, player->cnum, 1);
	break;
    default:
	CANT_REACH();
    }
    wu(0, ltcp->mailee, "%s #%d accepted by %s\n",
       ltcp->Name, ltcp->num, cname(player->cnum));
}
Esempio n. 5
0
int
chan(void)
{
    char *p;
    int charge;
    int btucost;
    char buf[1024];
    struct natstr *us;

    p = getstarg(player->argp[1], "country name or representative? ", buf);
    if (!p)
	return RET_SYN;
    us = getnatp(player->cnum);
    switch (*p) {
    case 'n':
    case 'c':
	charge = 0;
	btucost = 0;
	if (us->nat_stat == STAT_ACTIVE) {
	    if (opt_BLITZ == 0) {
		if (us->nat_btu < 254) {
		    pr("You need 254 btus to change your country name!\n");
		    return RET_FAIL;
		}
		pr("This command costs 254 BTU's and 10%% of your money.\n");
		if (!confirm("Are you sure you want to do this? "))
		    return RET_FAIL;
		btucost = 254;
		if (us->nat_money <= 0)
		    charge = 0;
		else
		    charge = us->nat_money / 10;
	    }
	}
	p = getstarg(player->argp[2], "New country name -- ", buf);
	if (!p)
	    return RET_SYN;
	if (!check_nat_name(p, player->cnum))
	    return RET_FAIL;
	player->dolcost += charge;
	player->btused += btucost;
	strcpy(us->nat_cnam, p);
	putnat(us);
	nreport(player->cnum, N_NAME_CHNG, 0, 1);
	break;
    case 'p':
    case 'r':
	pr("(note: these are stored in plain text.)\n");
	p = getstarg(player->argp[2], "New representative name -- ", buf);
	if (!p)
	    return RET_SYN;
	p[sizeof(us->nat_pnam) - 1] = 0;
	strcpy(us->nat_pnam, p);
	putnat(us);
	break;
    default:
	pr("Only \"country\" or \"representative\" can change.\n");
	return RET_SYN;
    }
    return RET_OK;
}
Esempio n. 6
0
int
repa(void)
{
    struct lonstr loan;
    struct natstr *natp;
    struct natstr *loaner;
    int loan_num;
    int payment;
    int newdue;
    char *cp;
    time_t now;
    char buf[1024];

    if (!opt_LOANS) {
	pr("Loans are not enabled.\n");
	return RET_FAIL;
    }
    natp = getnatp(player->cnum);
    cp = getstarg(player->argp[1], "Repay loan #? ", buf);
    if (!cp)
	return RET_SYN;
    loan_num = atoi(cp);
    if (loan_num < 0)
	return RET_SYN;
    if (!getloan(loan_num, &loan) || loan.l_lonee != player->cnum
	|| loan.l_status != LS_SIGNED) {
	pr("You don't owe anything on that loan.\n");
	return RET_FAIL;
    }
    if (!(cp = getstarg(player->argp[2], "amount? ", buf)))
	return RET_SYN;
    if (!check_loan_ok(&loan))
	return RET_FAIL;
    payment = atoi(cp);
    if (payment <= 0)
	return RET_SYN;

    newdue = (int)ceil(loan_owed(&loan, time(&now)) - payment);
    if (newdue < 0) {
	pr("You don't owe that much.\n");
	return RET_FAIL;
    }
    if (natp->nat_money < payment) {
	pr("You only have $%d.\n", natp->nat_money);
	return RET_FAIL;
    }
    player->dolcost += payment;
    loaner = getnatp(loan.l_loner);
    loaner->nat_money += payment;
    putnat(loaner);
    loan.l_lastpay = now;
    if (newdue == 0) {
	wu(0, loan.l_loner, "Country #%d paid off loan #%d with $%d\n",
	   player->cnum, loan_num, payment);
	nreport(player->cnum, N_REPAY_LOAN, loan.l_loner, 1);
	loan.l_status = LS_FREE;
	loan.l_ldur = 0;
	pr("Congratulations, you've paid off the loan!\n");
    } else {
	wu(0, loan.l_loner,
	   "Country #%d paid $%d on loan %d\n",
	   player->cnum, payment, loan_num);
	loan.l_amtdue = newdue;
	loan.l_amtpaid += payment;
    }
    if (!putloan(loan_num, &loan)) {
	logerror("repa: can't write loan");
	pr("Can't save loan; get help!\n");
	return RET_FAIL;
    }
    return RET_OK;
}
Esempio n. 7
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);
}
Esempio n. 8
0
int
check_trade(void)
{
    int n;
    struct natstr *natp;
    struct trdstr trade;
    union empobj_storage tg;
    time_t now;
    int price;
    int saveid;
    natid seller;

    for (n = 0; gettrade(n, &trade); n++) {
	if (trade.trd_unitid < 0)
	    continue;
	if (!trade_getitem(&trade, &tg))
	    continue;
	if (tg.gen.own == 0) {
	    trade.trd_owner = 0;
	    trade.trd_unitid = -1;
	    puttrade(n, &trade);
	    continue;
	}
	if (tg.gen.own != trade.trd_owner) {
	    logerror("Something weird, tg.gen.own != trade.trd_owner!\n");
	    trade.trd_owner = 0;
	    trade.trd_unitid = -1;
	    puttrade(n, &trade);
	    continue;
	}

	if (trade.trd_owner == trade.trd_maxbidder)
	    continue;

	(void)time(&now);
	if (trade.trd_markettime + TRADE_DELAY > now)
	    continue;

	saveid = trade.trd_unitid;
	seller = trade.trd_owner;
	trade.trd_owner = 0;
	trade.trd_unitid = -1;
	if (!puttrade(n, &trade)) {
	    logerror("Couldn't save trade after purchase; get help!\n");
	    continue;
	}

	price = trade.trd_price;
	natp = getnatp(trade.trd_maxbidder);
	if (natp->nat_money < price) {
	    nreport(trade.trd_maxbidder, N_WELCH_DEAL, seller, 1);
	    wu(0, seller,
	       "%s tried to buy a %s #%d from you for $%.2f\n",
	       cname(trade.trd_maxbidder), trade_nameof(&trade, &tg.gen),
	       saveid, price * tradetax);
	    wu(0, seller, "   but couldn't afford it.\n");
	    wu(0, seller,
	       "   Your item was taken off the market.\n");
	    wu(0, trade.trd_maxbidder,
	       "You tried to buy %s #%d from %s for $%d\n",
	       trade_nameof(&trade, &tg.gen), saveid, cname(seller),
	       price);
	    wu(0, trade.trd_maxbidder, "but couldn't afford it.\n");
	    continue;
	}

/* If we get this far, the sale will go through. */

	natp->nat_money -= price;
	putnat(natp);

	natp = getnatp(seller);
	natp->nat_money += roundavg(price * tradetax);
	putnat(natp);

	switch (trade.trd_type) {
	case EF_NUKE:
	    tg.nuke.nuk_x = trade.trd_x;
	    tg.nuke.nuk_y = trade.trd_y;
	    tg.nuke.nuk_plane = -1;
	    break;
	case EF_PLANE:
	    if (!pln_is_in_orbit(&tg.plane)) {
		tg.plane.pln_x = trade.trd_x;
		tg.plane.pln_y = trade.trd_y;
	    }
	    if (opt_MOB_ACCESS) {
		tg.plane.pln_mobil = -(etu_per_update / sect_mob_neg_factor);
		game_tick_to_now(&tg.plane.pln_access);
	    } else {
		tg.plane.pln_mobil = 0;
	    }
	    tg.plane.pln_harden = 0;
	    tg.plane.pln_ship = -1;
	    tg.plane.pln_land = -1;
	    break;
	case EF_SHIP:
	    break;
	case EF_LAND:
	    tg.land.lnd_x = trade.trd_x;
	    tg.land.lnd_y = trade.trd_y;
	    if (opt_MOB_ACCESS) {
		tg.land.lnd_mobil = -(etu_per_update / sect_mob_neg_factor);
		game_tick_to_now(&tg.land.lnd_access);
	    } else {
		tg.land.lnd_mobil = 0;
	    }
	    tg.land.lnd_harden = 0;
	    unit_drop_cargo(&tg.gen, 0);
	    tg.land.lnd_ship = -1;
	    tg.land.lnd_land = -1;
	    break;
	default:
	    logerror("Bad trade type %d in trade\n", trade.trd_type);
	    break;
	}
	unit_give_away(&tg.gen, trade.trd_maxbidder, 0);
	put_empobj(trade.trd_type, saveid, &tg.gen);

	nreport(seller, N_MAKE_SALE, trade.trd_maxbidder, 1);
	wu(0, seller, "%s bought %s #%d from you for $%.2f\n",
	   cname(trade.trd_maxbidder), trade_nameof(&trade, &tg.gen),
	   saveid, price * tradetax);
	wu(0, trade.trd_maxbidder,
	   "The bidding is over & you bought %s #%d from %s for $%d\n",
	   trade_nameof(&trade, &tg.gen), saveid, cname(seller),
	   price);
    }
    return RET_OK;
}
Esempio n. 9
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;
}
Esempio n. 10
0
static void
nreport_divine_aid(natid whom, int goodness)
{
    if (opt_GODNEWS && getnatp(whom)->nat_stat != STAT_GOD && goodness)
	nreport(player->cnum, goodness > 0 ? N_AIDS : N_HURTS, whom, 1);
}
Esempio n. 11
0
int
torp(void)
{
    natid vshipown;
    int range;
    int dam;
    int subno;
    int victno;
    int erange;
    double hitchance;
    struct shpstr vship;
    struct shpstr sub;
    struct mchrstr *sub_mcp;
    char *ptr;
    struct nstr_item nbst;
    char buf[1024];
    int ntorping = 0;
    char prompt[128];

    if (!snxtitem(&nbst, EF_SHIP, player->argp[1], "From ship(s)? "))
	return RET_SYN;
    while (nxtitem(&nbst, &sub)) {
	if (sub.shp_own != player->cnum)
	    continue;
	if ((mchr[(int)sub.shp_type].m_flags & M_TORP) == 0)
	    continue;
	if (sub.shp_item[I_GUN] == 0
	    || sub.shp_item[I_SHELL] < SHP_TORP_SHELLS)
	    continue;
	if (sub.shp_item[I_MILIT] < 1)
	    continue;
	if (sub.shp_effic < 60)
	    continue;
	if (sub.shp_mobil <= 0)
	    continue;
	ntorping++;
    }
    pr("%d ships are eligible to torpedo\n", ntorping);
    snxtitem_rewind(&nbst);
    while (nxtitem(&nbst, &sub)) {
	if (!sub.shp_own)
	    continue;
	if (sub.shp_own != player->cnum) {
	    continue;
	}
	sub_mcp = &mchr[sub.shp_type];
	if (!(sub_mcp->m_flags & M_TORP)) {
	    pr("Ship # %d: A %s can't fire torpedoes!\n",
	       sub.shp_uid, sub_mcp->m_name);
	    continue;
	}
	if (sub.shp_item[I_GUN] == 0
	    || sub.shp_item[I_SHELL] < SHP_TORP_SHELLS) {
	    pr("Ship #%d has insufficient armament\n", sub.shp_uid);
	    continue;
	}
	if (sub.shp_item[I_MILIT] < 1) {
	    pr("Ship #%d has insufficient crew\n", sub.shp_uid);
	    continue;
	}
	if (sub.shp_effic < 60) {
	    pr("Ship #%d torpedo tubes inoperative.\n", sub.shp_uid);
	    continue;
	}
	if (sub.shp_mobil <= 0) {
	    pr("Ship #%d has insufficient mobility\n", sub.shp_uid);
	    continue;
	}
	subno = sub.shp_uid;
	sprintf(prompt, "Ship %d, target? ", sub.shp_uid);
	if (!(ptr = getstarg(player->argp[2], prompt, buf)))
	    return RET_SYN;
	if (!check_ship_ok(&sub))
	    return RET_FAIL;
	if ((victno = atoi(ptr)) < 0)
	    return RET_SYN;
	if (!getship(victno, &vship))
	    return RET_FAIL;
	if (!vship.shp_own)
	    return RET_FAIL;
	vshipown = vship.shp_own;
	if (victno == subno) {
	    pr("Shooting yourself, eh?  How strange...\n");
	    continue;
	}
	if (mchr[(int)vship.shp_type].m_flags & M_SUB) {
	    if (!(sub_mcp->m_flags & M_SUBT)) {
		pr("You can't torpedo a submarine!\n");
		continue;
	    }
	}
	dam = shp_torp(&sub, 1);
	sub.shp_mission = 0;
	putship(sub.shp_uid, &sub);
	if (CANT_HAPPEN(dam < 0)) {
	    pr("Ship #%d has insufficient armament\n", sub.shp_uid);
	    continue;
	}

	if (!(sub_mcp->m_flags & M_SUB)) {
	    pr("Starting our attack run...\n");
	    anti_torp(sub.shp_uid, ntorping, vshipown);
	}
	getship(sub.shp_uid, &sub);
	if (sub.shp_own == 0)
	    continue;

	erange = roundrange(torprange(&sub));
	pr("Effective torpedo range is %d.0\n", erange);
	pr("Whooosh... ");
	getship(victno, &vship);
	vshipown = vship.shp_own;
	range = mapdist(sub.shp_x, sub.shp_y, vship.shp_x, vship.shp_y);
	hitchance = shp_torp_hitchance(&sub, range);
	if (range <= erange) {
	    pr("Hitchance = %.0f%%\n", hitchance * 100);
	}
	if (range > erange)
	    pr("Out of range\n");
	else if (!line_of_sight(NULL, sub.shp_x, sub.shp_y,
				vship.shp_x, vship.shp_y)) {
	    pr("BOOM!... Torpedo slams into land before reaching target.\n");
	    /* We only tell the victim if we were within range. */
	    if (vshipown != 0 && vshipown != player->cnum)
		wu(0, vshipown, "Torpedo sighted @ %s by %s\n",
		   xyas(sub.shp_x, sub.shp_y, vshipown),
		   prship(&vship));
	} else if (chance(hitchance)) {
	    pr("BOOM!...\n");
	    if (vshipown != 0 && vshipown != player->cnum)
		wu(0, vshipown, "%s in %s torpedoed %s for %d damage.\n",
		   sub_mcp->m_flags & M_SUB ? "sub" : prship(&sub),
		   xyas(sub.shp_x, sub.shp_y, vshipown),
		   prship(&vship), dam);
	    pr("Torpedo hit %s for %d damage.\n", prsub(&vship), dam);
	    if (!(mchr[vship.shp_type].m_flags & M_SUB)) {
		if (mchr[sub.shp_type].m_flags & M_SUB)
		    nreport(vshipown, N_TORP_SHIP, 0, 1);
		else
		    nreport(vshipown, N_SHIP_TORP, player->cnum, 1);
	    }
	    shipdamage(&vship, dam);
	    if (vship.shp_effic < SHIP_MINEFF)
		pr("%s sunk!\n", prsub(&vship));
	    if (vship.shp_rflags & RET_TORPED)
		retreat_ship(&vship, vshipown, 't');
	    putship(vship.shp_uid, &vship);
	} else {
	    pr("Missed\n");
	    if (vshipown != 0 && vshipown != player->cnum)
		wu(0, vshipown, "Torpedo sighted @ %s by %s\n",
		   xyas(sub.shp_x, sub.shp_y, vshipown), prship(&vship));
	}

	if (sub_mcp->m_flags & M_SUB)
	    anti_torp(sub.shp_uid, ntorping, vshipown);
    }
    return RET_OK;
}
Esempio n. 12
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);
}
Esempio n. 13
0
static int
msl_intercept(struct plnstr *msl, struct sctstr *sp, int sublaunch,
	      struct emp_qelem *irvlist, char *att_name, char *def_name,
	      int news_item)
{
    struct plnstr *pp;
    struct emp_qelem *intlist;
    struct emp_qelem intfoo;
    struct emp_qelem *qp;
    struct emp_qelem *next;
    struct plist *ip;
    int icount = 0;
    short destroyed;
    char *who = sublaunch ? "" : cname(msl->pln_own);

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

    /* attempt to destroy incoming missile */

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

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

	if (msl_launch(pp, EF_PLANE, att_name, sp->sct_x, sp->sct_y,
		       msl->pln_own, NULL) >= 0
	    && msl_hit(pp, pln_def(msl), EF_PLANE, 0, 0, 0, msl->pln_own)) {
	    mpr(msl->pln_own, "%s destroyed by %s %s!\n",
		att_name, cname(pp->pln_own), def_name);
	    mpr(sp->sct_own, "%s %s intercepted!\n", who, att_name);
	    if (sp->sct_own != pp->pln_own)
		mpr(pp->pln_own, "%s %s intercepted!\n", who, att_name);
	    if (sublaunch)
		nreport(pp->pln_own, news_item, 0, 1);
	    else
		nreport(pp->pln_own, news_item, msl->pln_own, 1);
	    destroyed = 1;
	}
	/* zap the missile */
	pp->pln_effic = 0;
	putplane(pp->pln_uid, pp);
	emp_remque(qp);
	free(qp);
    }
    /* Clean out what is left in the list */
    while (!QEMPTY(intlist)) {
	qp = intlist->q_forw;
	emp_remque(qp);
	free(qp);
    }
    if (destroyed)
	return 1;
    if (icount) {
	mpr(msl->pln_own, "%s made it through %s defenses!\n",
	    att_name, def_name);
	mpr(sp->sct_own, "%s made it through %s defenses!\n",
	    att_name, def_name);
    }
    return 0;
}
Esempio n. 14
0
int
tele(void)
{
    natid to;
    struct natstr *natp;
    char buf[MAXTELSIZE + 1];	/* UTF-8 */
    int n;

    if (*player->argp[0] == 'a') {
	if (getele("everybody", buf) <= 0) {
	    pr("Announcement aborted\n");
	    return RET_FAIL;
	}
	pr("\n");
	to = 0;
	if (typed_wu(player->cnum, to, buf, TEL_ANNOUNCE) < 0)
	    logerror("tele: typed_wu failed to #%d", to);
    } else if (*player->argp[0] == 'p') {
	if (getele("your Gracious Deity", buf) <= 0) {
	    pr("Prayer aborted\n");
	    return RET_FAIL;
	}
	pr("\n");
	if (typed_wu(player->cnum, 0, buf, TEL_NORM) < 0)
	    logerror("tele: typed_wu failed to #0");
    } else {
	int kk;

	kk = 1;
	do {
	    if ((n = natarg(player->argp[kk], "for which country? ")) < 0)
		return RET_SYN;
	    to = n;

	    if (kk == 1) {
		if (player->argp[2]) {
		    if (getele("multiple recipients", buf) < 0) {
			pr("Telegram aborted\n");
			return RET_FAIL;
		    }
		} else {
		    if (getele(cname(to), buf) < 0) {
			pr("Telegram aborted\n");
			return RET_FAIL;
		    }
		}
		pr("\n");
	    }

	    natp = getnatp(to);
	    if (natp->nat_stat < STAT_SANCT) {
		pr("%s has no \"telegram privileges\".\n", cname(to));
		kk++;
		continue;
	    }
	    if (!player->god
		&& (getrejects(player->cnum, natp) & REJ_TELE)) {
		pr("%s is rejecting your telegrams.\n", cname(to));
		return RET_SYN;
	    }
	    if (typed_wu(player->cnum, to, buf, TEL_NORM) < 0) {
		logerror("tele: typed_wu failed to #%d", n);
		return RET_FAIL;
	    }

	    if (!player->god && natp->nat_stat != STAT_GOD
		&& player->cnum != to)
		nreport(player->cnum, N_SENT_TEL, to, 1);
	    if (opt_HIDDEN) {
		setcont(to, player->cnum, FOUND_TELE);
	    }
	    kk++;
	} while (player->argp[kk] != NULL);
    }
    return RET_OK;
}
Esempio n. 15
0
void
do_plague(struct sctstr *sp, struct natstr *np, int etu)
{
    int pstage, ptime;
    int n;

    if (opt_NO_PLAGUE)		/* no plague nothing to do */
	return;

    pstage = sp->sct_pstage;
    ptime = sp->sct_ptime;

    if (pstage == PLG_HEALTHY) {
	pstage = infect_people(np, sp);
	ptime = 0;
    } else {
	n = plague_people(np, sp->sct_item, &pstage, &ptime, etu);
	switch (n) {
	case PLG_DYING:
	    wu(0, sp->sct_own, "PLAGUE deaths reported in %s.\n",
	       ownxy(sp));
	    nreport(sp->sct_own, N_DIE_PLAGUE, 0, 1);
	    break;
	case PLG_INFECT:
	    wu(0, sp->sct_own, "%s battling PLAGUE\n", ownxy(sp));
	    break;
	case PLG_INCUBATE:
	    /* Are we still incubating? */
	    if (n == pstage) {
		/* Yes. Will it turn "infectious" next time? */
		if (ptime <= etu) {
		    /* Yes.  Report an outbreak. */
		    wu(0, sp->sct_own,
		       "Outbreak of PLAGUE in %s!\n", ownxy(sp));
		    nreport(sp->sct_own, N_OUT_PLAGUE, 0, 1);
		}
	    } else {
		/* It has already moved on to "infectious" */
		wu(0, sp->sct_own, "%s battling PLAGUE\n", ownxy(sp));
	    }
	    break;
	case PLG_EXPOSED:
	    /* Has the plague moved to "incubation" yet? */
	    if (n != pstage) {
		/* Yes. Will it turn "infectious" next time? */
		if (ptime <= etu) {
		    /* Yes.  Report an outbreak. */
		    wu(0, sp->sct_own,
		       "Outbreak of PLAGUE in %s!\n", ownxy(sp));
		    nreport(sp->sct_own, N_OUT_PLAGUE, 0, 1);
		}
	    }
	    break;
	default:
	    break;
	}
    }
    if (sp->sct_item[I_CIVIL] == 0 && sp->sct_item[I_MILIT] == 0
	&& !has_units(sp->sct_x, sp->sct_y, sp->sct_own, NULL)) {
	makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
	sp->sct_own = 0;
	sp->sct_oldown = 0;
    }
    sp->sct_pstage = pstage;
    sp->sct_ptime = ptime;
}
Esempio n. 16
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;
}