]> git.pond.sub.org Git - empserver/blob - src/lib/commands/offe.c
01570b596ca72a7d1a0d6a74c82b04be5bc2de7b
[empserver] / src / lib / commands / offe.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  offe.c: Offer a loan or treaty
29  *
30  *  Known contributors to this file:
31  *     Pat Loney, 1992
32  *     Steve McClure, 1996
33  */
34
35 #include <config.h>
36
37 #include "commands.h"
38 #include "loan.h"
39 #include "optlist.h"
40 #include "treaty.h"
41
42 static int do_treaty(void);
43 static int do_loan(void);
44
45 int
46 offe(void)
47 {
48     char *cp;
49     char buf[1024];
50
51     if (!(cp = getstarg(player->argp[1], "loan or treaty? ", buf)) || !*cp)
52         return RET_SYN;
53
54     switch (*cp) {
55     case 'l':
56         if (!opt_LOANS) {
57             pr("Loans are not enabled.\n");
58             return RET_FAIL;
59         }
60         return do_loan();
61     case 't':
62         if (!opt_TREATIES) {
63             pr("Treaties are not enabled.\n");
64             return RET_FAIL;
65         }
66         return do_treaty();
67     default:
68         pr("You must specify \"loan\" as there are no treaties.\n");
69         return RET_SYN;
70     }
71 }
72
73 static int
74 do_treaty(void)
75 {
76     char *cp;
77     int ourcond, theircond;
78     struct symbol *tfp;
79     struct trtstr trty;
80     struct nstr_item nstr;
81     natid recipient;
82     time_t now;
83     int j, n;
84     struct natstr *natp;
85     char prompt[128];
86     char buf[1024];
87
88     if ((n = natarg(player->argp[2], "Treaty offered to? ")) < 0)
89         return RET_SYN;
90     recipient = n;
91     if (recipient == player->cnum) {
92         pr("You can't sign a treaty with yourself!\n");
93         return RET_FAIL;
94     }
95     natp = getnatp(recipient);
96     if (player->cnum && (getrejects(player->cnum, natp) & REJ_TREA)) {
97         pr("%s is rejecting your treaties.\n", cname(recipient));
98         return RET_SYN;
99     }
100     pr("Terms for %s:\n", cname(recipient));
101     theircond = 0;
102     for (tfp = treaty_flags; tfp && tfp->name; tfp++) {
103         sprintf(prompt, "%s? ", tfp->name);
104         if ((cp = getstring(prompt, buf)) == 0)
105             return RET_FAIL;
106         if (*cp == 'y')
107             theircond |= tfp->value;
108     }
109     pr("Terms for you:\n");
110     ourcond = 0;
111     for (tfp = treaty_flags; tfp && tfp->name; tfp++) {
112         sprintf(prompt, "%s? ", tfp->name);
113         if ((cp = getstring(prompt, buf)) == 0)
114             return RET_FAIL;
115         if (*cp == 'y')
116             ourcond |= tfp->value;
117     }
118     if (ourcond == 0 && theircond == 0) {
119         pr("Treaties with no clauses aren't very useful, boss!\n");
120         return RET_SYN;
121     }
122     cp = getstring("Proposed treaty duration? (days) ", buf);
123     if (cp == 0)
124         return RET_FAIL;
125     j = atoi(cp);
126     if (j <= 0) {
127         pr("Bad treaty duration.\n");
128         return RET_SYN;
129     }
130     (void)time(&now);
131     snxtitem_all(&nstr, EF_TREATY);
132     while (nxtitem(&nstr, &trty)) {
133         if (trty.trt_status == TS_FREE) {
134             break;
135         }
136     }
137     ef_blank(EF_TREATY, nstr.cur, &trty);
138     trty.trt_acond = ourcond;
139     trty.trt_bcond = theircond;
140     trty.trt_status = TS_PROPOSED;
141     trty.trt_cna = player->cnum;
142     trty.trt_cnb = recipient;
143     trty.trt_exp = j * SECS_PER_DAY + now;
144     if (!puttre(nstr.cur, &trty)) {
145         logerror("do_treaty: can't write treaty");
146         pr("Couldn't save treaty; get help.\n");
147         return RET_FAIL;
148     }
149     wu(0, recipient, "Treaty #%d proposed to you by %s\n",
150        nstr.cur, cname(player->cnum));
151     pr("You have proposed treaty #%d\n", nstr.cur);
152     return RET_OK;
153 }
154
155 static int
156 do_loan(void)
157 {
158     int amt, irate, dur, maxloan;
159     struct nstr_item nstr;
160     struct natstr *natp;
161     struct lonstr loan;
162     natid recipient;
163     int n;
164     char prompt[128];
165
166     if ((n = natarg(player->argp[2], "Lend to? ")) < 0)
167         return RET_SYN;
168     recipient = n;
169     if (recipient == player->cnum) {
170         pr("You can't loan yourself money!\n");
171         return RET_FAIL;
172     }
173     natp = getnatp(recipient);
174     if (player->cnum && (getrejects(player->cnum, natp) & REJ_LOAN)) {
175         pr("%s is rejecting your loans.\n", cname(recipient));
176         return RET_SYN;
177     }
178     natp = getnatp(player->cnum);
179     if (natp->nat_money + 100 > MAXLOAN)
180         maxloan = MAXLOAN;
181     else
182         maxloan = natp->nat_money - 100;
183     if (maxloan < 0) {
184         pr("You don't have enough money to loan!\n");
185         return RET_FAIL;
186     }
187     sprintf(prompt, "Size of loan for country #%d? (max %d) ",
188             recipient, maxloan);
189     amt = onearg(player->argp[3], prompt);
190     if (amt <= 0)
191         return RET_FAIL;
192     if (amt > MAXLOAN) {
193         pr("You can only loan $%d at a time.\n", MAXLOAN);
194         return RET_FAIL;
195     }
196     if (amt > maxloan) {
197         pr("You can't afford that much.\n");
198         return RET_FAIL;
199     }
200     dur = onearg(player->argp[4], "Duration? (days, max 7) ");
201     if (dur <= 0)
202         return RET_FAIL;
203     if (dur > 7)
204         return RET_FAIL;
205     irate = onearg(player->argp[5], "Interest rate? (from 5 to 25%) ");
206     if (irate > 25)
207         return RET_FAIL;
208     if (irate < 5)
209         return RET_FAIL;
210     snxtitem_all(&nstr, EF_LOAN);
211     while (nxtitem(&nstr, &loan)) {
212         if ((loan.l_status == LS_SIGNED) && (loan.l_lonee == player->cnum)
213             && (loan.l_loner == recipient)) {
214             pr("You already owe HIM money - how about repaying your loan?\n");
215             return RET_FAIL;
216         }
217     }
218     snxtitem_all(&nstr, EF_LOAN);
219     while (nxtitem(&nstr, &loan)) {
220         if (loan.l_status == LS_FREE)
221             break;
222     }
223     ef_blank(EF_LOAN, nstr.cur, &loan);
224     loan.l_loner = player->cnum;
225     loan.l_lonee = recipient;
226     loan.l_status = LS_PROPOSED;
227     loan.l_irate = MIN(irate, 127);
228     loan.l_ldur = MIN(dur, 127);
229     loan.l_amtpaid = 0;
230     loan.l_amtdue = amt;
231     (void)time(&loan.l_lastpay);
232     loan.l_duedate = loan.l_ldur * SECS_PER_DAY + loan.l_lastpay;
233     if (!putloan(nstr.cur, &loan)) {
234         logerror("do_loan: can't save loan");
235         pr("Couldn't save loan; get help!\n");
236         return RET_FAIL;
237     }
238     pr("You have offered loan %d\n", nstr.cur);
239     wu(0, recipient, "Country #%d has offered you a loan (#%d)\n",
240        player->cnum, nstr.cur);
241     return RET_OK;
242 }