empserver/src/lib/commands/coll.c
Markus Armbruster 4ae9c417b3 (bzero, bcopy): Obsolete BSDisms; remove. Remove some calls without
effect.  Replace calls by struct assignment where possible.  Replace
clear buffer, copy string to buffer by strncpy().  Use assignment to
clear when that's clearer.  Replace overlapping copy through bounce
buffer by memmove().  Replace rest by standard memset() and memcpy().
Also use sizeof() instead of literal array sizes for robustness, and
instead of symbolic array sizes for clarity.
2004-01-08 17:54:28 +00:00

183 lines
5.5 KiB
C

/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
* related information and legal notices. It is expected that any future
* projects/authors will amend these files as needed.
*
* ---
*
* coll.c: Collet on a loan
*
* Known contributors to this file:
* Pat Loney, 1992
* Steve McClure, 1996-2000
*/
#include <math.h>
#include "misc.h"
#include "player.h"
#include "var.h"
#include "file.h"
#include "sect.h"
#include "item.h"
#include "loan.h"
#include "news.h"
#include "nat.h"
#include "xy.h"
#include "commands.h"
#include "optlist.h"
int
coll(void)
{
register int arg;
register int i;
register int val;
time_t now;
s_char *p;
struct lonstr loan;
struct sctstr sect;
coord x, y;
long due;
long last;
long rdur;
long xdur;
double rate;
double owed;
double pay;
s_char buf[1024];
int vec[I_MAX + 1];
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. */
(void)time(&now);
due = loan.l_duedate;
if (now <= due) {
pr("There has been no default on loan %d\n", arg);
return RET_FAIL;
}
last = loan.l_lastpay;
if (last < due && due < now) {
rdur = due - last;
xdur = now - due;
} else if (due < last) {
rdur = 0;
xdur = now - last;
}
rate = loan.l_irate / (loan.l_ldur * 8.64e6);
/* changed following to avoid overflow 3/27/89 bailey@math-cs.kent.edu
owed = ((rdur * rate) + (xdur * rate * 2.0) + 1.0) * loan.l_amtdue;
Begin overflow fix */
owed = ((rdur * rate) + (xdur * rate * 2.0) + 1.0);
if (((1 << 30) / owed) < loan.l_amtdue)
owed = (1 << 30);
else
owed *= loan.l_amtdue;
/* End overflow fix */
pr("You are owed $%.2f on that loan.\n", owed);
if (!
(p =
getstarg(player->argp[2],
"What sector do you wish to confiscate? ", buf)))
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 = dchr[sect.sct_type].d_value * ((float)sect.sct_effic + 100.0);
for (i = 0; ichr[i].i_name; i++) {
if (ichr[i].i_value == 0 || ichr[i].i_vtype == 0)
continue;
val = getvar(ichr[i].i_vtype, (s_char *)&sect, EF_SECTOR);
pay += val * ichr[i].i_value;
}
pr("That sector (and its contents) is valued at $%.2f\n", pay);
if (pay > owed * 1.2) {
pr("That is more than is owed!\n");
return RET_FAIL;
}
if (sect.sct_type == SCT_CAPIT || sect.sct_type == SCT_MOUNT)
caploss(&sect, sect.sct_own, "that was %s's capital!\n");
putvar(V_MILIT, 1, (s_char *)&sect, EF_SECTOR);
/* Consider modifying takeover to take a "no che" argument and
putting using it here again. */
/* (void) takeover(&sect, player->cnum);*/
makelost(EF_SECTOR, sect.sct_own, 0, sect.sct_x, sect.sct_y);
makenotlost(EF_SECTOR, player->cnum, 0, sect.sct_x, sect.sct_y);
sect.sct_own = player->cnum;
memset(vec, 0, sizeof(vec));
putvec(VT_DIST, vec, (s_char *)&sect, EF_SECTOR);
putvec(VT_DEL, vec, (s_char *)&sect, EF_SECTOR);
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);
if (pay >= owed) {
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 = (long)owed;
pay += loan.l_amtpaid;
loan.l_amtpaid = 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;
}