]> git.pond.sub.org Git - empserver/blobdiff - src/lib/commands/cons.c
commands: Rename the command functions
[empserver] / src / lib / commands / cons.c
index 37bb99db2f2adb68a42a70978f668fb7770bc26b..a2d56dbf16cb0f3bf07a5e5dd5fa22e7a3656cd3 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
+ *  Copyright (C) 1986-2021, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                Ken Stevens, Steve McClure, Markus Armbruster
  *
- *  This program is free software; you can redistribute it and/or modify
+ *  Empire 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
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
  *  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
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  *  ---
  *
- *  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.
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
  *
  *  ---
  *
- *  cons.c: Consider a loan or treaty
- * 
+ *  cons.c: Consider a loan
+ *
  *  Known contributors to this file:
- *     
+ *     Markus Armbruster, 2004-2014
  */
 
-#include "misc.h"
-#include "player.h"
+#include <config.h>
+
+#include "commands.h"
 #include "loan.h"
-#include "nat.h"
-#include "treaty.h"
 #include "news.h"
-#include "xy.h"
-#include "nsc.h"
-#include "file.h"
-#include "commands.h"
 #include "optlist.h"
 
-/*
- * Things common to a loan or treaty.
- */
 struct ltcomstr {
-       int     type;                   /* EF_LOAN or EF_TREATY */
-       int     num;                    /* number */
-       s_char  *name;                  /* "loan" or "treaty" */
-       s_char  *Name;                  /* "Loan" or "Treaty" */
-       natid   proposer;               /* country offering */
-       natid   proposee;               /* country offered to */
-       natid   mailee;                 /* who gets mail about it */
-       s_char  op;                     /* 'a', 'd', or 'p' */
-       union {
-               struct  lonstr l;       /* the loan */
-               struct  trtstr t;       /* the treaty */
-       } u;
+    int type;                  /* currently always EF_LOAN */
+    int num;                   /* number */
+    char *name;                        /* "loan" */
+    char *Name;                        /* "Loan" */
+    natid proposer;            /* country offering */
+    natid proposee;            /* country offered to */
+    natid mailee;              /* who gets mail about it */
+    char op;                   /* 'a', 'd', or 'p' */
+    union {
+       struct lonstr l;        /* the loan */
+    } u;
 };
 
 static int cons_choose(struct ltcomstr *ltcp);
-static int treaty_accept(struct ltcomstr *ltcp);
-static int treaty_decline(struct ltcomstr *ltcp);
+static int cons_display(struct ltcomstr *ltcp);
+static int cons_accept(struct ltcomstr *ltcp);
+static int cons_decline(struct ltcomstr *ltcp);
+static int cons_postpone(struct ltcomstr *ltcp);
 static int loan_accept(struct ltcomstr *ltcp);
 static int loan_decline(struct ltcomstr *ltcp);
-static int postpone(struct ltcomstr *ltcp);
 static void accpt(struct ltcomstr *ltcp);
 static void decline(struct ltcomstr *ltcp);
 static void late(struct ltcomstr *ltcp);
 static void prev_signed(struct ltcomstr *ltcp);
 
 int
