1*6fb30065Schristos /* $NetBSD: setup.c,v 1.10 2009/03/31 18:48:16 christos Exp $ */ 2887dd216Scgd 361f28255Scgd /* 4887dd216Scgd * Copyright (c) 1980, 1993 5887dd216Scgd * The Regents of the University of California. All rights reserved. 661f28255Scgd * 761f28255Scgd * Redistribution and use in source and binary forms, with or without 861f28255Scgd * modification, are permitted provided that the following conditions 961f28255Scgd * are met: 1061f28255Scgd * 1. Redistributions of source code must retain the above copyright 1161f28255Scgd * notice, this list of conditions and the following disclaimer. 1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright 1361f28255Scgd * notice, this list of conditions and the following disclaimer in the 1461f28255Scgd * documentation and/or other materials provided with the distribution. 15e5aeb4eaSagc * 3. Neither the name of the University nor the names of its contributors 1661f28255Scgd * may be used to endorse or promote products derived from this software 1761f28255Scgd * without specific prior written permission. 1861f28255Scgd * 1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2961f28255Scgd * SUCH DAMAGE. 3061f28255Scgd */ 3161f28255Scgd 32ef383c95Schristos #include <sys/cdefs.h> 3361f28255Scgd #ifndef lint 34887dd216Scgd #if 0 35887dd216Scgd static char sccsid[] = "@(#)setup.c 8.1 (Berkeley) 5/31/93"; 36887dd216Scgd #else 37*6fb30065Schristos __RCSID("$NetBSD: setup.c,v 1.10 2009/03/31 18:48:16 christos Exp $"); 38887dd216Scgd #endif 3961f28255Scgd #endif /* not lint */ 4061f28255Scgd 41ef383c95Schristos #include <stdio.h> 42ef383c95Schristos #include <math.h> 4332330650Smatt #include <string.h> 44ef383c95Schristos #include <unistd.h> 45ef383c95Schristos #include <stdlib.h> 46ef383c95Schristos #include <err.h> 47*6fb30065Schristos #include <limits.h> 4861f28255Scgd #include "trek.h" 4961f28255Scgd #include "getpar.h" 5061f28255Scgd 5161f28255Scgd /* 5261f28255Scgd ** INITIALIZE THE GAME 5361f28255Scgd ** 5461f28255Scgd ** The length, skill, and password are read, and the game 5561f28255Scgd ** is initialized. It is far too difficult to describe all 5661f28255Scgd ** that goes on in here, but it is all straight-line code; 5761f28255Scgd ** give it a look. 5861f28255Scgd ** 5961f28255Scgd ** Game restart and tournament games are handled here. 6061f28255Scgd */ 6161f28255Scgd 62b7e11e5cShubertf const struct cvntab Lentab[] = 6361f28255Scgd { 64ef383c95Schristos { "s", "hort", (cmdfun)1, 0 }, 65ef383c95Schristos { "m", "edium", (cmdfun)2, 0 }, 66ef383c95Schristos { "l", "ong", (cmdfun)4, 0 }, 67ef383c95Schristos { "restart", "", (cmdfun)0, 0 }, 68ef383c95Schristos { NULL, NULL, NULL, 0 } 6961f28255Scgd }; 7061f28255Scgd 71b7e11e5cShubertf const struct cvntab Skitab[] = 7261f28255Scgd { 73ef383c95Schristos { "n", "ovice", (cmdfun)1, 0 }, 74ef383c95Schristos { "f", "air", (cmdfun)2, 0 }, 75ef383c95Schristos { "g", "ood", (cmdfun)3, 0 }, 76ef383c95Schristos { "e", "xpert", (cmdfun)4, 0 }, 77ef383c95Schristos { "c", "ommodore", (cmdfun)5, 0 }, 78ef383c95Schristos { "i", "mpossible", (cmdfun)6, 0 }, 79ef383c95Schristos { NULL, NULL, NULL, 0 } 8061f28255Scgd }; 8161f28255Scgd 82ef383c95Schristos void 8361f28255Scgd setup() 8461f28255Scgd { 85b7e11e5cShubertf const struct cvntab *r; 86ef383c95Schristos int i, j; 8761f28255Scgd double f; 8861f28255Scgd int d; 8961f28255Scgd int klump; 9061f28255Scgd int ix, iy; 91ef383c95Schristos struct quad *q; 9261f28255Scgd struct event *e; 9361f28255Scgd 9461f28255Scgd while (1) 9561f28255Scgd { 9661f28255Scgd r = getcodpar("What length game", Lentab); 97c4816c32Scgd Game.length = (long) r->value; 9861f28255Scgd if (Game.length == 0) 9961f28255Scgd { 10061f28255Scgd if (restartgame()) 10161f28255Scgd continue; 10261f28255Scgd return; 10361f28255Scgd } 10461f28255Scgd break; 10561f28255Scgd } 10661f28255Scgd r = getcodpar("What skill game", Skitab); 107c4816c32Scgd Game.skill = (long) r->value; 10861f28255Scgd Game.tourn = 0; 10961f28255Scgd getstrpar("Enter a password", Game.passwd, 14, 0); 110ef383c95Schristos if (strcmp(Game.passwd, "tournament") == 0) 11161f28255Scgd { 11261f28255Scgd getstrpar("Enter tournament code", Game.passwd, 14, 0); 11361f28255Scgd Game.tourn = 1; 11461f28255Scgd d = 0; 11561f28255Scgd for (i = 0; Game.passwd[i]; i++) 11661f28255Scgd d += Game.passwd[i] << i; 11761f28255Scgd srand(d); 11861f28255Scgd } 11961f28255Scgd Param.bases = Now.bases = ranf(6 - Game.skill) + 2; 12061f28255Scgd if (Game.skill == 6) 12161f28255Scgd Param.bases = Now.bases = 1; 12261f28255Scgd Param.time = Now.time = 6.0 * Game.length + 2.0; 12361f28255Scgd i = Game.skill; 12461f28255Scgd j = Game.length; 12561f28255Scgd Param.klings = Now.klings = i * j * 3.5 * (franf() + 0.75); 12661f28255Scgd if (Param.klings < i * j * 5) 12761f28255Scgd Param.klings = Now.klings = i * j * 5; 12861f28255Scgd if (Param.klings <= i) /* numerical overflow problems */ 12961f28255Scgd Param.klings = Now.klings = 127; 13061f28255Scgd Param.energy = Ship.energy = 5000; 13161f28255Scgd Param.torped = Ship.torped = 10; 13261f28255Scgd Ship.ship = ENTERPRISE; 13361f28255Scgd Ship.shipname = "Enterprise"; 13461f28255Scgd Param.shield = Ship.shield = 1500; 13561f28255Scgd Param.resource = Now.resource = Param.klings * Param.time; 13661f28255Scgd Param.reserves = Ship.reserves = (6 - Game.skill) * 2.0; 13761f28255Scgd Param.crew = Ship.crew = 387; 13861f28255Scgd Param.brigfree = Ship.brigfree = 400; 13961f28255Scgd Ship.shldup = 1; 14061f28255Scgd Ship.cond = GREEN; 14161f28255Scgd Ship.warp = 5.0; 14261f28255Scgd Ship.warp2 = 25.0; 14361f28255Scgd Ship.warp3 = 125.0; 14461f28255Scgd Ship.sinsbad = 0; 14561f28255Scgd Ship.cloaked = 0; 14661f28255Scgd Param.date = Now.date = (ranf(20) + 20) * 100; 14761f28255Scgd f = Game.skill; 14861f28255Scgd f = log(f + 0.5); 14961f28255Scgd for (i = 0; i < NDEV; i++) 15061f28255Scgd if (Device[i].name[0] == '*') 15161f28255Scgd Param.damfac[i] = 0; 15261f28255Scgd else 15361f28255Scgd Param.damfac[i] = f; 15461f28255Scgd /* these probabilities must sum to 1000 */ 15561f28255Scgd Param.damprob[WARP] = 70; /* warp drive 7.0% */ 15661f28255Scgd Param.damprob[SRSCAN] = 110; /* short range scanners 11.0% */ 15761f28255Scgd Param.damprob[LRSCAN] = 110; /* long range scanners 11.0% */ 15861f28255Scgd Param.damprob[PHASER] = 125; /* phasers 12.5% */ 15961f28255Scgd Param.damprob[TORPED] = 125; /* photon torpedoes 12.5% */ 16061f28255Scgd Param.damprob[IMPULSE] = 75; /* impulse engines 7.5% */ 16161f28255Scgd Param.damprob[SHIELD] = 150; /* shield control 15.0% */ 16261f28255Scgd Param.damprob[COMPUTER] = 20; /* computer 2.0% */ 16361f28255Scgd Param.damprob[SSRADIO] = 35; /* subspace radio 3.5% */ 16461f28255Scgd Param.damprob[LIFESUP] = 30; /* life support 3.0% */ 16561f28255Scgd Param.damprob[SINS] = 20; /* navigation system 2.0% */ 16661f28255Scgd Param.damprob[CLOAK] = 50; /* cloaking device 5.0% */ 16761f28255Scgd Param.damprob[XPORTER] = 80; /* transporter 8.0% */ 16861f28255Scgd /* check to see that I didn't blow it */ 16961f28255Scgd for (i = j = 0; i < NDEV; i++) 17061f28255Scgd j += Param.damprob[i]; 17161f28255Scgd if (j != 1000) 172ef383c95Schristos errx(1, "Device probabilities sum to %d", j); 17361f28255Scgd Param.dockfac = 0.5; 17461f28255Scgd Param.regenfac = (5 - Game.skill) * 0.05; 17561f28255Scgd if (Param.regenfac < 0.0) 17661f28255Scgd Param.regenfac = 0.0; 17761f28255Scgd Param.warptime = 10; 17861f28255Scgd Param.stopengy = 50; 17961f28255Scgd Param.shupengy = 40; 18061f28255Scgd i = Game.skill; 18161f28255Scgd Param.klingpwr = 100 + 150 * i; 18261f28255Scgd if (i >= 6) 18361f28255Scgd Param.klingpwr += 150; 18461f28255Scgd Param.phasfac = 0.8; 18561f28255Scgd Param.hitfac = 0.5; 18661f28255Scgd Param.klingcrew = 200; 18761f28255Scgd Param.srndrprob = 0.0035; 18861f28255Scgd Param.moveprob[KM_OB] = 45; 18961f28255Scgd Param.movefac[KM_OB] = .09; 19061f28255Scgd Param.moveprob[KM_OA] = 40; 19161f28255Scgd Param.movefac[KM_OA] = -0.05; 19261f28255Scgd Param.moveprob[KM_EB] = 40; 19361f28255Scgd Param.movefac[KM_EB] = 0.075; 19461f28255Scgd Param.moveprob[KM_EA] = 25 + 5 * Game.skill; 19561f28255Scgd Param.movefac[KM_EA] = -0.06 * Game.skill; 19661f28255Scgd Param.moveprob[KM_LB] = 0; 19761f28255Scgd Param.movefac[KM_LB] = 0.0; 19861f28255Scgd Param.moveprob[KM_LA] = 10 + 10 * Game.skill; 19961f28255Scgd Param.movefac[KM_LA] = 0.25; 20061f28255Scgd Param.eventdly[E_SNOVA] = 0.5; 20161f28255Scgd Param.eventdly[E_LRTB] = 25.0; 20261f28255Scgd Param.eventdly[E_KATSB] = 1.0; 20361f28255Scgd Param.eventdly[E_KDESB] = 3.0; 20461f28255Scgd Param.eventdly[E_ISSUE] = 1.0; 20561f28255Scgd Param.eventdly[E_SNAP] = 0.5; 20661f28255Scgd Param.eventdly[E_ENSLV] = 0.5; 20761f28255Scgd Param.eventdly[E_REPRO] = 2.0; 20861f28255Scgd Param.navigcrud[0] = 1.50; 20961f28255Scgd Param.navigcrud[1] = 0.75; 21061f28255Scgd Param.cloakenergy = 1000; 21161f28255Scgd Param.energylow = 1000; 21261f28255Scgd for (i = 0; i < MAXEVENTS; i++) 21361f28255Scgd { 21461f28255Scgd e = &Event[i]; 215*6fb30065Schristos e->date = TOOLARGE; 21661f28255Scgd e->evcode = 0; 21761f28255Scgd } 21861f28255Scgd xsched(E_SNOVA, 1, 0, 0, 0); 21961f28255Scgd xsched(E_LRTB, Param.klings, 0, 0, 0); 22061f28255Scgd xsched(E_KATSB, 1, 0, 0, 0); 22161f28255Scgd xsched(E_ISSUE, 1, 0, 0, 0); 22261f28255Scgd xsched(E_SNAP, 1, 0, 0, 0); 22361f28255Scgd Ship.sectx = ranf(NSECTS); 22461f28255Scgd Ship.secty = ranf(NSECTS); 22561f28255Scgd Game.killk = Game.kills = Game.killb = 0; 22661f28255Scgd Game.deaths = Game.negenbar = 0; 22761f28255Scgd Game.captives = 0; 22861f28255Scgd Game.killinhab = 0; 22961f28255Scgd Game.helps = 0; 23061f28255Scgd Game.killed = 0; 23161f28255Scgd Game.snap = 0; 23261f28255Scgd Move.endgame = 0; 23361f28255Scgd 23461f28255Scgd /* setup stars */ 23561f28255Scgd for (i = 0; i < NQUADS; i++) 23661f28255Scgd for (j = 0; j < NQUADS; j++) 23761f28255Scgd { 238e62c2681Schristos short s5; 23961f28255Scgd q = &Quad[i][j]; 24061f28255Scgd q->klings = q->bases = 0; 24161f28255Scgd q->scanned = -1; 24261f28255Scgd q->stars = ranf(9) + 1; 243e62c2681Schristos q->holes = ranf(3); 244e62c2681Schristos s5 = q->stars / 5; 245e62c2681Schristos q->holes = q->holes > s5 ? q->holes - s5 : 0; 24661f28255Scgd q->qsystemname = 0; 24761f28255Scgd } 24861f28255Scgd 24961f28255Scgd /* select inhabited starsystems */ 25061f28255Scgd for (d = 1; d < NINHAB; d++) 25161f28255Scgd { 25261f28255Scgd do 25361f28255Scgd { 25461f28255Scgd i = ranf(NQUADS); 25561f28255Scgd j = ranf(NQUADS); 25661f28255Scgd q = &Quad[i][j]; 25761f28255Scgd } while (q->qsystemname); 25861f28255Scgd q->qsystemname = d; 25961f28255Scgd } 26061f28255Scgd 26161f28255Scgd /* position starbases */ 26261f28255Scgd for (i = 0; i < Param.bases; i++) 26361f28255Scgd { 26461f28255Scgd while (1) 26561f28255Scgd { 26661f28255Scgd ix = ranf(NQUADS); 26761f28255Scgd iy = ranf(NQUADS); 26861f28255Scgd q = &Quad[ix][iy]; 26961f28255Scgd if (q->bases > 0) 27061f28255Scgd continue; 27161f28255Scgd break; 27261f28255Scgd } 27361f28255Scgd q->bases = 1; 27461f28255Scgd Now.base[i].x = ix; 27561f28255Scgd Now.base[i].y = iy; 27661f28255Scgd q->scanned = 1001; 27761f28255Scgd /* start the Enterprise near starbase */ 27861f28255Scgd if (i == 0) 27961f28255Scgd { 28061f28255Scgd Ship.quadx = ix; 28161f28255Scgd Ship.quady = iy; 28261f28255Scgd } 28361f28255Scgd } 28461f28255Scgd 28561f28255Scgd /* position klingons */ 28661f28255Scgd for (i = Param.klings; i > 0; ) 28761f28255Scgd { 28861f28255Scgd klump = ranf(4) + 1; 28961f28255Scgd if (klump > i) 29061f28255Scgd klump = i; 29161f28255Scgd while (1) 29261f28255Scgd { 29361f28255Scgd ix = ranf(NQUADS); 29461f28255Scgd iy = ranf(NQUADS); 29561f28255Scgd q = &Quad[ix][iy]; 29661f28255Scgd if (q->klings + klump > MAXKLQUAD) 29761f28255Scgd continue; 29861f28255Scgd q->klings += klump; 29961f28255Scgd i -= klump; 30061f28255Scgd break; 30161f28255Scgd } 30261f28255Scgd } 30361f28255Scgd 30461f28255Scgd /* initialize this quadrant */ 30561f28255Scgd printf("%d Klingons\n%d starbase", Param.klings, Param.bases); 30661f28255Scgd if (Param.bases > 1) 30761f28255Scgd printf("s"); 30861f28255Scgd printf(" at %d,%d", Now.base[0].x, Now.base[0].y); 30961f28255Scgd for (i = 1; i < Param.bases; i++) 31061f28255Scgd printf(", %d,%d", Now.base[i].x, Now.base[i].y); 31161f28255Scgd printf("\nIt takes %d units to kill a Klingon\n", Param.klingpwr); 31261f28255Scgd Move.free = 0; 31361f28255Scgd initquad(0); 31461f28255Scgd srscan(1); 31561f28255Scgd attack(0); 31661f28255Scgd } 317