games@tekred.TEK.COM (06/01/88)
Submitted by: udenva!koala!dir (Dan Rosenblatt) Comp.sources.games: Volume 4, Issue 21 Archive-name: spacewar/Part01 [I've compiled this, but haven't had a chance to try it out. -br] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 6)." # Contents: README MANIFEST build.c play.c unplay.c # Wrapped by billr@saab on Tue May 31 09:54:48 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"README\" else echo shar: Extracting \"README\" \(1277 characters\) sed "s/^X//" >README <<'END_OF_README' XUnfortunately, I have not gotten around to packaging spacewar Xfor totally automatic installation; so here are some notes: X X spacewar.h contains various pathnames that must be edited X before compilation. There is also a define for X SWMASTER, the player that has special game commands X and ship privileges. The special game commands X can be found in prvcmd.c. X X Makefile must define the right symbols during compilation X for your system type: X VMS for VMS; certain mailbox privileges X are required. X BSD for non System-V. X If neither of these are defined, then a System-V X environment with named pipes is assumed. X VOID either 'int' or 'void' depending on X what your compiler supports. X NEEDFMOD if your system doesn't have an fmod X function in libc.a or libm.a. X X swobj should be created by copying swobj.init into it. X X swerr X swdb.dir X swdb.pag should be created empty. X X psw.sh should be edited for pathnames and installed somewhere X like /usr/games. X X psw X sw should be setuid to the owner of swobj, swdb.dir, swdb.pag, X and swerr. Also, the directory that these files are in X must be mode 'rwx' for the same user-id as the setuid cuz X various other files are created and exist here only while X spacewar is running. END_OF_README if test 1277 -ne `wc -c <README`; then echo shar: \"README\" unpacked with wrong size! fi # end of overwriting check fi if test -f MANIFEST -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"MANIFEST\" else echo shar: Extracting \"MANIFEST\" \(2274 characters\) sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X Makefile 4 X README 1 X aln.h 6 X alninit.c 4 X bfuncs.c 6 X bits.c 5 X build.c 1 X build.h 4 X cmd.c 2 X copyright 6 X crft.h 5 X crftupdate.c 5 X damage.c 4 X dbm.c 5 X dbm.h 6 X dmpdbm.c 5 X doc.ms 2 X fixdir.c 6 X flds.h 5 X globals.c 6 X lckmsg.c 6 X login.h 6 X logoff.c 5 X logon.c 5 X mail.c 2 X mlbx.h 6 X mutils.c 3 X obj.h 6 X objinit.c 5 X objupdate.c 5 X output.c 5 X play.c 1 X plinit.c 3 X plyr.h 6 X proctrap.c 3 X prvcmd.c 3 X psw.c 4 X psw.sh 6 X remove.c 5 X rpt.c 6 X rsw.c 6 X scrn.c 3 X see.c 3 X shutdown.c 5 X spacewar.h 5 X sw.c 4 X swobj.init 5 X sys.h 6 X tget.c 6 X torp.h 6 X tstsz.c 6 X ucmd.h 6 X uio.h 6 X uio2.h 6 X universe.h 6 X unplay.c 1 X updaln.c 3 X update.c 2 X upddbm.c 4 X upddmg.c 4 X upddsh.c 5 X updmov.c 3 X updobjs.c 5 X updsys.c 4 X updtorp.c 5 X usrcmd.c 4 X vdisp.c 5 X vmsdelmbx.c 6 X vmspsw.c 4 X vmsrsw.c 5 X who.c 6 END_OF_MANIFEST if test 2274 -ne `wc -c <MANIFEST`; then echo shar: \"MANIFEST\" unpacked with wrong size! fi # end of overwriting check fi if test -f build.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"build.c\" else echo shar: Extracting \"build.c\" \(14850 characters\) sed "s/^X//" >build.c <<'END_OF_build.c' X/* X * Spacewar - (re)build a ship X * X * Copyright 1984 obo Systems, Inc. X * Copyright 1984 Dan Rosenblatt X */ X X#ifndef VMS X#include <sys/types.h> X#include <dbm.h> X#else /* BSD SYSIII SYSV */ X#include <types.h> X#include "dbm.h" X#endif /* VMS */ X#include "spacewar.h" X#include "universe.h" X#include "obj.h" X#include "login.h" X#include "sys.h" X#include "crft.h" X#define BUILD X#include "build.h" X Xstatic struct crftkey getcrkey; Xstatic struct crft getcrdat; Xstatic struct syskey getskey; Xstatic struct sys getsdat; Xstatic datum dbmkey,dbmdata; Xstatic struct sysc *getsc; Xstatic getsys(),getcrft(); Xstatic VOID fixdmg(),putcrft(),putsys(),delsys(); Xextern long atol(); X XVOID build(plogin) Xstruct login *plogin; X{ X char buf[80+1]; X X#ifdef DEBUG X DBG("build(#%d/%s)\n",plogin-loginlst,plogin->ln_name); X#endif X X /****************/ X /* no craft yet */ X /****************/ X#ifdef DEBUG X VDBG("build: #%d/%s doing %s/%d\n",plogin-loginlst,plogin->ln_name, X plogin->ln_crft,(int)plogin->ln_substat); X#endif X if (!plogin->ln_crft[0]) { X X /* nothing - prompt for craft name */ X if (!plogin->ln_input[0]) { X#ifdef DEBUG X VDBG("build: prompt for craft name\n"); X#endif X output(plogin,'C',0, X "A single dot (.) on a line by itself terminates Build.\n\n"); X output(plogin,'C',0,"What is the name of your ship?"); X output(plogin,0,0,0); X#ifdef DEBUG X VDBG("build return\n"); X#endif X return; X X /* craft name - store and get or create craft */ X } else { X#ifdef DEBUG X VDBG("build: get/create craft '%s'\n",plogin->ln_input); X#endif X plogin->ln_input[sizeof(plogin->ln_crft)-1] = NULL; X strcpy(plogin->ln_crft,plogin->ln_input); X if (!strcmp(plogin->ln_input,".")) { X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X#ifdef DEBUG X VDBG("build return\n"); X#endif X return; X } X X /* exists */ X if (getcrft(plogin)) { X#ifdef DEBUG X VDBG("build: craft exists\n"); X#endif X X /* has a valid hull type */ X if (getcrdat.cr_htyp) { X#ifdef DEBUG X VDBG("build: has valid hull %d\n",getcrdat.cr_htyp); X#endif X X /* must be docked or priviledged */ X if ((!getcrdat.cr_dock.ip_ofst || X getcrdat.cr_dock.ip_ofst >= MAXOBJ) && X !getcrdat.cr_plvl) { X#ifdef DEBUG X VDBG("build: docked=%d plvl=%d\n", X getcrdat.cr_dock.ip_ofst,getcrdat.cr_plvl); X#endif X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,"Must be docked to rebuild."); X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X#ifdef DEBUG X VDBG("build return\n"); X#endif X return; X X /* docked - fix hull damage; set next subsys prompt */ X } else { X#ifdef DEBUG X VDBG("build: docked=%d plvl=%d\n", X getcrdat.cr_dock.ip_ofst,getcrdat.cr_plvl); X#endif X if (!getsys(plogin,HULL)) { X perror("build: docked and can't find HULL"); X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X#ifdef DEBUG X VDBG("build return\n"); X#endif X return; X } X fixdmg(); X putsys(plogin); X plogin->ln_substat = (char *)(HULL+1); X } X X /* invalid hull - set up prompting for hull type */ X } else { X#ifdef DEBUG X VDBG("build: has invalid hull %d\n",getcrdat.cr_htyp); X#endif X plogin->ln_substat = (char *)(HULL); X } X X /* craft doesn't exist - create it, */ X /* set up prompting for hull type */ X } else { X#ifdef DEBUG X VDBG("build: creating craft\n"); X#endif X binit((char *)&getcrdat,sizeof(getcrdat)); X getcrdat.cr_dock.ip_ofst = -1; X dbmdata.dptr = (char *)&getcrdat; X dbmdata.dsize = CRDATSIZ; X if (store(dbmkey,dbmdata)) { X output(plogin,'C',0, X "(sigh) database collision - try another ship name\n\n\ XWhat is the name of your ship?"); X output(plogin,0,0,0); X plogin->ln_crft[0] = NULL; X#ifdef DEBUG X VDBG("build return\n"); X#endif X return; X } X plogin->ln_substat = (char *)(HULL); X } X } X X /******************************/ X /* get craft - error if can't */ X /******************************/ X } else if (!getcrft(plogin)) { X perror("build: can't find craft\n"); X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X#ifdef DEBUG X VDBG("build return\n"); X#endif X return; X X /*************************************/ X /* no hull type - input is hull type */ X /*************************************/ X } else if (!getcrdat.cr_htyp) { X#ifdef DEBUG X VDBG("build: craft given hull '%s'\n",plogin->ln_input); X#endif X X if (!strcmp(plogin->ln_input,".")) { X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X#ifdef DEBUG X VDBG("build return\n"); X#endif X return; X } X X /* must be 1, 2, or 3 */ X if (strcmp("1",plogin->ln_input) && X strcmp("2",plogin->ln_input) && X strcmp("3",plogin->ln_input)) X output(plogin,'C',0,"Bad hull type\n\n"); X X /* update craft */ X /* create hull subsystem */ X /* set next subsys prompt */ X else { X getcrdat.cr_htyp = plogin->ln_input[0] - '0'; X getsc = &config[HULL][getcrdat.cr_htyp]; X getcrdat.cr_flsp = getsc->sc_bsp; X getcrdat.cr_crew = getsc->sc_bcr; X putcrft(plogin); X X getsys(plogin,HULL); /* should fail */ X getsdat.s_pct = getsc->sc_rpct; X getsdat.s_edmg = getsc->sc_edmg; X getsdat.s_dmg = 0; X getsdat.s_lvl = getsc->sc_ilvl; X getsdat.s_cap = getsc->sc_cap; X putsys(plogin); X X plogin->ln_substat = (char *)(HULL+1); X } X X /**********************************************/ X /* null response - fix damage and leave as is */ X /**********************************************/ X } else if (!plogin->ln_input[0]) { X#ifdef DEBUG X VDBG("build: null response for subsys %d\n", X (int)plogin->ln_substat); X#endif X X /* only if system exists */ X if (getsys(plogin,(int)plogin->ln_substat)) { X fixdmg(); X putsys(plogin); X } X X plogin->ln_substat = (char *)((int)plogin->ln_substat + 1); X X /*****************************************************************/ X /* zero - delete subsystem if at starbase, zero it out otherwise */ X /*****************************************************************/ X } else if (!strcmp("0",plogin->ln_input)) { X#ifdef DEBUG X VDBG("build: zero percent for subsys %d\n",(int)plogin->ln_substat); X#endif X X /* only if system exists */ X if (getsys(plogin,(int)plogin->ln_substat)) { X#ifdef DEBUG X VDBG("build: subsys exists\n"); X#endif X fixdmg(); X X /* delete if priviledged or brand new or */ X /* docked at starbase freeing up space and crew */ X getsc = &config[getskey.s_type][getcrdat.cr_htyp]; X if (getcrdat.cr_plvl || getcrdat.cr_dock.ip_ofst < 0 || X (getcrdat.cr_dock.ip_ofst > 0 && X univlst[getcrdat.cr_dock.ip_ofst].uv_pctr == '#')) { X#ifdef DEBUG X VDBG("build: deleting subsys\n"); X#endif X getcrdat.cr_flsp += getsc->sc_bsp + X (getsc->sc_fsp * getsdat.s_pct) / 100L; X getcrdat.cr_crew += getsc->sc_bcr + X (getsc->sc_fcr * getsdat.s_pct) / 100L; X delsys(plogin); X X /* otherwise set to 0 keeping base space and */ X /* crew freeing incremental space and crew */ X } else { X#ifdef DEBUG X VDBG("build: zero out subsys\n"); X#endif X getcrdat.cr_flsp += (getsc->sc_fsp * getsdat.s_pct) / 100L; X getcrdat.cr_crew += (getsc->sc_fcr * getsdat.s_pct) / 100L; X getsdat.s_pct = 0; X putsys(plogin); X } X putcrft(plogin); X } X X plogin->ln_substat = (char *)((int)plogin->ln_substat + 1); X X /************************************************************/ X /* create/update to new percentage if enough space and crew */ X /************************************************************/ X } else { X long pct = atol(plogin->ln_input); X long maxspcpct,maxcrwpct,maxpct; X long fspc = getcrdat.cr_flsp; /* current free space */ X long fcrw = getcrdat.cr_crew; /* current free crew */ X X#ifdef DEBUG X VDBG("build: %s%% for subsys %d\n",plogin->ln_input, X (int)plogin->ln_substat); X#endif X if (!strcmp(plogin->ln_input,".")) { X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X#ifdef DEBUG X VDBG("build return\n"); X#endif X return; X } X X /***************************************/ X /* compute maximum percentage possible */ X /***************************************/ X if (getsys(plogin,(int)plogin->ln_substat)) { X#ifdef DEBUG X VDBG("build: subsys exists with %d%%\n",getsdat.s_pct); X#endif X getsc = &config[getskey.s_type][getcrdat.cr_htyp]; X fspc += getsc->sc_bsp + (getsc->sc_fsp * getsdat.s_pct) / 100L; X fcrw += getsc->sc_bcr + (getsc->sc_fcr * getsdat.s_pct) / 100L; X } else { X#ifdef DEBUG X VDBG("build: subsys doesn't exist\n"); X#endif X binit((char *)&getsdat,sizeof(getsdat)); X } X maxspcpct = ((fspc - getsc->sc_bsp) * 100L) / getsc->sc_fsp; X maxcrwpct = ((fcrw - getsc->sc_bcr) * 100L) / getsc->sc_fcr; X maxpct = (maxspcpct < maxcrwpct) ? maxspcpct : maxcrwpct; X if (maxpct < 0L) X maxpct = 0L; X else if (maxpct > 100L) X maxpct = 100L; X X /* check request against limits */ X if (pct < 0L || pct > maxpct) { X#ifdef DEBUG X VDBG("build: %ld%% not between %ld and %ld\n",pct,0,maxpct); X#endif X sprintf(buf, X "\nPercent of subsystem '%s' must be between 0 and %ld?", X subsysnam[(int)plogin->ln_substat],maxpct); X output(plogin,'C',0,buf); X output(plogin,0,0,0); X#ifdef DEBUG X VDBG("build return\n"); X#endif X return; X X /* create/update subsystem; update craft free space and crew */ X } else { X#ifdef DEBUG X VDBG("build: subsys from %d%% to %ld%%\n",getsdat.s_pct,pct); X#endif X getsdat.s_pct = pct; X fixdmg(); X putsys(plogin); X X getsc = &config[getskey.s_type][getcrdat.cr_htyp]; X getcrdat.cr_flsp = fspc - (getsc->sc_bsp + X (getsc->sc_fsp * pct) / 100L); X getcrdat.cr_crew = fcrw - (getsc->sc_bcr + X (getsc->sc_fcr * pct) / 100L); X putcrft(plogin); X X plogin->ln_substat = (char *)((int)plogin->ln_substat + 1); X } X } X X /*****************************/ X /* prompt for next subsystem */ X /*****************************/ X if ((int)plogin->ln_substat == HULL) { X output(plogin,'C',0, X "Hull type (1-rocket, 2-sphere, 3-Enterprise)>"); X output(plogin,0,0,0); X } else if ((int)plogin->ln_substat < MAXSYS) { X getsc = &config[(int)plogin->ln_substat][getcrdat.cr_htyp]; X sprintf(buf,"\n\nSubsystem '%s'\n",subsysnam[(int)plogin->ln_substat]); X output(plogin,'C',0,buf); X sprintf(buf,"Your ship has free space of %ld and free crew of %ld\n", X getcrdat.cr_flsp,getcrdat.cr_crew); X output(plogin,'C',0,buf); X if (getsys(plogin,(int)plogin->ln_substat)) { X sprintf(buf,"Your ship currently has %d%% of this subsystem\n", X getsdat.s_pct); X output(plogin,'C',0,buf); X } X sprintf(buf, X "For this subsystem, the base space is %ld and the base crew is %ld\n", X getsc->sc_bsp,getsc->sc_bcr); X output(plogin,'C',0,buf); X sprintf(buf, X "100%% installation uses an additional %ld space and %ld crew\n", X getsc->sc_fsp,getsc->sc_fcr); X output(plogin,'C',0,buf); X output(plogin,'C',0,"What percent do you want?"); X output(plogin,0,0,0); X X /* all done */ X } else { X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X } X#ifdef DEBUG X VDBG("build return\n"); X#endif X} X Xstatic getcrft(plogin) Xstruct login *plogin; X{ X binit((char *)&getcrkey,sizeof(getcrkey)); X getcrkey.cr_crftkey = CRAFT; X strcpy(getcrkey.cr_plyr,plogin->ln_name); X strcpy(getcrkey.cr_name,plogin->ln_crft); X dbmkey.dptr = (char *)&getcrkey; X dbmkey.dsize = sizeof(getcrkey); X dbmdata = fetch(dbmkey); X#ifdef DEBUG X VDBG("getcrft - %s %s\n",(dbmdata.dptr) ? "found" : "couldn't find", X getcrkey.cr_name); X#endif X if (!dbmdata.dptr) X return(0); X bcopy((char *)&getcrdat,dbmdata.dptr,CRDATSIZ); X return(1); X} X X/* assumes getcrkey and getcrdat are current */ Xstatic VOID putcrft(plogin) Xstruct login *plogin; X{ X#ifdef DEBUG X VDBG("putcrft - %s\n",getcrkey.cr_name); X#endif X dbmkey.dptr = (char *)&getcrkey; X dbmkey.dsize = sizeof(getcrkey); X dbmdata.dptr = (char *)&getcrdat; X dbmdata.dsize = CRDATSIZ; X if (store(dbmkey,dbmdata)) { X perror("putcrft: can't update craft"); X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X } X} X Xstatic getsys(plogin,styp) Xstruct login *plogin; Xint styp; X{ X binit((char *)&getskey,sizeof(getskey)); X getskey.s_syskey = SUBSYS; X strcpy(getskey.s_plyr,plogin->ln_name); X strcpy(getskey.s_crft,plogin->ln_crft); X getskey.s_type = styp; X dbmkey.dptr = (char *)&getskey; X dbmkey.dsize = sizeof(getskey); X dbmdata = fetch(dbmkey); X#ifdef DEBUG X VDBG("getsys - %s %d\n",(dbmdata.dptr) ? "found" : "couldn't find",styp); X#endif X if (!dbmdata.dptr) X return(0); X bcopy((char *)&getsdat,dbmdata.dptr,sizeof(getsdat)); X return(1); X} X X/* assumes getskey and getsdat are current */ Xstatic VOID putsys(plogin) Xstruct login *plogin; X{ X#ifdef DEBUG X VDBG("putsys - %d\n",getskey.s_type); X#endif X dbmkey.dptr = (char *)&getskey; X dbmkey.dsize = sizeof(getskey); X dbmdata.dptr = (char *)&getsdat; X dbmdata.dsize = sizeof(getsdat); X if (store(dbmkey,dbmdata)) { X perror("putsys: can't update subsystem"); X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X } X} X X/* assumes getskey is current */ Xstatic VOID delsys(plogin) Xstruct login *plogin; X{ X#ifdef DEBUG X VDBG("delsys - %d\n",getskey.s_type); X#endif X dbmkey.dptr = (char *)&getskey; X dbmkey.dsize = sizeof(getskey); X if (delete(dbmkey)) { X perror("delsys: can't delete subsystem"); X plogin->ln_crft[0] = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X } X} X X/* assumes getcrdat, getskey, and getsdat are current */ Xstatic VOID fixdmg() X{ X /* if priviledged or docked at a starbase, fix all damage */ X if (getcrdat.cr_plvl || X (getcrdat.cr_dock.ip_ofst > 0 && X univlst[getcrdat.cr_dock.ip_ofst].uv_pctr == '#')) X getsdat.s_dmg = 0; X X /* fix temporary damage to 0, permanent damage to 45 */ X getsdat.s_dmg = (getsdat.s_dmg > 45) ? 45 : 0; X X /* update passive parameters and level */ X getsc = &config[getskey.s_type][getcrdat.cr_htyp]; X getsdat.s_edmg = getsc->sc_edmg; X getsdat.s_lvl = getsc->sc_ilvl; X getsdat.s_cap = getsc->sc_cap; X if (getskey.s_type == ROCKETS) X getsdat.s_lvl = ((long)getsdat.s_lvl * (long)getsdat.s_pct) / 100L; X else if (getskey.s_type == TORPS) X getsdat.s_lvl = (getsdat.s_cap * getsdat.s_pct) / 100; X} END_OF_build.c if test 14850 -ne `wc -c <build.c`; then echo shar: \"build.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f play.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"play.c\" else echo shar: Extracting \"play.c\" \(31675 characters\) sed "s/^X//" >play.c <<'END_OF_play.c' X/* X * Spacewar - routine to execute user playing commands X * X * Copyright 1985 obo Systems, Inc. X * Copyright 1985 Dan Rosenblatt X */ X X#ifndef VMS X#include <sys/types.h> X#include <dbm.h> X#else /* BSD SYSIII SYSV */ X#include <types.h> X#include "dbm.h" X#endif /* VMS */ X#include "spacewar.h" X#include "universe.h" X#include "login.h" X#include "sys.h" X#include "crft.h" X#include "flds.h" X#include "build.h" X#include "aln.h" X#include "obj.h" X#include "torp.h" X#include "ucmd.h" X Xextern VOID fixdir(); Xextern double vdist(),vlen(); Xstatic int okdir(); Xstatic VOID fixaf(); X Xstatic struct { X char *pc_cmd; X char pc_mincmdl; X} pcmds[] = { X/* 0 */ {"erase",1}, {"angle",2}, {"right",2}, {"left",3}, X/* 4 */ {"up",2}, {"down",3}, {"vdist",1}, {"home",1}, X/* 8 */ {"unhome",2}, {"faceforward",2},{"autopilot",2},{"shields",2}, X/* 12 */{"stopthrust",2},{"thrust",2}, {"warp",2}, {"damage",3}, X/* 16 */{"leave",3}, {"dock",3}, {"radio",2}, {"who",2}, X/* 20 */{"report",3}, {"phasers",1}, {"torpedo",2}, {"fix",2}, X/* 24 */{"-",1}, {"sensors",2}, {"lockon",2}, {"redraw",3} X}; X XVOID play(plogin) Xregister struct login *plogin; X{ X int i,j; X long l,m; X register struct crft *pcrft; X struct torp *ptorp; X register struct universe *puniv; X struct login *plgn; X char buf[128]; X double ftmp,tmpvec[3],tmpvec2[3]; X struct ucmdkey getuckey; X datum dbmkey,dbmdata; X char ucargs[9][20+1],inuc=0; X dsplcmnt tmpdspl; X X#ifdef DEBUG X DBG("play(#%d/%s)\n",plogin-loginlst,plogin->ln_name); X#endif X X /* if not yet placed into the universe, try doing so */ X if (!plogin->ln_play.ip_ptr) { X if (plinit(plogin)) { X pcrft = plogin->ln_play.ip_ptr->uv_ptr.uv_crft; X sprintf(plogin->ln_input,"Wlcm abrd the %s captain %s", X plogin->ln_crft,plogin->ln_name); X i = 0; /* force erase, not redraw */ X goto erase; X } X#ifdef DEBUG X VDBG("play return\n"); X#endif X return; X } X pcrft = plogin->ln_play.ip_ptr->uv_ptr.uv_crft; X X /* move last command indicator */ Xdouc: output(plogin,'H',(pcrft->cr_lcmd<<8)|FLD_LSTCMD," "); X if (++pcrft->cr_lcmd >= flds[FLD_LSTCMD].f_maxg) X pcrft->cr_lcmd = 0; X output(plogin,'H',(pcrft->cr_lcmd<<8)|FLD_LSTCMD,"#"); X X /* find command */ X for (i=sizeof(pcmds)/sizeof(pcmds[0]);i-- > 0;) X if (!strncmp(plogin->ln_input,pcmds[i].pc_cmd,pcmds[i].pc_mincmdl)) X break; X if (i < 0) { Xbadinp: sprintf(buf,"??? %s",plogin->ln_input); Xbadinp2: output(plogin,'H',(pcrft->cr_lcmd<<8)|FLD_COMMAND,buf); X inuc = 0; X goto done; X } X X X switch(i) { X X /*********/ X /* erase */ X /*********/ X case 0: Xerase: /* erase screen, redraw background */ X output(plogin,'E',0,0); Xredraw: background(pcrft); X X /* indicate all fields changed so they get re-displayed */ X for (j=0;j < sizeof(pcrft->cr_chng);++j) X pcrft->cr_chng[j] = ~0; X pcrft->cr_scrn[0][0] = NULL; X X if (i == 0) { /* redraw instead of erase */ X X /* reset last report and command markers */ X pcrft->cr_lrpt = 0; X pcrft->cr_lcmd = 0; X X /* restore last command marker */ X output(plogin,'H',(pcrft->cr_lcmd<<8)|FLD_LSTCMD,"#"); X } X X break; X X /*********/ X /* angle */ X /*********/ X case 1: X if (sscanf(plogin->ln_input,"%*s %lf",&ftmp) != 1) X goto badinp; X X /* must be 0<ang<=180 (or 360 if privileged) */ X if (ftmp <= 0. || SUB(ftmp,360.) > 0. || X (SUB(ftmp,180.) > 0 && !pcrft->cr_plvl)) X goto badinp; X X pcrft->cr_vang = MUL(ftmp,DEGTORAD); X biton(pcrft->cr_chng,BIT_VANGL); X X /* recompute viewing distance if not privileged */ X if (!pcrft->cr_plvl) { X pcrft->cr_vdst = X INT(DIV(VANGVDST,SQUARE(pcrft->cr_vang))); X biton(pcrft->cr_chng,BIT_VDIST); X } X break; X X /*********/ X /* right */ X /*********/ X case 2: X if (!okdir(plogin,pcrft,&ftmp)) goto badinp; X pcrft->cr_dir[1] = SUB(pcrft->cr_dir[1],ftmp); X biton(pcrft->cr_chng,BIT_DIR1); X fixdir(pcrft); X fixaf(pcrft); X break; X X /********/ X /* left */ X /********/ X case 3: X if (!okdir(plogin,pcrft,&ftmp)) goto badinp; X pcrft->cr_dir[1] = ADD(pcrft->cr_dir[1],ftmp); X biton(pcrft->cr_chng,BIT_DIR1); X fixdir(pcrft); X fixaf(pcrft); X break; X X /******/ X /* up */ X /******/ X case 4: X if (!okdir(plogin,pcrft,&ftmp)) goto badinp; X pcrft->cr_dir[2] = SUB(pcrft->cr_dir[2],ftmp); X biton(pcrft->cr_chng,BIT_DIR2); X fixdir(pcrft); X fixaf(pcrft); X break; X X /********/ X /* down */ X /********/ X case 5: X if (!okdir(plogin,pcrft,&ftmp)) goto badinp; X pcrft->cr_dir[2] = ADD(pcrft->cr_dir[2],ftmp); X biton(pcrft->cr_chng,BIT_DIR2); X fixdir(pcrft); X fixaf(pcrft); X break; X X /**********************/ X /* vdist (privileged) */ X /**********************/ X case 6: X if (!pcrft->cr_plvl) X goto badinp; X if (sscanf(plogin->ln_input,"%*s %ld",&pcrft->cr_vdst) != 1) X goto badinp; X biton(pcrft->cr_chng,BIT_VDIST); X break; X X /********/ X /* home */ X /********/ X case 7: X if (sscanf(plogin->ln_input,"%*s %d",&i) != 1) X goto badinp; X if (i < 1 || i > MHOM) X goto badinp; X i -= 1; X X /* must be autopiloted on something */ X if (!pcrft->cr_auto.ip_ptr) { X sprintf(buf,"%.22s - not autopiloted",plogin->ln_input); X goto badinp2; X } X X pcrft->cr_hom[i].ip_ptr = pcrft->cr_auto.ip_ptr; X /*pcrft->cr_hdst[i] = INT(vdist(pcrft->cr_pstn, X pcrft->cr_auto.ip_ptr->uv_pstn));*/ X tmpdspl = vdisp(pcrft->cr_univ.ip_ptr,pcrft->cr_auto.ip_ptr,'d'); X pcrft->cr_hdst[i] = INT(tmpdspl.dst); X biton(pcrft->cr_chng,BIT_HOMCHAN+i); X break; X X /**********/ X /* unhome */ X /**********/ X case 8: X if (sscanf(plogin->ln_input,"%*s %d",&i) != 1) X goto badinp; X if (i < 1 || i > MHOM) X goto badinp; X i -= 1; X X /* must be homed in */ X if (!pcrft->cr_hom[i].ip_ptr) { X sprintf(buf,"%.25s - not homed in",plogin->ln_input); X goto badinp2; X } X X pcrft->cr_hom[i].ip_ptr = NULL; X pcrft->cr_hdst[i] = NULL; X biton(pcrft->cr_chng,BIT_HOMCHAN+i); X break; X X /***************/ X /* faceforward */ X /***************/ X case 9: X if (vlen(pcrft->cr_vel) == 0.) { X sprintf(buf,"%.27s - not moving",plogin->ln_input); X goto badinp2; X } X pcrft->cr_ffwd = 1; X pcrft->cr_auto.ip_ptr = NULL; X rttosp(pcrft->cr_vel,pcrft->cr_dir); X biton(pcrft->cr_chng,BIT_AUTOFFWD); X biton(pcrft->cr_chng,BIT_DIR1); X biton(pcrft->cr_chng,BIT_DIR2); X fixdir(pcrft); X break; X X /*************/ X /* autopilot */ X /*************/ X case 10: X if (sscanf(plogin->ln_input,"%*s%c",&i) != 1) /* null */ X i = 0; X else if (sscanf(plogin->ln_input,"%*s %d",&i) != 1) X goto badinp; X X /* to a specific homing channel; privileges allow */ X /* a negative # for absolute universe objects */ X if (i) { X if (i > MHOM || (i < 1 && !pcrft->cr_plvl)) X goto badinp; X if (i < 1) { X if ((i=(-i-1)) >= MAXUNIVERSE || !univlst[i].uv_type) X goto badinp; X else X pcrft->cr_auto.ip_ptr = univlst + i; X } else { X i -= 1; X if (!pcrft->cr_hom[i].ip_ptr) { X sprintf(buf,"%.25s - not homed in",plogin->ln_input); X goto badinp2; X } X pcrft->cr_auto.ip_ptr = pcrft->cr_hom[i].ip_ptr; X } X X /* if docked, shift to docked object (because docking */ X /* loses autos, docks, and torps but not homing) */ X puniv = pcrft->cr_auto.ip_ptr; X if (puniv->uv_type == 'P' && X puniv->uv_ptr.uv_crft->cr_dock.ip_ptr) X pcrft->cr_auto.ip_ptr = X puniv->uv_ptr.uv_crft->cr_dock.ip_ptr; X /* but not to player's own craft */ X if (pcrft->cr_auto.ip_ptr == plogin->ln_play.ip_ptr) X pcrft->cr_auto.ip_ptr = NULL; X X /* to closest to center/closest object */ X } else { X Xdoauto: /* use viewing distance and smaller of */ X /* 5 degrees, half of viewing angle */ X ftmp = MUL(10.,DEGTORAD); X if (SUB(pcrft->cr_vang,ftmp) < 0.) X ftmp = pcrft->cr_vang; X ftmp = DIV(ftmp,2.); X l = pcrft->cr_vdst; X pcrft->cr_auto.ip_ptr = NULL; X X /* select based on closest to center/closest */ X for (puniv = univlst+MAXUNIVERSE;puniv-- > univlst;) { X if (!puniv->uv_type) continue; X if (puniv == plogin->ln_play.ip_ptr) continue; X /*vdiff(puniv->uv_pstn,pcrft->cr_pstn,tmpvec);*/ X tmpdspl = vdisp(puniv,pcrft->cr_univ.ip_ptr,'v'); X vecmul(/*tmpvec*/tmpdspl.vec,pcrft->cr_rmat,tmpvec); X rttosp(tmpvec,tmpvec); X m = INT(tmpvec[0]); X if ((tmpvec[2] == ftmp && m <= l) || X (SUB(tmpvec[2],ftmp) <= 0. && m <= pcrft->cr_vdst)) { X pcrft->cr_auto.ip_ptr = puniv; X ftmp = tmpvec[2]; X l = m; X } X } X } X X biton(pcrft->cr_chng,BIT_AUTOFFWD); X if (!pcrft->cr_auto.ip_ptr) { X sprintf(buf,"%.24s - nothing there",plogin->ln_input); X goto badinp2; X } else { X pcrft->cr_ffwd = NULL; X /*vdiff(pcrft->cr_auto.ip_ptr->uv_pstn,pcrft->cr_pstn, X pcrft->cr_dir);*/ X tmpdspl = vdisp(pcrft->cr_auto.ip_ptr,pcrft->cr_univ.ip_ptr,'v'); X rttosp(/*pcrft->cr_dir*/tmpdspl.vec,pcrft->cr_dir); X biton(pcrft->cr_chng,BIT_DIR1); X biton(pcrft->cr_chng,BIT_DIR2); X fixdir(pcrft); X } X break; X X /***********/ X /* shields */ X /***********/ X case 11: X if (!pcrft->cr_sys[SHIELDS].s_cap) { X sprintf(buf,"%.27s - no shields",plogin->ln_input); X goto badinp2; X } X if (sscanf(plogin->ln_input,"%*s %d",&i) != 1) X goto badinp; X X /* 0<=arg<=100 */ X if (i < 0 || i > 100) X goto badinp; X X pcrft->cr_sys[SHIELDS].s_lvl = i; X biton(pcrft->cr_chng,BIT_SLEVEL+SHIELDS*flds[FLD_SLEVEL].f_grpw); X break; X X /**************/ X /* stopthrust */ X /**************/ X case 12: X if (!pcrft->cr_sys[ROCKETS].s_cap) { X sprintf(buf,"%.27s - no rockets",plogin->ln_input); X goto badinp2; X } X if (vlen(pcrft->cr_thr) == 0.) { X sprintf(buf,"%.20s - no pending thrust",plogin->ln_input); X goto badinp2; X } X vinit(pcrft->cr_thr); X break; X X /**********/ X /* thrust */ X /**********/ X case 13: X if (!pcrft->cr_sys[ROCKETS].s_cap) { X sprintf(buf,"%.27s - no rockets",plogin->ln_input); X goto badinp2; X } X if (!pcrft->cr_sys[ROCKETS].s_lvl) { X sprintf(buf,"%.30s - no fuel",plogin->ln_input); X goto badinp2; X } X vinit(tmpvec); X if ((i=sscanf(plogin->ln_input,"%*s %lf %lf %lf %lf%c",&ftmp, X tmpvec+0,tmpvec+1,tmpvec+2,&j)) < 1 || i > 4) X goto badinp; X X /* first number is thrust in direction pointed */ X /* others are cartesian components */ X pcrft->cr_dir[0] = ftmp; X sptort(pcrft->cr_dir,tmpvec2); X for (i=0;i<3;++i) X pcrft->cr_thr[i] = X ADD(pcrft->cr_thr[i],ADD(tmpvec[i],tmpvec2[i])); X X /* turn off docking */ X if (puniv=pcrft->cr_dock.ip_ptr) { X X /* fix other player's screen if docked with another craft */ X if (puniv->uv_type == 'P') X puniv->uv_ptr.uv_crft->cr_scrn[7][15] = '?'; X X /* place craft away from docked object */ X /* according to direction of thrust */ X rttosp(pcrft->cr_thr,tmpvec); X tmpvec[0] = ADD(MUL(FLOAT(puniv->uv_rad+1),2.),1.); X sptort(tmpvec,tmpvec); X for (i=0;i<3;++i) X pcrft->cr_pstn[i] = ADD(pcrft->cr_pstn[i],tmpvec[i]); X vchngd(pcrft->cr_univ.ip_ptr); X pcrft->cr_dock.ip_ptr = NULL; X pcrft->cr_scrn[7][15] = '?'; X } X X break; X X /********/ X /* warp */ X /********/ X case 14: X if (!pcrft->cr_sys[WARP].s_cap) { X sprintf(buf,"%.30s - no warp",plogin->ln_input); X goto badinp2; X } X if (sscanf(plogin->ln_input,"%*s %lf",&ftmp) != 1 || ftmp == 0.) X goto badinp; X ftmp = MUL(ftmp,1000.); X X /* check energy required */ X l = 500L + 15L * INT(SQRT((ftmp < 0.) ? NEG(ftmp) : ftmp)); X if (l > pcrft->cr_sys[WARP].s_lvl) { X sprintf(buf,"%.18s - need at least %ld",plogin->ln_input,l); X goto badinp2; X } X X /* reduce warp energy level */ X pcrft->cr_sys[WARP].s_lvl -= l; X biton(pcrft->cr_chng,BIT_SLEVEL+WARP*flds[FLD_SLEVEL].f_grpw); X X /* new position; % and %dmg affect accuracy */ X pcrft->cr_dir[0] = ftmp; X sptort(pcrft->cr_dir,tmpvec); X ftmp = DIV(MUL(ftmp,FLOAT(100-pcrft->cr_sys[WARP].s_pct+ X pcrft->cr_sys[WARP].s_dmg)),100.); X for (i=0;i<3;++i) X pcrft->cr_pstn[i] = ADD(pcrft->cr_pstn[i], X ADD(tmpvec[i],MUL(ftmp,DIV(FLOAT(RANDOM(200)-100),100.)))); X vchngd(pcrft->cr_univ.ip_ptr); X biton(pcrft->cr_chng,BIT_PN1); X biton(pcrft->cr_chng,BIT_PN2); X biton(pcrft->cr_chng,BIT_PN3); X X /* turn off auto/dock for this and other crafts on this craft */ X if (pcrft->cr_dock.ip_ptr) { X pcrft->cr_dock.ip_ptr = NULL; X pcrft->cr_scrn[7][15] = '?'; X } X if (pcrft->cr_auto.ip_ptr) { X pcrft->cr_auto.ip_ptr = NULL; X biton(pcrft->cr_chng,BIT_AUTOFFWD); X } X for (puniv=univlst+MAXUNIVERSE;puniv-- > univlst;) { X register struct crft *pcrft2; X if (puniv->uv_type != 'P') continue; X pcrft2 = puniv->uv_ptr.uv_crft; X if (pcrft2->cr_dock.ip_ptr == plogin->ln_play.ip_ptr) { X pcrft2->cr_dock.ip_ptr = NULL; X pcrft2->cr_scrn[7][15] = '?'; X pcrft->cr_scrn[7][15] = '?'; X } X if (pcrft2->cr_auto.ip_ptr == plogin->ln_play.ip_ptr) { X pcrft2->cr_auto.ip_ptr = NULL; X biton(pcrft2->cr_chng,BIT_AUTOFFWD); X } X } X X break; X X /***********************/ X /* damage (privileged) */ X /***********************/ X case 15: X if (!pcrft->cr_plvl) X goto badinp; X if (sscanf(plogin->ln_input,"%*s %d %d",&i,&j) != 2) X goto badinp; X X /* must be a valid, existing system */ X if (i < 0 || i >= MSYS || !pcrft->cr_sys[i].s_cap) X goto badinp; X X /* 0<=%dmg<=100 */ X if (j < 0 || j > 100) X goto badinp; X X pcrft->cr_sys[i].s_dmg = j; X if (i == HULL) X plogin->ln_play.ip_ptr->uv_mass = j; X biton(pcrft->cr_chng,BIT_SDMG+i*flds[FLD_SDMG].f_grpw); X break; X X /*********/ X /* leave */ X /*********/ X case 16: X /* only if privileged or nothing bad */ X /* nearby or docked with an object */ X if (pcrft->cr_plvl || pcrft->cr_sens[1] == 0 || X ((puniv=pcrft->cr_dock.ip_ptr) && puniv->uv_type == 'O')) { X output(plogin,'H',(pcrft->cr_lcmd<<8)|FLD_COMMAND, X plogin->ln_input); X unplay(plogin); X output(plogin,'E',0,0); X output(plogin,'C',0,PROMPT); X output(plogin,0,0,0); X return; X } X sprintf(buf,"%.14s - not docked and BAD != 0",plogin->ln_input); X goto badinp2; X X /********/ X /* dock */ X /********/ X case 17: X /* find the closest, dock'able object */ X l = 10000L; X pcrft->cr_dock.ip_ptr = NULL; X for (puniv=univlst+MAXUNIVERSE;puniv-- > univlst;) { X double *pvel; X switch(puniv->uv_type) { X case 0: continue; X case 'P': X if (puniv == plogin->ln_play.ip_ptr) X continue; X if (puniv->uv_ptr.uv_crft->cr_dock.ip_ptr) X continue; X pvel = puniv->uv_ptr.uv_crft->cr_vel; X break; X case 'T': X pvel = puniv->uv_ptr.uv_torp->tp_vel; X break; X case 'A': X pvel = puniv->uv_ptr.uv_aln->al_vel; X break; X case 'O': X if (puniv->uv_pctr == ' ' || puniv->uv_pctr == '*') X continue; X pvel = puniv->uv_ptr.uv_obj->oj_vel; X break; X } X /*m = INT(vdist(pcrft->cr_pstn,puniv->uv_pstn));*/ X tmpdspl = vdisp(pcrft->cr_univ.ip_ptr,puniv,'d'); X m = INT(tmpdspl.dst); X if (m < l && m <= 5*(puniv->uv_rad+1)) { X pcrft->cr_dock.ip_ptr = puniv; X l = m; X vcopy(tmpvec,pvel); X } X } X if (!pcrft->cr_dock.ip_ptr) { X sprintf(buf,"%.25s - too far away",plogin->ln_input); X goto badinp2; X } X puniv = pcrft->cr_dock.ip_ptr; X X /* must also be within range next movement iteration */ X for (i=0;i<3;++i) X tmpvec[i] = SUB(ADD(puniv->uv_pstn[i],tmpvec[i]), X ADD(pcrft->cr_pstn[i],pcrft->cr_vel[i])); X if (INT(vlen(tmpvec)) > 5*(puniv->uv_rad+1)) { X sprintf(buf,"%.22s - moving too fast",plogin->ln_input); X pcrft->cr_dock.ip_ptr = NULL; X goto badinp2; X } X X /* dock */ X pcrft->cr_scrn[7][15] = '?'; X vinit(pcrft->cr_thr); X vcopy(pcrft->cr_pstn,puniv->uv_pstn); X vchngd(pcrft->cr_univ.ip_ptr); X biton(pcrft->cr_chng,BIT_PN1); X biton(pcrft->cr_chng,BIT_PN2); X biton(pcrft->cr_chng,BIT_PN3); X output(plogin,0,0,0); X X /* fix autopilots, docks, torp aim, alien attack */ X for (puniv=univlst+MAXUNIVERSE;puniv-- > univlst;) { X register struct crft *pcrft2; X struct aln *paln; X switch(puniv->uv_type) { X case 0: continue; X case 'P': X pcrft2 = puniv->uv_ptr.uv_crft; X if (pcrft2->cr_auto.ip_ptr == X plogin->ln_play.ip_ptr) { X X /* shift autopilot to item docked with */ X /* if its not an object and not itself */ X if (pcrft->cr_dock.ip_ptr->uv_type != 'O' && X pcrft->cr_dock.ip_ptr != puniv) X pcrft2->cr_auto.ip_ptr = X pcrft->cr_dock.ip_ptr; X X /* its an object or itself - lose autopilot */ X else X pcrft2->cr_auto.ip_ptr = NULL; X biton(pcrft2->cr_chng,BIT_AUTOFFWD); X pcrft2->cr_scrn[7][15] = '?'; X } X X if (pcrft2->cr_dock.ip_ptr == X plogin->ln_play.ip_ptr) { X X /* shift dock to item docked */ X /* with if its an object */ X if (pcrft->cr_dock.ip_ptr->uv_type == 'O') X pcrft2->cr_dock.ip_ptr = X pcrft->cr_dock.ip_ptr; X else X pcrft2->cr_dock.ip_ptr = NULL; X pcrft2->cr_scrn[7][15] = '?'; X } X X break; X case 'T': X ptorp = puniv->uv_ptr.uv_torp; X if (ptorp->tp_aim.ip_ptr == X plogin->ln_play.ip_ptr && X pcrft->cr_dock.ip_ptr->uv_type == 'O' && X ptorp->tp_fby.ip_ptr && X ptorp->tp_fby.ip_ptr->uv_type == 'P') { X pcrft2 = ptorp->tp_fby.ip_ptr->uv_ptr.uv_crft; X output(pcrft2->cr_lgn,'B',0,0); X setrpt(pcrft2); X rpt(pcrft2,"Torpedo missed - target docked"); X fnshrpt(pcrft2,1); X remove(ptorp->tp_univ); X } X break; X case 'A': X paln = puniv->uv_ptr.uv_aln; X if (paln->al_atck.ip_ptr == plogin->ln_play.ip_ptr X && (pcrft->cr_dock.ip_ptr->uv_type == 'O' || X pcrft->cr_dock.ip_ptr == puniv)) { X paln->al_atck.ip_ptr = NULL; X } X break; X } X } X break; X X /*********/ X /* radio */ X /*********/ X case 18: X if (sscanf(plogin->ln_input,"%*s %[^\n]",buf) != 1) X goto badinp; X X output(pcrft->cr_lgn,0,0,0); X X /* similar to autopilot */ X ftmp = MUL(10.,DEGTORAD); X if (SUB(pcrft->cr_vang,ftmp) < 0.) X ftmp = pcrft->cr_vang; X ftmp = DIV(ftmp,2.); X for (puniv=univlst+MAXUNIVERSE;puniv-- > univlst;) { X if (puniv->uv_type != 'P') continue; X if (puniv->uv_ptr.uv_crft == pcrft) continue; X /*vdiff(puniv->uv_pstn,pcrft->cr_pstn,tmpvec);*/ X tmpdspl = vdisp(puniv,pcrft->cr_univ.ip_ptr,'v'); X vecmul(/*tmpvec*/tmpdspl.vec,pcrft->cr_rmat,tmpvec); X rttosp(tmpvec,tmpvec); X if (SUB(tmpvec[2],ftmp) <= 0.) { X char buf2[40+1]; X plgn = puniv->uv_ptr.uv_crft->cr_lgn; X output(plgn,'B',0,0); X output(plgn,'H',FLD_RADIO,buf); X /*vdiff(pcrft->cr_pstn,puniv->uv_pstn,tmpvec);*/ X tmpdspl = vdisp(pcrft->cr_univ.ip_ptr,puniv,'v'); X rttosp(/*tmpvec*/tmpdspl.vec,tmpvec); X setrpt(puniv->uv_ptr.uv_crft); X sprintf(buf2,"Radio @%ld %.1f %.1f",INT(tmpvec[0]), X DIV(tmpvec[1],DEGTORAD),DIV(tmpvec[2],DEGTORAD)); X rpt(puniv->uv_ptr.uv_crft,buf2); X fnshrpt(puniv->uv_ptr.uv_crft,1); X } X } X break; X X /*******/ X /* who */ X /*******/ X case 19: X if (sscanf(plogin->ln_input,"%*s%c",&i) != 1) /* null */ X i = 0; X else if (sscanf(plogin->ln_input,"%*s %d",&i) != 1 || i < 0) X goto badinp; X i *= flds[FLD_REPORT].f_maxg; /* skip display group count */ X X setrpt(pcrft); X *buf = NULL; X for (plgn=loginlst+MAXLOGIN;plgn-- > loginlst;) { X if (!plgn->ln_play.ip_ptr) continue; X if (i-- > 0) continue; X if (strlen(buf) + strlen(plgn->ln_name) + X strlen(plgn->ln_crft) + 5 > flds[FLD_REPORT].f_len) { X rpt(pcrft,buf); X *buf = NULL; X } X sprintf(buf+strlen(buf),"%s/%s(%c) ",plgn->ln_name, X plgn->ln_crft,plgn->ln_play.ip_ptr->uv_pctr); X } X rpt(pcrft,buf); X fnshrpt(pcrft,0); X break; X X /**********/ X /* report */ X /**********/ X case 20: X if (sscanf(plogin->ln_input,"%*s%c",&i) != 1) /* null */ X i = 0; X else if (sscanf(plogin->ln_input,"%*s %d",&i) != 1 || i < 0) X goto badinp; X i *= flds[FLD_REPORT].f_maxg; /* skip display group count */ X X setrpt(pcrft); X X /* almost identical to view() */ X for (puniv=univlst+MAXUNIVERSE;puniv-- > univlst;) { X if (!puniv->uv_type) continue; X if (puniv->uv_ptr.uv_crft == pcrft) continue; X /*vdiff(puniv->uv_pstn,pcrft->cr_pstn,tmpvec);*/ X tmpdspl = vdisp(puniv,pcrft->cr_univ.ip_ptr,'v'); X vecmul(/*tmpvec*/tmpdspl.vec,pcrft->cr_rmat,tmpvec); X rttosp(tmpvec,tmpvec); X ftmp = DIV(pcrft->cr_vang,2.); X if (SUB(ftmp,tmpvec[2]) >= 0. && X (l=INT(tmpvec[0])) <= pcrft->cr_vdst) { X if (i-- > 0) continue; X tmpvec[0] = DIV(tmpvec[2],ftmp); X tmpvec[2] = DIV(PI,2.); X sptort(tmpvec,tmpvec); X X /* common characteristics */ X sprintf(buf,"%ld,%ld(%c)@%ld",-INT(MUL(tmpvec[1],7.)), X INT(MUL(tmpvec[0],15.)),puniv->uv_pctr,l); X X /* individual characteristics */ X switch(puniv->uv_type) { X case 'O': X sprintf(buf+strlen(buf)," r=%d m=%ld", X puniv->uv_rad,puniv->uv_mass); X break; X case 'P': X plgn = puniv->uv_ptr.uv_crft->cr_lgn; X sprintf(buf+strlen(buf)," %s/%s h%ld s%d", X plgn->ln_name,plgn->ln_crft,puniv->uv_mass, X puniv->uv_ptr.uv_crft->cr_sys[SHIELDS].s_lvl); X break; X case 'T': X sprintf(buf+strlen(buf)," h%ld",puniv->uv_mass); X break; X case 'A': X sprintf(buf+strlen(buf)," h%ld s%d", X puniv->uv_mass, X puniv->uv_ptr.uv_aln->al_sys[SHIELDS].s_lvl); X break; X } X X /* indicate auto'd, dock'd, or home'd */ X l = 0; X if (pcrft->cr_auto.ip_ptr == puniv) { X if (!l) strcat(buf," ("); X l = 1; X strcat(buf,"A"); X } X if (pcrft->cr_dock.ip_ptr == puniv) { X if (!l) strcat(buf," ("); X l = 1; X strcat(buf,"D"); X } X for (j=0;j<MHOM;++j) X if (pcrft->cr_hom[j].ip_ptr == puniv) { X if (!l) strcat(buf," ("); X l = 1; X sprintf(buf+strlen(buf),"%d",j+1); X } X if (l) strcat(buf,")"); X X rpt(pcrft,buf); X } X } X fnshrpt(pcrft,0); X break; X X /***********/ X /* phasers */ X /***********/ X case 21: X if (!pcrft->cr_sys[PHASERS].s_cap) { X sprintf(buf,"%.27s - no phasers",plogin->ln_input); X goto badinp2; X } X if (sscanf(plogin->ln_input,"%*s %d",&i) != 1) X goto badinp; X X /* 1<=arg<=1000 */ X if (i < 1 || i > 1000) X goto badinp; X X /* check if conditions allow phasers */ X if (pcrft->cr_dock.ip_ptr) { X sprintf(buf,"%.21s - not while docked",plogin->ln_input); X goto badinp2; X } X puniv = pcrft->cr_auto.ip_ptr; X if (!puniv || puniv->uv_type == 'O') { X sprintf(buf,"%.19s - nothing to fire at",plogin->ln_input); X goto badinp2; X } X if (inuc) { X sprintf(buf,"%.24s - not in '-cmd'",plogin->ln_input); X goto badinp2; X } X X /* must have enough energy for phaser blast */ X if (!pcrft->cr_sys[DILITH].s_cap || X pcrft->cr_sys[DILITH].s_lvl < i) { X sprintf(buf,"%.20s - not enough energy",plogin->ln_input); X goto badinp2; X } X X /* phasers must not be damaged too much */ X if (pcrft->cr_sys[PHASERS].s_dmg >= 60) { X sprintf(buf,"%.22s - too much damage",plogin->ln_input); X goto badinp2; X } X X /* use the requested energy */ X pcrft->cr_sys[DILITH].s_lvl -= i; X biton(pcrft->cr_chng,BIT_SLEVEL+DILITH*flds[FLD_SLEVEL].f_grpw); X X /* compute damage */ X l = i; X l *= pcrft->cr_sys[PHASERS].s_pct; X l /= 100; X l *= (100-pcrft->cr_sys[PHASERS].s_dmg); X l /= 100; X l *= pcrft->cr_sys[PHASERS].s_cap; X l /= 100; X X /* finally, do it */ X output(pcrft->cr_lgn,0,0,0); /* flush buffering */ X damage(plogin->ln_play.ip_ptr,puniv,1.,FLOAT(l), X "Phaser attack"); X X break; X X /***********/ X /* torpedo */ X /***********/ X case 22: X if (!pcrft->cr_sys[TORPS].s_cap || X pcrft->cr_sys[TORPS].s_lvl < 1) { X sprintf(buf,"%.25s - no torpedoes",plogin->ln_input); X goto badinp2; X } X X /* check if conditions allow torpedoes */ X if (pcrft->cr_dock.ip_ptr) { X sprintf(buf,"%.21s - not while docked",plogin->ln_input); X goto badinp2; X } X puniv = pcrft->cr_auto.ip_ptr; X if (!puniv || puniv->uv_type == 'O') { X sprintf(buf,"%.19s - nothing to fire at",plogin->ln_input); X goto badinp2; X } X if (inuc) { X sprintf(buf,"%.24s - not in '-cmd'",plogin->ln_input); X goto badinp2; X } X X /* torpedo tubes must not be damaged too much */ X if (pcrft->cr_sys[TORPS].s_dmg >= 60) { X sprintf(buf,"%.22s - too much damage",plogin->ln_input); X goto badinp2; X } X X /* search for an open slot */ X for (ptorp=torplst+MAXTORP;ptorp-- > torplst;) X if (!ptorp->tp_aim.ip_ptr) X break; X if (ptorp < torplst) { X sprintf(buf,"%.17s - sorry, universe full",plogin->ln_input); X goto badinp2; X } X for (puniv=univlst+MAXUNIVERSE;puniv-- > univlst;) X if (!puniv->uv_type) X break; X if (puniv < univlst) { X perror("play: ptorp but no puniv"); X goto badinp; X } X X /* reduce torpedo count */ X pcrft->cr_sys[TORPS].s_lvl -= 1; X biton(pcrft->cr_chng,BIT_SLEVEL+TORPS*flds[FLD_SLEVEL].f_grpw); X X /* put torpedo into the universe */ X pcrft->cr_dir[0] = 1.0; X sptort(pcrft->cr_dir,tmpvec); X for (i=0;i<3;++i) { X ptorp->tp_pstn[i] = ADD(pcrft->cr_pstn[i], X ptorp->tp_thr[i]=MUL(tmpvec[i],50.)); X ptorp->tp_vel[i] = ADD(pcrft->cr_vel[i],MUL(tmpvec[i],10.)); X } X ptorp->tp_aim.ip_ptr = pcrft->cr_auto.ip_ptr; X ptorp->tp_fby.ip_ptr = plogin->ln_play.ip_ptr; X ptorp->tp_dist = INT(vdist(ptorp->tp_pstn, X ptorp->tp_aim.ip_ptr->uv_pstn)); X ptorp->tp_dmg = 0; X ptorp->tp_lhit.ip_ptr = NULL; X puniv->uv_type = 'T'; X puniv->uv_pctr = '+'; X puniv->uv_pstn = ptorp->tp_pstn; X puniv->uv_mass = ptorp->tp_dmg; X puniv->uv_rad = 1; X puniv->uv_ptr.uv_torp = ptorp; X ptorp->tp_univ.ip_ptr = puniv; X X break; X X /*******/ X /* fix */ X /*******/ X case 23: X if (!pcrft->cr_sys[DMGCON].s_cap) { X sprintf(buf,"%.20s - no damage control",plogin->ln_input); X goto badinp2; X } X if (sscanf(plogin->ln_input,"%*s%c",&i) != 1) /* null */ X i = 0; X else if (sscanf(plogin->ln_input,"%*s %d",&i) != 1) X goto badinp; X X /* 0<=arg<=MSYS */ X if (i < 0 || i > MSYS) X goto badinp; X X /* subsystem must be present */ X if (i > 0 && !pcrft->cr_sys[i-1].s_cap) { X sprintf(buf,"%.20s - no such subsystem",plogin->ln_input); X goto badinp2; X } X X pcrft->cr_sys[DMGCON].s_lvl = i; X biton(pcrft->cr_chng,BIT_SLEVEL+DMGCON*flds[FLD_SLEVEL].f_grpw); X break; X X /***************/ X /* - (ucmd) */ X /***************/ X case 24: X if (inuc) { X sprintf(buf,"%.24s - nested '-cmd'",plogin->ln_input); X goto badinp2; X } X for (i=0;i<9;ucargs[i++][0] = NULL) ; X if ((i=sscanf(plogin->ln_input, X "-%s %20s %20s %20s %20s %20s %20s %20s %20s %20s%c", X buf,ucargs[0],ucargs[1],ucargs[2],ucargs[3],ucargs[4], X ucargs[5],ucargs[6],ucargs[7],ucargs[8],&j)) < 1 || i > 10) X goto badinp; X buf[sizeof(getuckey.uc_name)-1] = NULL; X X /* set up data structure to get first line of ucmd */ X binit((char *)&getuckey,sizeof(getuckey)); X getuckey.uc_ucmdkey = UCMD; X strcpy(getuckey.uc_plyr,plogin->ln_name); X strcpy(getuckey.uc_name,buf); X getuckey.uc_ucmd = 1; X X /* verify that ucmd exists */ X dbmkey.dptr = (char *)&getuckey; X dbmkey.dsize = sizeof(getuckey); X dbmdata = fetch(dbmkey); X if (!dbmdata.dptr) { X sprintf(buf,"%.23s - no such '-cmd'",plogin->ln_input); X goto badinp2; X } X inuc = 1; X break; X X /***********/ X /* sensors */ X /***********/ X case 25: X if (sscanf(plogin->ln_input,"%*s%c",&i) != 1) /* null */ X i = 0; X else if (sscanf(plogin->ln_input,"%*s %d",&i) != 1 || i < 0) X goto badinp; X i *= flds[FLD_REPORT].f_maxg; /* skip display group count */ X X setrpt(pcrft); X X /* stolen from report and modified */ X for (puniv=univlst+MAXUNIVERSE;puniv-- > univlst;) { X if (!puniv->uv_type) continue; X if (puniv->uv_ptr.uv_crft == pcrft) continue; X /*vdiff(puniv->uv_pstn,pcrft->cr_pstn,tmpvec);*/ X tmpdspl = vdisp(puniv,pcrft->cr_univ.ip_ptr,'v'); X vcopy(tmpvec,tmpdspl.vec); X vcopy(tmpvec2,tmpvec); X rttosp(tmpvec,tmpvec); X l = INT(tmpvec[0]); X if (l <= 5000L) { X if (i-- > 0) continue; X X /* is it on viewscreen? */ X vecmul(tmpvec2,pcrft->cr_rmat,tmpvec2); X rttosp(tmpvec2,tmpvec2); X ftmp = DIV(pcrft->cr_vang,2.); X *buf = NULL; X if (SUB(ftmp,tmpvec2[2]) >= 0.) { X tmpvec2[0] = DIV(tmpvec2[2],ftmp); X tmpvec2[2] = DIV(PI,2.); X sptort(tmpvec2,tmpvec2); X sprintf(buf,"%ld,%ld",-INT(MUL(tmpvec2[1],7.)), X INT(MUL(tmpvec2[0],15.))); X } X X X /* common characteristics */ X sprintf(buf+strlen(buf),"(%c)@%ld %.1f %.1f", X puniv->uv_pctr,l,DIV(tmpvec[1],DEGTORAD), X DIV(tmpvec[2],DEGTORAD)); X X /* indicate auto'd, dock'd, or home'd */ X l = 0; X if (pcrft->cr_auto.ip_ptr == puniv) { X if (!l) strcat(buf," ("); X l = 1; X strcat(buf,"A"); X } X if (pcrft->cr_dock.ip_ptr == puniv) { X if (!l) strcat(buf," ("); X l = 1; X strcat(buf,"D"); X } X for (j=0;j<MHOM;++j) X if (pcrft->cr_hom[j].ip_ptr == puniv) { X if (!l) strcat(buf," ("); X l = 1; X sprintf(buf+strlen(buf),"%d",j+1); X } X if (l) strcat(buf,")"); X X rpt(pcrft,buf); X } X } X fnshrpt(pcrft,0); X break; X X /**********/ X /* lockon */ X /**********/ X case 26: X if (!pcrft->cr_lhit.ip_ptr) { X sprintf(buf,"%.26s - no attacker",plogin->ln_input); X goto badinp2; X } X X /* undo FFWD/AUTO; point in direction of last hit position */ X fixaf(pcrft); X vdiff(pcrft->cr_lhpstn,pcrft->cr_pstn,pcrft->cr_dir); X rttosp(pcrft->cr_dir,pcrft->cr_dir); X biton(pcrft->cr_chng,BIT_DIR1); X biton(pcrft->cr_chng,BIT_DIR2); X fixdir(pcrft); X X /* try autopiloting (gross!) */ X goto doauto; X X /**********/ X /* redraw */ X /**********/ X case 27: X goto redraw; X X default: X perror("play: impossible cmd"); X goto badinp; X } X X /* display last command */ X output(plogin,'H',(pcrft->cr_lcmd<<8)|FLD_COMMAND,plogin->ln_input); X X /* process ucmd */ Xdone: if (inuc) { X char *ip,*op; X X /* get ucmd text; setup for next one */ X dbmdata = fetch(dbmkey); X if (!dbmdata.dptr) goto done2; X getuckey.uc_ucmd += 1; X X /* substitute arguments */ X for (ip=dbmdata.dptr,op=plogin->ln_input; X *ip && op < plogin->ln_input + sizeof(plogin->ln_input)-1;) { X if (*ip == '$' && ip[1] >= '1' && ip[1] <= '9') { X char *ap=ucargs[ip[1]-'1']; X while (*ap && X op < plogin->ln_input + sizeof(plogin->ln_input)-1) X *op++ = *ap++; X ip += 2; X } else X *op++ = *ip++; X } X *op = NULL; X X goto douc; X } X X /* update screen, reposition cursor, and clear command line if present */ Xdone2: nums(pcrft); X view(pcrft); X if (plogin->ln_input[0]) { X output(plogin,'D',0,0); X plogin->ln_input[0] = NULL; X } X output(plogin,0,0,0); X X#ifdef DEBUG X VDBG("play return\n"); X#endif X return; X} X Xstatic int okdir(plogin,pcrft,pftmp) Xregister struct login *plogin; Xregister struct crft *pcrft; Xdouble *pftmp; X{ X char c; X X /* no argument, use half viewing angle */ X if (sscanf(plogin->ln_input,"%*s%c",&c) != 1) { X *pftmp = DIV(pcrft->cr_vang,2.); X return(1); X } X X /* 0<arg<360 */ X if (sscanf(plogin->ln_input,"%*s %lf",pftmp) != 1) X return(0); X if (SUB(*pftmp,360.) >= 0. || *pftmp <= 0.) X return(0); X *pftmp = MUL(*pftmp,DEGTORAD); X return(1); X} X Xstatic VOID fixaf(pcrft) Xregister struct crft *pcrft; X{ X if (pcrft->cr_ffwd) { X pcrft->cr_ffwd = NULL; X biton(pcrft->cr_chng,BIT_AUTOFFWD); X } else if (pcrft->cr_auto.ip_ptr) { X pcrft->cr_auto.ip_ptr = NULL; X biton(pcrft->cr_chng,BIT_AUTOFFWD); X } X} END_OF_play.c if test 31675 -ne `wc -c <play.c`; then echo shar: \"play.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f unplay.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"unplay.c\" else echo shar: Extracting \"unplay.c\" \(3248 characters\) sed "s/^X//" >unplay.c <<'END_OF_unplay.c' X/* X * Spacewar - remove a player from the universe X * update/destroy the ship X * X * Copyright 1985 obo Systems, Inc. X * Copyright 1985 Dan Rosenblatt X */ X X#ifndef VMS X#include <sys/types.h> X#include <dbm.h> X#else /* BSD SYSIII SYSV */ X#include <types.h> X#include "dbm.h" X#endif /* VMS */ X#include "spacewar.h" X#include "universe.h" X#include "plyr.h" X#include "login.h" X#include "sys.h" X#include "crft.h" X XVOID unplay(plogin) Xregister struct login *plogin; X{ X register struct crft *pcrft; X struct crft *pcrft2; X struct sys *psys; X struct crftkey getcrkey; X struct syskey getskey; X struct plyrkey getplkey; X struct plyr getpldat; X datum dbmkey,dbmdata; X int i; X extern int numpling; X X#ifdef DEBUG X DBG("unplay(#%d/%s)\n",plogin-loginlst,plogin->ln_name); X#endif X X /* privileged or docked with an object or nothing bad nearby */ X pcrft = plogin->ln_play.ip_ptr->uv_ptr.uv_crft; X if (pcrft->cr_plvl || (pcrft->cr_dock.ip_ptr && X pcrft->cr_dock.ip_ptr->uv_type == 'O') || pcrft->cr_sens[1] == 0) X crftupdate(plogin); X X /* destroy; report and give credit if due to another player */ X else { X X /* delete craft and subsystems from database */ X binit((char *)&getcrkey,sizeof(getcrkey)); X getcrkey.cr_crftkey = CRAFT; X strcpy(getcrkey.cr_plyr,plogin->ln_name); X strcpy(getcrkey.cr_name,plogin->ln_crft); X dbmkey.dptr = (char *)&getcrkey; X dbmkey.dsize = sizeof(getcrkey); X if (delete(dbmkey)) X perror("unplay: can't delete crft"); X binit((char *)&getskey,sizeof(getskey)); X getskey.s_syskey = SUBSYS; X strcpy(getskey.s_plyr,plogin->ln_name); X strcpy(getskey.s_crft,plogin->ln_crft); X dbmkey.dptr = (char *)&getskey; X dbmkey.dsize = sizeof(getskey); X for (psys=pcrft->cr_sys,i=0;i < MSYS;++psys,++i) { X if (!psys->s_cap) continue; /* not in this craft */ X getskey.s_type = i; X if (delete(dbmkey)) X perror("unplay: can't delete sys"); X } X X /* update player losing craft */ X binit((char *)&getplkey,sizeof(getplkey)); X getplkey.pl_plyrkey = PLYR; X strcpy(getplkey.pl_name,plogin->ln_name); X dbmkey.dptr = (char *)&getplkey; X dbmkey.dsize = sizeof(getplkey); X dbmdata = fetch(dbmkey); X if (dbmdata.dptr) { X bcopy((char *)&getpldat,dbmdata.dptr,sizeof(getpldat)); X getpldat.pl_slst += 1; X getpldat.pl_klst += pcrft->cr_kill; X getpldat.pl_plst += pcrft->cr_pnts; X getpldat.pl_tlst += pcrft->cr_time; X dbmdata.dptr = (char *)&getpldat; X dbmdata.dsize = sizeof(getpldat); X if (store(dbmkey,dbmdata)) X perror("unplay: can't update plyr"); X } else X perror("unplay: can't fetch plyr"); X X /* report destruction and credit destroyer */ X if (pcrft->cr_lhit.ip_ptr && pcrft->cr_lhit.ip_ptr->uv_type == 'P') { X pcrft2 = pcrft->cr_lhit.ip_ptr->uv_ptr.uv_crft; X pcrft2->cr_kill += 1; X output(pcrft2->cr_lgn,'B',0,0); X setrpt(pcrft2); X rpt(pcrft2,"Ship destroyed by you"); X fnshrpt(pcrft2,1); X } X } X X /* remove craft from universe */ X remove(plogin->ln_play); X if (--numpling < 0) numpling = 0; X X /* put player back to command mode */ X plogin->ln_iomode = NULL; X plogin->ln_crft[0] = NULL; X plogin->ln_play.ip_ptr = NULL; X plogin->ln_stat = NULL; X plogin->ln_substat = NULL; X X#ifdef DEBUG X VDBG("unplay return\n"); X#endif X} END_OF_unplay.c if test 3248 -ne `wc -c <unplay.c`; then echo shar: \"unplay.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 1 \(of 6\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0