src/lib/commands/new.c

Go to the documentation of this file.
00001 /*
00002  *  Empire - A multi-player, client/server Internet based war game.
00003  *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
00004  *                           Ken Stevens, Steve McClure
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  *  ---
00021  *
00022  *  See files README, COPYING and CREDITS in the root of the source
00023  *  tree for related information and legal notices.  It is expected
00024  *  that future projects/authors will amend these files as needed.
00025  *
00026  *  ---
00027  *
00028  *  new.c: Create a new capital for a player
00029  * 
00030  *  Known contributors to this file:
00031  *     Dave Pare, 1986
00032  */
00033 
00034 #include <config.h>
00035 
00036 #include <fcntl.h>
00037 #include <sys/stat.h>
00038 #include <unistd.h>
00039 #include "commands.h"
00040 #include "land.h"
00041 #include "optlist.h"
00042 #include "path.h"
00043 #include "prototypes.h"
00044 #include "tel.h"
00045 
00046 static int isok(int x, int y);
00047 static void ok(signed char *map, int x, int y);
00048 static void init_sanct(struct natstr *, coord, coord);
00049 
00050 static struct range defrealm = { -8, -5, 10, 5, 0, 0 };
00051 
00052 #define MAXAVAIL        300
00053 
00054 int
00055 new(void)
00056 {
00057     struct sctstr sect;
00058     struct natstr *natp;
00059     struct realmstr newrealm;
00060     struct range absrealm;
00061     natid num;
00062     coord x, y;
00063     int i;
00064     char *p;
00065     char buf[1024];
00066     time_t current_time = time(NULL);
00067 
00068     natp = getnatp(player->cnum);
00069     if (natp->nat_xorg != 0 || natp->nat_yorg != 0) {
00070         pr("Must be at 0,0 to add a new country\n");
00071         return RET_FAIL;
00072     }
00073     if (!(natp = natargp(player->argp[1], "Country? ")))
00074         return RET_SYN;
00075     num = natp->nat_cnum;
00076     if (natp->nat_stat != STAT_NEW) {
00077         pr("Country #%d (%s) isn't a new country!\n", num, cname(num));
00078         return RET_SYN;
00079     }
00080     if (player->argp[2] != 0) {
00081         if ((p = getstarg(player->argp[2], "sanctuary pair : ", buf)) == 0)
00082             return RET_SYN;
00083         if (!sarg_xy(p, &x, &y) || !getsect(x, y, &sect))
00084             return RET_SYN;
00085         if (sect.sct_type != SCT_RURAL) {
00086             pr("%s is a %s; try again...\n",
00087                xyas(x, y, player->cnum), dchr[sect.sct_type].d_name);
00088             return RET_SYN;
00089         }
00090         getsect(x + 2, y, &sect);
00091         if (sect.sct_type != SCT_RURAL) {
00092             pr("%s is a %s; try again...\n",
00093                xyas(x + 2, y, player->cnum), dchr[sect.sct_type].d_name);
00094             return RET_SYN;
00095         }
00096     } else {
00097         for (i = 0; i < 300 && !player->aborted; i++) {
00098             /* Both x and y should be either odd or even */
00099             x = (random() % WORLD_X) - (WORLD_X / 2);
00100             y = (((random() % WORLD_Y) - (WORLD_Y / 2)) & ~1) | (x & 1);
00101             /*
00102              * If either of the two potential
00103              * sanctuary sectors are already
00104              * owned by someone else, pick
00105              * another place on the map.
00106              */
00107             getsect(x, y, &sect);
00108             if (sect.sct_type == SCT_WATER || sect.sct_own != 0)
00109                 continue;
00110             getsect(x + 2, y, &sect);
00111             if (sect.sct_type == SCT_WATER || sect.sct_own != 0)
00112                 continue;
00113             if (isok(x, y))
00114                 break;
00115         }
00116         if (i == 300) {
00117             pr("couldn't find an empty slot!\n");
00118             return RET_FAIL;
00119         }
00120     }
00121 
00122     if (player->aborted)
00123         return RET_FAIL;
00124     pr("added country %d at %s\n", num, xyas(x, y, player->cnum));
00125     natp->nat_btu = max_btus;
00126     natp->nat_stat = STAT_SANCT;
00127     natp->nat_xcap = x;
00128     natp->nat_ycap = y;
00129     natp->nat_xorg = x;
00130     natp->nat_yorg = y;
00131     xyabsrange(natp, &defrealm, &absrealm);
00132     for (i = 0; i < MAXNOR; i++) {
00133         getrealm(i, num, &newrealm);
00134         newrealm.r_xl = absrealm.lx;
00135         newrealm.r_xh = absrealm.hx;
00136         newrealm.r_yl = absrealm.ly;
00137         newrealm.r_yh = absrealm.hy;
00138         newrealm.r_timestamp = current_time;
00139         putrealm(&newrealm);
00140     }
00141     if (players_at_00) {
00142         natp->nat_xorg = 0;
00143         natp->nat_yorg = 0;
00144     }
00145     natp->nat_money = start_cash;
00146     natp->nat_level[NAT_HLEV] = start_happiness;
00147     natp->nat_level[NAT_RLEV] = start_research;
00148     natp->nat_level[NAT_TLEV] = start_technology;
00149     natp->nat_level[NAT_ELEV] = start_education;
00150     natp->nat_tgms = 0;
00151     close(creat(mailbox(buf, num), S_IRWUG));
00152     init_sanct(natp, x, y);
00153     init_sanct(natp, x + 2, y);
00154     putnat(natp);
00155     return RET_OK;
00156 }
00157 
00158 static void
00159 init_sanct(struct natstr *natp, coord x, coord y)
00160 {
00161     struct sctstr sect;
00162 
00163     getsect(x, y, &sect);
00164     sect.sct_own = natp->nat_cnum;
00165     sect.sct_type = SCT_SANCT;
00166     sect.sct_newtype = SCT_SANCT;
00167     sect.sct_effic = 100;
00168     sect.sct_road = 0;
00169     sect.sct_rail = 0;
00170     sect.sct_defense = 0;
00171     sect.sct_mobil = startmob;
00172     sect.sct_work = 100;
00173     sect.sct_oldown = natp->nat_cnum;
00174     if (at_least_one_100) {
00175         sect.sct_oil = 100;
00176         sect.sct_fertil = 100;
00177         sect.sct_uran = 100;
00178         sect.sct_min = 100;
00179         sect.sct_gmin = 100;
00180     }
00181     sect.sct_item[I_CIVIL] = max_pop(start_research, &sect);
00182     sect.sct_item[I_MILIT] = 55;
00183     sect.sct_item[I_FOOD] = opt_NOFOOD ? 0 : 550;
00184     sect.sct_item[I_UW] = 75;
00185     putsect(&sect);
00186 }
00187 
00188 static int nmin, ngold, noil, nur;
00189 static int nfree, navail, nowned;
00190 
00191 static int
00192 isok(int x, int y)
00193 {
00194     signed char *map;
00195     char *p;
00196     char buf[1024];
00197 
00198     nmin = ngold = noil = nur = 0;
00199     navail = nfree = nowned = 0;
00200     if (!(map = malloc(WORLD_SZ()))) {
00201         logerror("malloc failed in isok\n");
00202         pr("Memory error.  Tell the deity.\n");
00203         return 0;
00204     }
00205     memset(map, 0, WORLD_SZ());
00206     ok(map, x, y);
00207     free(map);
00208     if (nfree < 5)
00209         return 0;
00210     pr("Cap at %s; owned sectors: %d, free sectors: %d, avail: %d\n",
00211        xyas(x, y, player->cnum), nowned, nfree, navail);
00212     pr("min: %d, oil: %d, gold: %d, uranium: %d\n",
00213        nmin, noil, ngold, nur);
00214     p = getstring("This setup ok? ", buf);
00215     if (p == 0 || *p != 'y')
00216         return 0;
00217     return 1;
00218 }
00219 
00220 static void
00221 ok(signed char *map, int x, int y)
00222 {
00223     struct sctstr sect;
00224     int dir;
00225     int id;
00226 
00227     if (navail > MAXAVAIL)
00228         return;
00229     id = sctoff(x, y);
00230     if (map[id])
00231         return;
00232     if (!ef_read(EF_SECTOR, id, &sect))
00233         return;
00234     if (sect.sct_type == SCT_WATER || sect.sct_type == SCT_BSPAN)
00235         return;
00236     navail++;
00237     if (navail >= MAXAVAIL) {
00238         pr("At least %d...\n", MAXAVAIL);
00239         return;
00240     }
00241     if (sect.sct_type != SCT_MOUNT && sect.sct_type != SCT_PLAINS) {
00242         if (sect.sct_own == 0)
00243             nfree++;
00244         else
00245             nowned++;
00246         if (sect.sct_min > 9)
00247             nmin++;
00248         if (sect.sct_gmin > 9)
00249             ngold++;
00250         if (sect.sct_uran > 9)
00251             nur++;
00252         if (sect.sct_oil > 9)
00253             noil++;
00254     }
00255     map[id] = 1;
00256     for (dir = DIR_FIRST; dir <= DIR_LAST; dir++)
00257         ok(map, diroff[dir][0] + x, diroff[dir][1] + y);
00258 }

Generated on Fri Mar 28 11:01:12 2008 for empserver by  doxygen 1.5.2