-cons(void)
+c_consider(void)
 {
-       int     rv;
-       struct  ltcomstr ltc;
-
-       rv = cons_choose(&ltc);
-       if (rv != RET_OK)
-               return rv;
-
-       switch (ltc.op) {
-       case 'a':
-               rv = (ltc.type == EF_TREATY) ? treaty_accept(&ltc)
-                                            : loan_accept(&ltc);
-               break;
-       case 'd':
-               rv = (ltc.type == EF_TREATY) ? treaty_decline(&ltc)
-                                            : loan_decline(&ltc);
-               break;
-       case 'p':
-               rv = postpone(&ltc);
-               break;
-       default:
-               pr("Bad operation %c from cons_choose; get help!\n",
-                       ltc.op);
-               break;
-       };
+    int rv;
+    struct ltcomstr ltc;
 
+    rv = cons_choose(&ltc);
+    if (rv != RET_OK)
        return rv;
+
+    switch (ltc.op) {
+    case 'a':
+       return cons_accept(&ltc);
+    case 'd':
+       return cons_decline(&ltc);
+    case 'p':
+       return cons_postpone(&ltc);
+    default:
+       CANT_REACH();
+       return RET_SYN;
+    }
 }
 
 /*
  * Choose whether we want to accept, decline, or postpone a
- * loan or treaty.  Put all the goodies in ltcp, and return
+ * loan.  Put all the goodies in ltcp, and return
  * RET_OK if all goes well, and anything else on error.
  */
 static int
 cons_choose(struct ltcomstr *ltcp)
 {
-       s_char  *p;
-       extern  int disloan();
-       extern  int distrea();
-       int     (*dis)();
-       struct  lonstr *lp;
-       struct  trtstr *tp;
-       s_char  prompt[128];
-       s_char  buf[1024];
+    static int lon_or_trt[] = { EF_LOAN, EF_BAD };
+    char *p;
+    struct lonstr *lp;
+    char prompt[128];
+    char buf[1024];
 
-       bzero((s_char *)ltcp, sizeof (*ltcp));
-       if (getstarg(player->argp[1], "loan or treaty? ", buf) == 0)
-               return RET_SYN;
-       ltcp->type = ef_byname(buf);
-       switch (ltcp->type) {
-       case EF_TREATY:
-               if (!opt_TREATIES) {
-                   pr("Treaties are not enabled.\n");
-                   return RET_FAIL;
-               }
-               ltcp->name = "treaty";
-               ltcp->Name = "Treaty";
-               dis = distrea;
-               break;
-       case EF_LOAN:
-               if (!opt_LOANS) {
-                   pr("Loans are not enabled.\n");
-                   return RET_FAIL;
-               }
-               ltcp->name = "loan";
-               ltcp->Name = "Loan";
-               dis = disloan;
-               break;
-       default:
-               pr("You must specify \"loan\" or \"treaty\".\n");
-               return RET_SYN;
+    memset(ltcp, 0, sizeof(*ltcp));
+    p = player->argp[1] ? player->argp[1] : "loan";
+    ltcp->type = ef_byname_from(p, lon_or_trt);
+    switch (ltcp->type) {
+    case EF_LOAN:
+       if (!opt_LOANS) {
+           pr("Loans are not enabled.\n");
+           return RET_FAIL;
        }
-       sprintf(prompt, "%s number? ", ltcp->Name);
-       if ((ltcp->num = onearg(player->argp[2], prompt)) < 0)
-               return RET_SYN;
-       if (!ef_read(ltcp->type, ltcp->num, (caddr_t)&ltcp->u) ||
-           !(*dis)(ltcp->num, &ltcp->u)) {
-               pr("%s #%d is not being offered to you!\n",
-                       ltcp->Name, ltcp->num);
-               return RET_SYN;
-       }
-       switch (ltcp->type) {
-       case EF_LOAN:
-               lp = &ltcp->u.l;
-               if (lp->l_status == LS_SIGNED) {
-                       pr("That loan has already been accepted!\n");
-                       return RET_FAIL;
-               }
-               ltcp->proposer = lp->l_loner;
-               ltcp->proposee = lp->l_lonee;
-               break;
-       case EF_TREATY:
-               tp = &ltcp->u.t;
-               if (tp->trt_status == TS_SIGNED) {
-                       pr("That treaty has already been accepted!\n");
-                       return RET_FAIL;
-               }
-               ltcp->proposer = tp->trt_cna;
-               ltcp->proposee = tp->trt_cnb;
-               break;
-       }
-       ltcp->mailee = (ltcp->proposer == player->cnum)
-               ? ltcp->proposee : ltcp->proposer;
-       while ((p = getstarg(player->argp[3], "Accept, decline or postpone? ", buf)) && *p) 
-{
-               if (*p == 'a' || *p == 'd' || *p == 'p')
-                       break;
-               player->argp[3] = 0;
+       ltcp->name = "loan";
+       ltcp->Name = "Loan";
+       break;
+    default:
+       pr("You must specify \"loan\".\n");
+       return RET_SYN;
+    }
+    sprintf(prompt, "%s number? ", ltcp->Name);
+    if ((ltcp->num = onearg(player->argp[2], prompt)) < 0)
+       return RET_SYN;
+    if (!ef_read(ltcp->type, ltcp->num, &ltcp->u) || !cons_display(ltcp)) {
+       pr("%s #%d is not being offered to you!\n", ltcp->Name, ltcp->num);
+       return RET_SYN;
+    }
+    switch (ltcp->type) {
+    case EF_LOAN:
+       lp = &ltcp->u.l;
+       if (lp->l_status == LS_SIGNED) {
+           pr("That loan has already been accepted!\n");
+           return RET_FAIL;
        }
-       if (p == 0 || *p == 0)
-               return RET_SYN;
-       ltcp->op = *p;
-       return RET_OK;
+       ltcp->proposer = lp->l_loner;
+       ltcp->proposee = lp->l_lonee;
+       break;
+    }
+    ltcp->mailee = (ltcp->proposer == player->cnum)
+       ? ltcp->proposee : ltcp->proposer;
+    p = getstarg(player->argp[3], "Accept, decline or postpone? ", buf);
+    if (!p || (*p != 'a' && *p != 'd' && *p != 'p'))
+       return RET_SYN;
+    ltcp->op = *p;
+    return RET_OK;
 }
 
-/*
- * Accept a loan.  If the offering country has too little money,
- * leave him $100 left and offer the rest.  Return RET_OK on
- * success, anything else on error.
- */
 static int
-loan_accept(struct ltcomstr *ltcp)
+cons_display(struct ltcomstr *ltcp)
 {
-       struct  lonstr *lp;
-       struct  natstr *lender;
-       struct  nstr_item nstr;
-       struct  lonstr loan;
-
-       lp = &ltcp->u.l;
-       if (ltcp->proposee != player->cnum) {
-               pr("%s %d is still pending.\n", ltcp->Name, ltcp->num);
-               return RET_OK;
-       }
-       if (!getloan(ltcp->num, (caddr_t)lp)) {
-               pr("loan_accept: can't read loan; get help!\n");
-               return RET_SYS;
-       }
-       if (lp->l_status == LS_FREE) {  /* other guy retratcted already */
-               late(ltcp);
-               return RET_OK;
-       }
-       if (lp->l_status == LS_SIGNED) { /* already signed somehow */
-               prev_signed(ltcp);
-               return RET_OK;
-       }
-       /* check to see if a loan already exists */
-       snxtitem_all(&nstr, EF_LOAN);
-       while (nxtitem(&nstr, (s_char *) &loan)) {
-               if (loan.l_status == LS_SIGNED && loan.l_lonee == lp->l_loner
-                                       && (loan.l_loner == lp->l_lonee)) {
-                 pr("He already owes you money - make him repay his loan!\n");
-                       return RET_OK;
-               }
-       }
-       lender = getnatp(ltcp->proposer);
-       if (lender->nat_money < lp->l_amtdue) { /* other guy is poor */
-               lp->l_amtdue = lender->nat_money - 100;
-               pr("%s no longer has the funds.\n", cname(ltcp->proposer));
-               if (lp->l_amtdue <= 0)
-                       return RET_FAIL;
-               pr("You may borrow $%d at the same terms.\n",
-                       lp->l_amtdue);
-       }
-       lender->nat_money -= lp->l_amtdue;
-       putnat(lender);
-       player->dolcost -= lp->l_amtdue;
-       lp->l_amtpaid = 0;
-       (void) time(&lp->l_lastpay);
-       lp->l_duedate = lp->l_ldur * 86400 + lp->l_lastpay;
-       lp->l_status = LS_SIGNED;
-       if (!putloan(ltcp->num, (s_char *)lp)) {
-               pr("Problem writing lp->to disk; get help!\n");
-               return RET_FAIL;
-       }
-       accpt(ltcp);
-       pr("You are now $%d richer (sort of).\n", lp->l_amtdue);
-       return RET_OK;
+    switch (ltcp->type) {
+    case EF_LOAN:
+       return disloan(ltcp->num, &ltcp->u.l);
+    default:
+       CANT_REACH();
+       return 0;
+    }
 }
 
-/*
- * Declne a loan.  Return RET_OK on success, anything else on error.
- */
 static int
-loan_decline(struct ltcomstr *ltcp)
+cons_accept(struct ltcomstr *ltcp)
 {
-       struct  lonstr *lp;
-
-       lp = &ltcp->u.l;
-       if (!getloan(ltcp->num, lp)) {
-               pr("Decline: can't read loan; get help!\n");
-               return RET_SYS;
-       }
-       /* loan got accepted somehow between now and last time we checked */
-       if (lp->l_status == LS_SIGNED) {
-               late(ltcp);
-               return RET_OK;
-       }
-       lp->l_status = LS_FREE;
-       if (!putloan(ltcp->num, lp)) {
-               pr("loan_decline: can't write loan; get help!\n");
-               return RET_SYS;
-       }
-       decline(ltcp);
-       return RET_OK;
+    switch (ltcp->type) {
+    case EF_LOAN:
+       return loan_accept(ltcp);
+    default:
+       CANT_REACH();
+       return RET_FAIL;
+    }
 }
 
-/*
- * Accept a treaty.  Return RET_OK on success, anything else on error.
- */
 static int
-treaty_accept(struct ltcomstr *ltcp)
+cons_decline(struct ltcomstr *ltcp)
 {
-       struct  trtstr *tp;
+    switch (ltcp->type) {
+    case EF_LOAN:
+       return loan_decline(ltcp);
+    default:
+       CANT_REACH();
+       return RET_FAIL;
+    }
+}
 
-       tp = &ltcp->u.t;
-       if (ltcp->proposee != player->cnum) {
-               pr("%s %d is still pending.\n", ltcp->Name, ltcp->num);
-               return RET_OK;
-       }
-       if (!gettre(ltcp->num, tp)) {
-               pr("Accept: can't read treaty; get help!\n");
-               return RET_SYS;
-       }
-       if (tp->trt_status == TS_FREE) {        /* treaty offer withdrawn */
-               late(ltcp);
-               return RET_OK;
-       }
-       if (tp->trt_status == TS_SIGNED) {      /* somehow got accepted */
-               prev_signed(ltcp);
-               return RET_OK;
-       }
-       tp->trt_status = TS_SIGNED;
-       if (!puttre(ltcp->num, tp)) {
-               pr("Problem saving treaty; get help!\n");
-               return RET_SYS;
-       }
-       accpt(ltcp);
-       pr("Treaty in effect until %s", ctime(&tp->trt_exp));
-       return RET_OK;
+static int
+cons_postpone(struct ltcomstr *ltcp)
+{
+    pr("%s %d is still pending.\n", ltcp->Name, ltcp->num);
+    if (ltcp->proposee == player->cnum)
+       wu(0, ltcp->proposer, "%s %d considered by %s\n",
+          ltcp->name, ltcp->num, cname(player->cnum));
+    return RET_OK;
 }
 
 /*
- * Decline a treaty.  Return RET_OK on success, anything else on error.
+ * Accept a loan.  If the offering country has too little money,
+ * leave him $100 left and offer the rest.  Return RET_OK on
+ * success, anything else on error.
  */
 static int
-treaty_decline(struct ltcomstr *ltcp)
+loan_accept(struct ltcomstr *ltcp)
 {
-       struct  trtstr *tp;
+    struct lonstr *lp;
+    struct natstr *lender;
+    struct nstr_item nstr;
+    struct lonstr loan;
 
-       tp = &ltcp->u.t;
-       if (!gettre(ltcp->num, tp)) {
-               pr("Decline: can't read treaty; get help!\n");
-               return RET_SYS;
-       }
-       /* treaty got signed somehow between now and last time we read it */
-       if (tp->trt_status == TS_SIGNED) {
-               late(ltcp);
-               return RET_OK;
-       }
-       tp->trt_status = TS_FREE;
-       if (!puttre(ltcp->num, tp)) {
-               pr("Problem saving treaty; get help!\n");
-               return RET_SYS;
-       }
-       decline(ltcp);
+    lp = &ltcp->u.l;
+    if (ltcp->proposee != player->cnum) {
+       pr("%s %d is still pending.\n", ltcp->Name, ltcp->num);
+       return RET_OK;
+    }
+    if (!getloan(ltcp->num, lp)) {
+       logerror("loan_accept: can't read loan");
+       pr("can't read loan; get help!\n");
+       return RET_FAIL;
+    }
+    if (lp->l_status == LS_FREE) {     /* other guy retratcted already */
+       late(ltcp);
        return RET_OK;
+    }
+    if (lp->l_status == LS_SIGNED) {   /* already signed somehow */
+       prev_signed(ltcp);
+       return RET_OK;
+    }
+    /* check to see if a loan already exists */
+    snxtitem_all(&nstr, EF_LOAN);
+    while (nxtitem(&nstr, &loan)) {
+       if (loan.l_status == LS_SIGNED && loan.l_lonee == lp->l_loner
+           && (loan.l_loner == lp->l_lonee)) {
+           pr("He already owes you money - make him repay his loan!\n");
+           return RET_OK;
+       }
+    }
+    lender = getnatp(ltcp->proposer);
+    if (lender->nat_money < lp->l_amtdue) {    /* other guy is poor */
+       lp->l_amtdue = lender->nat_money - 100;
+       pr("%s no longer has the funds.\n", cname(ltcp->proposer));
+       if (lp->l_amtdue <= 0)
+           return RET_FAIL;
+       pr("You may borrow $%d at the same terms.\n", lp->l_amtdue);
+    }
+    lender->nat_money -= lp->l_amtdue;
+    putnat(lender);
+    player->dolcost -= lp->l_amtdue;
+    lp->l_amtpaid = 0;
+    (void)time(&lp->l_lastpay);
+    lp->l_duedate = lp->l_ldur * SECS_PER_DAY + lp->l_lastpay;
+    lp->l_status = LS_SIGNED;
+    if (!putloan(ltcp->num, lp)) {
+       pr("Problem writing lp->to disk; get help!\n");
+       return RET_FAIL;
+    }
+    accpt(ltcp);
+    pr("You are now $%d richer (sort of).\n", lp->l_amtdue);
+    return RET_OK;
 }
 
 /*
- * Postpone a treaty; always succeeds.
+ * Decline a loan.  Return RET_OK on success, anything else on error.
  */
 static int
-postpone(struct ltcomstr *ltcp)
+loan_decline(struct ltcomstr *ltcp)
 {
-       pr("%s %d is still pending.\n", ltcp->Name, ltcp->num);
-       if (ltcp->proposee == player->cnum)
-               wu(0, ltcp->proposer, "%s %d considered by %s\n",
-                       ltcp->name, ltcp->num, cname(player->cnum));
+    struct lonstr *lp;
+
+    lp = &ltcp->u.l;
+    if (!getloan(ltcp->num, lp)) {
+       logerror("loan_decline: can't read loan");
+       pr("can't read loan; get help!\n");
+       return RET_FAIL;
+    }
+    /* loan got accepted somehow between now and last time we checked */
+    if (lp->l_status == LS_SIGNED) {
+       late(ltcp);
        return RET_OK;
+    }
+    lp->l_status = LS_FREE;
+    if (!putloan(ltcp->num, lp)) {
+       logerror("loan_decline: can't write loan");
+       pr("can't write loan; get help!\n");
+       return RET_FAIL;
+    }
+    decline(ltcp);
+    return RET_OK;
 }
 
 /*
- * Somebody tried to accept a loan/treaty that was retracted,
- * or to decline a loan/treaty they already signed.
+ * Somebody tried to accept a loan that was retracted,
+ * or to decline a loan they already signed.
  */
 static void
 late(struct ltcomstr *ltcp)
 {
-       pr("Too late; that %s %s!\n", ltcp->name,
-               (ltcp->op == 'a') ? "is no longer being offered"
-                                 : "has already been accepted");
+    pr("Too late; that %s %s!\n", ltcp->name,
+       (ltcp->op == 'a') ? "is no longer being offered"
+       : "has already been accepted");
 }
 
 /*
- * Loan or treaty was previously signed.
+ * Loan was previously signed.
  */
 static void
 prev_signed(struct ltcomstr *ltcp)
 {
-       pr("%s #%d is already in effect.\n", ltcp->Name, ltcp->num);
+    pr("%s #%d is already in effect.\n", ltcp->Name, ltcp->num);
 }
 
 /*
- * Post-processing after successful declination of loan or treaty.
+ * Post-processing after successful declination of loan.
  * Notify the folks involved.
  */
 static void
 decline(struct ltcomstr *ltcp)
 {
-       if (ltcp->proposee == player->cnum) {
-               wu(0, ltcp->proposer, "%s %d refused by %s\n",
-                       ltcp->Name, ltcp->num, cname(player->cnum));
-               pr("%s %d refused.\n", ltcp->Name, ltcp->num);
-       } else {
-               wu(0, ltcp->proposee,
-                       "%s offer %d retracted by %s\n",
-                       ltcp->Name, ltcp->num, cname(player->cnum));
-               pr("%s offer %d retracted.\n",
-                       ltcp->Name, ltcp->num);
-       }
+    if (ltcp->proposee == player->cnum) {
+       wu(0, ltcp->proposer, "%s %d refused by %s\n",
+          ltcp->Name, ltcp->num, cname(player->cnum));
+       pr("%s %d refused.\n", ltcp->Name, ltcp->num);
+    } else {
+       wu(0, ltcp->proposee,
+          "%s offer %d retracted by %s\n",
+          ltcp->Name, ltcp->num, cname(player->cnum));
+       pr("%s offer %d retracted.\n", ltcp->Name, ltcp->num);
+    }
 }
 
 /*
- * Post-processing after successful acceptance of loan or treaty.
+ * 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)
 {
-       if (ltcp->type == EF_LOAN)
-               nreport(ltcp->proposer, N_MAKE_LOAN, player->cnum, 1);
-       else
-               nreport(player->cnum, N_SIGN_TRE, ltcp->mailee, 1);
-       wu(0, ltcp->mailee, "%s #%d accepted by %s\n",
-               ltcp->Name, ltcp->num, cname(player->cnum));
+    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));
 }