1) If you are on a 4.2BSD system, change emp.h to uncomment the
#define BSD. For SysV, nothing has to be changed. Also, for
4.2BSD systems, you might want to use the 4.2mkfile in GENLIB,
TERMLIB, and UPDLIB instead of the Makefiles provided.
2) When any modifications have been made, do:
make clobber
make all
There are five main programs that are made:
ecre - program to create your local sector database (newsect)
also can be used to relocate in case you have to move your
capital.
eupd - program to extract info from Old Empire game output and update
your local sector database (empsect) and ship database (empship).
ehelp - Old Empire "visual empire". Screen oriented display of your
local databases (empsect & empship), and Old Empire command script
generator. Script gets written into file called .yout. I have
no idea why it was named .yout.
pworld - program to print out the world from your empsect file.
rdship - program to list the ships in your empship file.
In addition, there are several shell/awk programs in MISC that I have
found useful. They also demonstrate alternate ways to change or look at
your local database.
3) This version is meant to be played with Version 1.1 and any more recent
versions of Old Empire.
4) The file, Buglist contains all known bugs fixed and remaining in this
version.
5) This package was incrementally thrown together as adversaries
put pressure on the author's country. There are lots of opportunities
for improving the function and human factors of ehelp, and eupd contains
one of the most bizarre uses of lex and yacc I've ever seen - but it
works. The whole idea behind this set of tools was to make the emp'ing
more efficient than using grid paper and colored pencils, and using
up your BTU and time allocation doing census, map, ship, and mov
commands. Generally, only the "unpredictable" commands are executed
without a script (attack, assault, fly, board, spy).
6) Send all bug reports and wish list items to ihnp4!druxn!tsf.
@//E*O*F ./README//
chmod u=rw,g=r,o=r ./README
echo x - ./Buglist
sed 's/^@//' > "./Buglist" <<'@//E*O*F ./Buglist//'
==[ All the bugs that fit, we print ]==
Version 1.0 Visual Empire for Old Empire
December 1985
Things that generate incorrect scripts, core dumps, hung terminals,
cpu loops, inaccurate displays, are bugs. Things that are inconvenient,
un-pretty, incomplete, are items for the wish list. Please send all
bug reports and wish list items to ihnp4!druxn!tsf.
@//E*O*F ./Buglist//
chmod u=rw,g=r,o=r ./Buglist
echo x - ./Makefile
sed 's/^@//' > "./Makefile" <<'@//E*O*F ./Makefile//'
MAKE=make
LIBDIR=./_unix.O
GENLIB=$(LIBDIR)/genlib.a
TERMLIB=$(LIBDIR)/termlib.a
UPDLIB=$(LIBDIR)/updlib.a
all: $(GENLIB) $(TERMLIB) $(UPDLIB) eupd ehelp ecre pworld rdship
@echo All done!
$(GENLIB): FRC
@echo GENLIB:
@cd GENLIB; $(MAKE)
genlib.a: $(GENLIB)
$(TERMLIB): FRC
@echo TERMLIB:
@cd TERMLIB; $(MAKE)
termlib.a: $(TERMLIB)
$(UPDLIB): FRC
@echo UPDLIB:
@cd UPDLIB; $(MAKE)
updlib.a: $(UPDLIB)
eupd: FRC
@echo EUPD:
@cd EUPD; $(MAKE)
ehelp: FRC
@echo EHELP:
@cd EHELP; $(MAKE)
ecre: FRC
@echo ECRE:
@cd ECRE; $(MAKE)
pworld: FRC
@echo "MISC (pworld):"
@cd MISC; $(MAKE) pworld
rdship: FRC
@echo "MISC (rdship):"
@cd MISC; $(MAKE) rdship
clean:
@cd GENLIB; $(MAKE) clean
@cd TERMLIB; $(MAKE) clean
@cd UPDLIB; $(MAKE) clean
@cd EUPD; $(MAKE) clean
@cd EHELP; $(MAKE) clean
@cd ECRE; $(MAKE) clean
@cd MISC; $(MAKE) clean
clobber:
@cd GENLIB; $(MAKE) clobber
@cd TERMLIB; $(MAKE) clobber
@cd UPDLIB; $(MAKE) clobber
@cd EUPD; $(MAKE) clobber
@cd EHELP; $(MAKE) clobber
@cd ECRE; $(MAKE) clobber
@cd MISC; $(MAKE) clobber
@.PRECIOUS: $(GENLIB) $(TERMLIB) $(UPDLIB)
FRC:
@//E*O*F ./Makefile//
chmod u=rw,g=r,o=r ./Makefile
echo mkdir - ./MAN
mkdir ./MAN
chmod u=rwx,g=rx,o=rx ./MAN
echo x - ./MAN/ehelp.1
sed 's/^@//' > "./MAN/ehelp.1" <<'@//E*O*F ./MAN/ehelp.1//'
ehelp - an Old Empire playing aid Version 1.0 12/85
There are three programs designed (hacked together) to reduce the
empire playing time, while maximizing the enjoyment of interacting
with the other players. The program captures data from Old Empire
output (e.g. census, ship, radar, ...), and uses a screen oriented
user interface to display the accumulated knowledge of the world.
The user uses the display to create a empire command script which
can be executed with the "ex" command. In this way, delivery routes
can be established, goods can be moved, ships can be navigated, etc.
The four programs are: ecre, ehelp, and eupd.
They are used in the following sequence:
COMMAND WHAT TO DO WITH IT
1. ecre [-x new_capx] [-y new_capy]
Invoked without arguments, it creates an empty world
in a file called, "newsect".
Create a file "newsect". Rename it "empsect" after
optionally saving the old world. Also create an empty
file called "empship" ( >empship).
Invoked with arguments, this command can be used to change
the location of your capital. In fact, if you don't use
this program to reflect a new capital location, your view
of the world will get all hosed up. If you designate 1,3
as a new capital, use ecre -x 1 -y 3 to create a "newsect"
having the appropriate adjustments.
2. play empire, saving the output in a file
(e.g. empire Cname rep | tee outfile)
Optionally use scripts generated in step 4.
3. eupd < outfile
Update your view of the world. This updates
empsect and empship. I don't think eupd handles
"route" command output very gracefully, so don't use "route".
Use "census" and ehelp instead.
eupd -p
Suppose your neighbor has taken over most of your western
border while you were on a trip to New Jersey. The updater
isn't smart enough to read through the telegrams and find out
what you no longer own. This can be handled by issuing:
eupd -p
This purges the world of all sectors owned by you. To get the
sectors assigned to you again, simply do a cen # (the whole
world) and run the output through the eupd command. The
sectors you no longer own will be missing in the census output,
and therefore they will remain unowned on your map. Of course,
the best strategy of all is never take a trip to New Jersey.
4. ehelp Enter the screen oriented display, and create the
desired command scripts. These scripts are written in a
file called .yout .
Now erase outfile, and go back to step 2.
Use ehelp like this:
While in ehelp, the cursor is either on the map or down in the lower left
corner waiting for command input. Furthermore, ehelp is either set up for
a specified empire command or it's waiting for you to specify a command
(or possibly map coordinates).
When your prompt is ">" in the lower left corner, you haven't specified
a command yet. In this mode, the following is legal:
Enter:
x,y change center coordinates
map display map
cen set up for census commands
mov set up for move commands
del set up for delivery commands
des set up for designate commands
shi set up for ship commands
nav set up for navigate commands
>command append the string following the ">" to .yout
crtl-d exit ehelp
When you set up any of the command modes (cen, des, etc.) your prompt
will change, and the information block in the upper right will change.
For commands like mov, del, des, you change the quantity, designation,
resource, threshold, etc. by entering the number or letter while the
cursor is in the lower left corner, next to the prompt.
For example, after entering des, the cursor will still be in the lower
left corner. Note that the default designation in the information block
in the upper right is 'g'. Type d to change the designation to a defense
plant, for example.
To leave the specified command mode, type '.' or ctrl-d when the cursor
is in the corner.
After entering the number or letter, the cursor will go up to the
map. To bring the cursor back to the corner, hit the return key.
When the cursor is in the corner, put it on the map by hitting the
return key.
Once on the map, move around by using the
w e r k
\ | / |
s - - d or h - - l
/ | \ |
z x c j
keys. When positioned over a sector, hit the tab (ctrl-i) to see
what's in that sector. If you're in ship or nav mode, hit 'I' and
'i' to see other useful info.
Nothing gets written to the script file (.yout) unless you're on the
map and you hit the space bar, or you use the ">command" feature
shown above.
Specific commands:
When the prompt is ">", type "map" to get a map drawn on the screen.
The display is centered around the coordinates chosen (default is 0,0).
It might look like this:
. - . m
f h m ^?
. * f f d ?
m i m u ? ?
Question marks indicate sectors you don't own. Sometimes the designation
is shown just to the left of the '?'. In the display above, the mountain
was detected by a map or spy command, and the fact that it's owned by
someone else was probably obtained from a spy command. The other '?'s
were probably the result of a map command.
To get a census command appended to .yout, enter cen mode and postition
the cursor on the sector you want a census of. Then hit the space bar.
To designate sectors, enter des mode and select a designation.
Position the cursor on the victim sector, and hit the space bar.
A "des" command will be appended to .yout.
To establish a delivery route, enter del mode. Select resource
and threshold. Note that the screen will be redrawn showing the
existing routes for the selected resource.
When in del mode, position the cursor on the supplying
sector, then type a '+'. Next, position the cursor on the adjacent
receiving sector, and hit the space bar. A "del" command will be
appended to .yout, and the receiving sector is automatically marked
as the next supplying sector. Move the cursor to the next receiving
sector, and hit the space bar again. To indicate a new supplying
sector at any time, position the cursor, then type '+'. Your route is
shown as you construct it on the map, but remember that no changes are
made to the empire world until you run the script. In fact, your
local database isn't changed either. It will change when you run the
output of the empire session (with appropriate census output) through eupd.
To move things around, enter mov mode. Select resource and quantity.
Position cursor on the supplying sector, then type a '+'. Move
the cursor to the next sector in the route to the destination and
type another '+'. Continue in this way until the cursor is positioned
on the destination sector. Instead of typing '+', hit the space bar.
A "mov" command will be appended to .yout. The route will be indicated
with '@' characters. To tear down the route completely or partially,
type a '-'.
Ships are navigated the same way, except you enter nav mode, and
select a ship number, group of ships (124/35/245), or all ships
in the starting sector (type a ',' instead of ship number). Hit
the space bar to append a "nav" command to .yout .
To find out where all the ships are, enter ship mode. You can limit
the operation to ships of only certain types by entering a string
next to the prompt. For example, to limit operations to carriers
and battleships, type "cb". To reinstate the full list again, type
"*". To get a display of all the ships known to you, type "?".
Your ships will be to the right of the sector, and other country
ships will be positioned to the left. Ships are shown as capital letters.
For example your harbor with a pt boat in it and someone else's battleship
just to the north would look like this:
. . . .
m B. . f
f hP * m
^ f m u
All the ships in a particular sector "stack" up, and only the ship with the
highest number is shown. If there were 30 ships in your harbor above, and
several other countries had parked ships just to the north, the display
would look the same so long as the battleship and pt boat had the highest
ship number in that sector. Watch out for capital letters to the left
of your harbors...
There is a way to limit the other country display to just a particular
country, perhaps an enemy of particular interest. Before invoking
ehelp, set the shell variable FOES to the country number of interest.
e.g. FOES=4
export FOES
Then invoke ehelp. The numbers next to the sectors are the ones-digits
of the owning country number (11 and 1 will look alike), and ship displays
will be limited to just your ships and ships owned by the country number
FOES was set to.
Note that you can change your database (empsect and empship) just by
faking empire output and running it through eupd. For example, suppose
your ship hits a mine. You could have a shell script named "mine" that
takes the x,y coordinate of the mined sector and produces a fake
census command output having zero values for everything except the shells.
One effect of this is to change the '.' on the map to a ':' when that
sector is displayed. Hopefully you can avoid that sector when doing a "nav".
To get rid of the ':', fake a census command that has shells=0.
Another example is when ships sink (gasp!). You can fake a ship
command output and set the efficiency to zero. This way, the ship won't
be displayed.
You can also hose up your database pretty badly if you don't know what
you're doing with all these fake commands.
One last trick. Suppose you want to set up delivery routes for ore, shells
and guns all in one shot without having to wait for the screen to redraw
at 1200 baud. The trick is to change the resource with the mov command
instead of with the del command. Enter del, and select o as the resource.
The screen redraws showing the ore delivery routes. Get on the map and
set up your new ore routes. Then hit a return. That puts you back at
the prompt. Instead of selecting another resource (which would cause the
map to be redrawn), leave the del mode by entering a '.' or ctrl-d.
Now enter mov mode. Change the resource to s (shells). Leave mov mode,
and re-enter del mode. Without entering a resource, hit the return key
to get on the map. Now set up your shell delivery routes. Go on to do
the gun routes the same way. Not pretty, but it works.
While you're still getting familiar with ehelp, be sure to check your
scripts. Make sure they're what you intended. Otherwise you could end
up doing something you didn't want to do. Also, if you suspect that the
map isn't being drawn in the right place on the screen (bad termcap, flaky
terminal, noisy line, program bugs(gasp!)), redraw the screen before
creating another line of script. Otherwise, the coordinates of the script
commands will be wrong.
@//E*O*F ./MAN/ehelp.1//
chmod u=rw,g=r,o=r ./MAN/ehelp.1
echo x - ./MAN/eupd.1
sed 's/^@//' > "./MAN/eupd.1" <<'@//E*O*F ./MAN/eupd.1//'
eupd - an Old Empire playing aid Version 1.0 12/85
Eupd is used to extract information from Old Empire output and update
your local sector and ship databases (empsect and empship). Version 1.0
eupd extracts information from the following command outputs:
census map ship navigate look
radar deliver spy fly
For the navigate command, only the "ship #nn stopped at x,y" message
is extracted, and the coordinates of your ships is updated. The mobility
is left unchanged.
For the look command, in addition to the land and ship information extracted,
a message is printed when a sub is detected. The sub's presence is not
written into the empship file. It is assumed that you'll want to go take
a closer "look" to get the sub's number and country info.
The output of delivery commands of the following form:
del o #1 -
is parsed for the threshold information. The delivery direction is
gotten from the cesus command.
For the spy command, all the normal info is parsed, but when the spy
is shot, no info is extracted. When the spy is deported, the sector that
deported the spy is checked to see if you own it. That is, your local
database is checked to see if you think you still own that sector. If
your database indicates (falsely) that you still own that sector, the
owner of the sector is changed to 98 (unknown).
There is a way to gather reconnaissance data from planes. Fly over a sector
of unknown designation. Then do a 'v' to view the sector. This has to be
done in a particular manner. For example, suppose you suspect your
neighbor's capital is somewhere around 3 to 4 sectors to the east of
one of your airfields. You could find out like this:
fly 24,-10 1 0
<24.2:1:0:24,-10> rrr
<21.2:1:0:27,-10> v
Now over completely constructed technical center.
<20.2:1:0:27,-10> d
<19.2:1:0:27,-9> v
Now over completely constructed capital.
<18.2:1:0:27,-9> \llle
1 plane landed.
Always put the 'v' on a separate line by itself. Otherwise eupd
will update the wrong sectors.
@//E*O*F ./MAN/eupd.1//
chmod u=rw,g=r,o=r ./MAN/eupd.1
echo mkdir - ./_unix.O
mkdir ./_unix.O
chmod u=rwx,g=rx,o=rx ./_unix.O
echo x - ./_unix.O/genlib.a
sed 's/^@//' > "./_unix.O/genlib.a" <<'@//E*O*F ./_unix.O/genlib.a//'
@//E*O*F ./_unix.O/genlib.a//
chmod u=rw,g=r,o=r ./_unix.O/genlib.a
echo mkdir - ./hdrs
mkdir ./hdrs
chmod u=rwx,g=rx,o=rx ./hdrs
echo x - ./hdrs/emp.h
sed 's/^@//' > "./hdrs/emp.h" <<'@//E*O*F ./hdrs/emp.h//'
/* Copyright (c) 1985 by Thomas S. Fisher - Westminster, CO 80030 */
/* Define BSD if you're building this on a 4.2 BSD system */
/* Otherwise (for SysV), leave it undefined */
/* #define BSD */
#define MAXSCN 20
#define XYMAX 64
#define ERROR -1
#define OK 1
/*
* Sector Record
*/
#define CIV 0
#define MIL 1
#define SHL 2
#define GUN 3
#define PLN 4
#define ORE 5
#define BAR 6
struct sector {
int s_secno;
char s_des;
char s_flag;
int s_coun;
int s_date;
char s_ckpt;
char s_def;
int s_eff;
int s_min;
int s_gold;
int s_mob;
int s_rsrc[7];
int s_prod;
char s_del[7];
char s_rsrvd[9];
} ;
/*
*
*/
@//E*O*F ./hdrs/emp.h//
chmod u=rw,g=r,o=r ./hdrs/emp.h
echo x - ./hdrs/ship.h
sed 's/^@//' > "./hdrs/ship.h" <<'@//E*O*F ./hdrs/ship.h//'
/* ship types */
#define S_PT 0
#define S_MIN 1
#define S_DES 2
#define S_SUB 3
#define S_FRE 4
#define S_TEN 5
#define S_BAT 6
#define S_CAR 7
#define TMAXNO 7
struct shpstr {
char shp_own; /* country # of owner */
char shp_type; /* ship type */
char shp_effc; /* 0 - 100 */
short shp_xp, shp_yp; /* location in abs coords */
char shp_fleet; /* group membership */
char shp_crew; /* military | civvies on board */
char shp_shels; /* shells on board */
char shp_gun; /* etc */
char shp_plns;
char shp_or;
char shp_gld;
char shp_spric; /* ship price, if for sale */
char shp_mbl; /* mobility */
int shp_lstp; /* time of last update */
};
@//E*O*F ./hdrs/ship.h//
chmod u=rw,g=r,o=r ./hdrs/ship.h
echo mkdir - ./EHELP
mkdir ./EHELP
chmod u=rwx,g=rx,o=rx ./EHELP
echo x - ./EHELP/ehelp.c
sed 's/^@//' > "./EHELP/ehelp.c" <<'@//E*O*F ./EHELP/ehelp.c//'
/* Copyright (c) 1985 by Thomas S. Fisher - Westminster, CO 80030 */
/*
There are a variety of fflush and sleep calls in here to fix(?)
some of the problems with terminals running at 9600 baud on an
Amdahl UTS system.
*/
#include <stdio.h>
#include <ctype.h>
#include "emp.h"
#include "ship.h"
/*
There are two ways of handling raw mode in here: one for 4.2 BSD
and one for SysV. The BSD symbol in emp.h must be defined if this
is being built on a 4.2 system.
*/
#ifdef BSD
#include <sgtty.h>
#else
#include <termio.h>
#endif BSD
#define MAXLINE 132 /* Max command line (at bottom of screen) length */
#define MAXPATH 64 /* Max path for nav and mov */
/* Miscellaneous constants */
#define OK 1
#define RESET 0
#define TRUE 1
#define FALSE 0
/* Special characters while cursor is on the map */
#define DELETE 077
#define CR 015
#define LF 012
#define SPACE ' '
#define PLUS '+'
#define MINUS '-'
#define TAB 011
/* Screen motion characters */
#define UP 'e'
#define UPRIGHT 'r'
#define RIGHT 'd'
#define DNRIGHT 'c'
#define DOWN 'x'
#define DNLEFT 'z'
#define LEFT 's'
#define UPLEFT 'w'
#define VILEFT 'h'
#define VIDN 'j'
#define VIUP 'k'
#define VIRIGHT 'l'
#define CENSW 15 /* Width of census display area */
/* Valid command codes */
#define CEN 1
#define DES 2
#define MOV 3
#define DEL 4
#define MAP 5
#define SHP 6
#define NAV 7
#define NCMDS 7
FILE *fopen(), *fdsec, *fdscrpt, *fdship;
struct sector s;
struct shpstr Ship;
int Func = CEN;
char Stype[] = { 'p', 'm', 'd', 's', 'f', 't', 'b', 'c' };
char *Sorder = "cbdtspmf";
char Shiplist[128];
int Shpnum = 0;
char *Fchar[] = { " ", "cen", "des", "mov", "del", "map", "shi", "nav" };
char *Deldir[] = { ".", "$", "", "",
"", "", "", "",
"n", "ne", "e", "se",
"s", "sw", "w", "nw" };
char *Movdir[] = { "\\l", "l", "/l", "u",
"e", "d", "/r", "r", "\\r" };
int Rtxlat[] = { 15, 14, 13, 8, 0, 12, 9, 10, 11 };
char Rtdirl[] = { ' ', '$', ' ', ' ', ' ', ' ', ' ', ' ',
'^', ' ', ' ', ' ', 'v', '/', '<', '\\' };
char Rtdirr[] = { ' ', '$', ' ', ' ', ' ', ' ', ' ', ' ',
'^', '/', '>', '\\', 'v', ' ', ' ', ' ' };
char Desig = 'g';
int Thresh = 0;
int Rsrc = ORE;
int Quant = 0;
char Rchar[] = { 'c', 'm', 's', 'g', 'p', 'o', 'b' };
int Pathl = 0;
int Pathx[MAXPATH], Pathy[MAXPATH];
int Xcen = 0, Ycen = 0;
int Xcur = 0, Ycur = 0;
int Xl, Yl, Xh, Yh, Xlast, Ylast;
char linebuf[MAXLINE];
#ifdef BSD
struct sgttyb tty0, ttyb;
#else
struct termio st, st0;
#endif BSD
char tbuf[BUFSIZ], tcapbuf[50];
char *CL, *CM;
int Termh, Termw, Censtrt;
int Foe;
#undef putchar
int putchar();
main() {
char *prompt();
char funcstr[4], *getenv(), *foestr;
int i;
if( (fdsec = fopen("empsect", "r")) == NULL ) {
fprintf(stderr, "Can't open empsect\n");
exit(1);
}
if( (fdscrpt = fopen(".yout", "a+")) == NULL ) {
fprintf(stderr, "Can't open output file\n");
exit(2);
}
fdship = fopen("empship", "r");
if( (foestr = getenv("FOES")) == NULL ) {
Foe = 0;
} else {
Foe = atoi(foestr);
}
#ifdef BSD
ioctl(0, TIOCGETP, &tty0); /* save terminal state 4.2BSD */
#else
ioctl(0, TCGETA, &st0); /* save terminal state */
#endif BSD
getcap();
clrscrn();
rawmode();
ckdmode();
prfunc();
prcoord();
strcpy(Shiplist,",");
while( prompt(">") != NULL ) {
if( linebuf[0] == '>' ) {
fputs(&linebuf[1], fdscrpt);
continue;
}
if( sscanf(linebuf, "%d,%d%*[^\n]\n", &Xcen, &Ycen) == 2 ) {
prcoord();
Xcur = Xcen;
Ycur = Ycen;
continue;
}
if( sscanf(linebuf, "%3s%*[^\n]\n", funcstr) != 1 ) continue;
for( i = 1; i <= NCMDS; i++ ) {
if( strncmp(funcstr, Fchar[i], 3) != 0 ) continue;
Func = i;
prfunc();
fflush(stdout);
switch( Func ) {
case CEN:
docen();
break;
case DES:
dodes();
break;
case MOV:
domov();
break;
case DEL:
dodel();
break;
case MAP:
prmap();
break;
case SHP:
doship();
break;
case NAV:
donav();
break;
}
break;
}
}
mvcrsr(Termh, 1);
#ifdef BSD
ioctl(0, TIOCSETN, &ttyb); /* restore terminal state and exit 4.2BSD */
#else
ioctl(0, TCSETAF, &st0); /* restore terminal state and exit */
#endif BSD
}
getcap()
{
extern short ospeed;
char *ap;
char *getenv(), *tgetstr();
char *term;
term = getenv("TERM");
if(term == NULL) {
fprintf(stderr, "No TERM in environment\n");
exit(1);
}
switch(tgetent(tbuf, term)) {
case -1:
fprintf(stderr, "Cannot open termcap file\n");
exit(2);
case 0:
fprintf(stderr, "%s: unknown terminal", term);
exit(3);
}
ap = tcapbuf;
Termh = tgetnum("li");
Termw = tgetnum("co");
Censtrt = Termw - CENSW;
CL = tgetstr("cl", &ap);
CM = tgetstr("cm", &ap);
if (Termh <= 0 || Termw <= 0) {
fprintf(stderr, "Must know the screen size\n");
exit(5);
}
#ifdef BSD
ospeed = ttyb.sg_ospeed & 017;
#else
ospeed = st0.c_cflag & CBAUD;
#endif BSD
}
char *
prompt(s)
char *s;
{
static int plength, ilength;
int i, blanks;
char *ret;
blanks = plength + ilength;
for( i = 0; i < blanks; i++ ) {
linebuf[i] = ' ';
}
linebuf[blanks] = '\0';
mvcrsr(Termh-1, 1);
printf("%s", linebuf);
mvcrsr(Termh-1, 1);
printf("%s", s);
plength = strlen(s);
ret = fgets(linebuf, MAXLINE, stdin);
ilength = strlen(linebuf);
return(ret);
}
rawmode()
{
#ifdef BSD
ioctl(0, TIOCGETP, &ttyb);
ttyb.sg_flags &= ~ECHO;
ttyb.sg_flags |= RAW;
ioctl(0, TIOCSETN, &ttyb);
#else
ioctl(0, TCGETA, &st);
st.c_iflag &= ~(INLCR | ICRNL | BRKINT);
st.c_oflag |= OPOST;
st.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);
st.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOK | ECHONL);
st.c_cc[VMIN] = '\01';
st.c_cc[VTIME] = '\00';
ioctl(0, TCSETA, &st);
#endif BSD
/*
Now in raw mode
*/
}
ckdmode()
{
#ifdef BSD
ioctl(0, TIOCGETP, &ttyb);
ttyb.sg_flags |= ECHO;
ttyb.sg_flags &= ~RAW;
ioctl(0, TIOCSETN, &ttyb);
#else
ioctl(0, TCGETA, &st);
st.c_iflag |= ICRNL;
st.c_lflag |= (ICANON | ECHO);
st.c_cc[VMIN] = st0.c_cc[VMIN];
st.c_cc[VTIME] = st0.c_cc[VTIME];
ioctl(0, TCSETA, &st);
#endif BSD
/*
Now in cooked mode
*/
}
mvcrsr(row, col)
short row, col;
{
fflush(stdout);
printf("%s", tgoto(CM, col-1, row-1));
}
clrscrn() {
mvcrsr(1, 1);
tputs(CL, Termh, putchar);
fflush(stdout);
}
docen()
{
char c, onmap();
while( prompt("cen>") != NULL ) {
if( linebuf[0] == '.' ) break;
if( linebuf[0] != '\n' ) continue;
while( (c = onmap()) != '\n' ) {
if( c == SPACE ) {
fprintf(fdscrpt, "cen %d,%d\n", Xcur, Ycur);
}
if( c == TAB ) prfcen();
}
}
}
dodes()
{
char c, desstr[4], onmap();
prdes();
while( prompt("des>") != NULL ) {
if( linebuf[0] == '.' ) break;
if( sscanf(linebuf, "%1[abcdfghimrtuwx#*!)+-]%*[^\n]\n",
desstr) == 1 ) {
if( desstr[0] != '\0' ) {
Desig = desstr[0];
prdes();
linebuf[0] = '\n';
}
}
if( linebuf[0] != '\n' ) continue;
while( (c = onmap()) != '\n' ) {
if( c == SPACE ) {
fprintf(fdscrpt, "des %d,%d %c\n",
Xcur, Ycur, Desig);
putchar( Desig );
}
if( c == TAB ) prfcen();
}
}
}
domov()
{
int ret;
char c, onmap();
Pathl = 0;
prrsrc();
prquant();
while( prompt("mov>") != NULL ) {
if( linebuf[0] == '.' ) break;
if( sscanf(linebuf, "%d%*[^\n]\n", &Quant) == 1 ) {
prquant();
linebuf[0] = '\n';
}
if( (ret = getrsrc()) != ERROR ) {
Rsrc = ret;
prrsrc();
linebuf[0] = '\n';
}
if( linebuf[0] != '\n' ) continue;
while( (c = onmap()) != '\n' ) {
switch( c ) {
case TAB:
prfcen();
break;
case PLUS:
addsec();
break;
case MINUS:
delsec();
getsec(&s, secno(Xcur, Ycur));
break;
case SPACE:
if( Pathl == 0 && Quant > 0 ) break;
if( addsec() != OK ) break;
fprintf(fdscrpt, "mov %c %d,%d %d ",
Rchar[Rsrc], Pathx[0], Pathy[0], Quant);
mvcrsr((Pathy[0]-Yl+1), (Pathx[0]-Xl)*3+2);
if( Quant == 0 ) {
fprintf(fdscrpt, "\n");
delsec();
break;
}
moveit();
fprintf(fdscrpt, "v\ne\n");
break;
}
}
}
}
dodel()
{
int ret, index, ix, iy;
char c, onmap();
prrsrc();
prthresh();
while( prompt("del>") != NULL ) {
if( linebuf[0] == '.' ) break;
if( sscanf(linebuf, "%d%*[^\n]\n", &Thresh) == 1 ) {
prthresh();
linebuf[0] = '\n';
}
if( (ret = getrsrc()) != ERROR ) {
Rsrc = ret;
prmap();
prrsrc();
prthresh();
linebuf[0] = '\n';
}
if( linebuf[0] != '\n' ) continue;
while( (c = onmap()) != '\n' ) {
switch( c ) {
case TAB:
prfcen();
break;
case PLUS:
addsec();
break;
case SPACE:
if( adjacent(Xcur, Ycur, Xlast, Ylast) != OK ) break;
fprintf(fdscrpt, "del %c %d,%d\n%d,%d (%d)\n",
Rchar[Rsrc], Xlast, Ylast, Xcur, Ycur, Thresh);
ix = Xcur - Xlast;
if( ix < -1 ) ix += XYMAX;
if( ix > 1 ) ix -= XYMAX;
iy = Ycur - Ylast;
if( iy < -1 ) iy += XYMAX;
if( iy > 1 ) iy -= XYMAX;
index = (ix + 1)*3 + (iy + 1);
mvcrsr(Ylast - Yl + 1, (Xlast - Xl)*3 + 1);
putchar(Rtdirl[Rtxlat[index]]);
mvcrsr(Ylast - Yl + 1, (Xlast - Xl)*3 + 3);
putchar(Rtdirr[Rtxlat[index]]);
addsec();
break;
}
}
}
}
getrsrc()
{
int i;
char rstr[4];
if( sscanf(linebuf, "%1[cmsgpob]%*[^\n]\n", rstr) != 1 ) {
return(ERROR);
}
if( rstr[0] == '\0' ) return(ERROR);
for( i = 0; i <= BAR; i++ ) {
if( rstr[0] == Rchar[i] ) return(i);
}
return(ERROR);
}
doship()
{
int x, y, row, col, i;
int shipok;
char c, sorder[TMAXNO+1];
if( fdship == NULL ) return;
prorder();
prshpnum();
while( prompt("ship>") != NULL ) {
shipok = ERROR;
for( i = 0; i <= TMAXNO; i++ ) {
sorder[i] = ' ';
}
if( linebuf[0] == '.' ) break;
if( sscanf(linebuf, "%d%*[^\n]\n", &Shpnum) == 1 ) {
prshpnum();
shipok = OK;
}
sscanf(linebuf, "%8[pmdsftbcPMDSFTBC]%*[^\n]\n", sorder);
for( i = 0; i <= TMAXNO; i++ ) {
if( sorder[i] == '\0' || sorder[i] == ' ' ) break;
Sorder[i] = tolower(sorder[i]);
}
if( sorder[0] != '\0' && sorder[0] != ' ' ) {
Sorder[i] = '\0';
prorder();
shipok = OK;
}
if( linebuf[0] == '*' && linebuf[1] == '\n' ) {
strcpy(Sorder, "cbdtspmf");
prorder();
shipok = OK;
}
if( linebuf[0] == '?' && linebuf[1] == '\n' ) {
rewind(fdship);
while( fread(&Ship, sizeof(struct shpstr), 1, fdship) == 1 ) {
if( Ship.shp_effc == 0 ) continue;
if( Foe != 0 && Ship.shp_own != 0 &&
Ship.shp_own != Foe ) continue;
for( i = 0; i <= TMAXNO && Sorder[i]!='\0'; i++ ) {
if( Sorder[i] == Stype[Ship.shp_type]) break;
}
if( Sorder[i] != Stype[Ship.shp_type]) continue;
x = Ship.shp_xp;
if( (Xcen - x) >= XYMAX/2 ) x += XYMAX;
if( (x - Xcen) >= XYMAX/2 ) x -= XYMAX;
if( x < Xl || x > Xh ) continue;
y = Ship.shp_yp;
if( (Ycen - y) >= XYMAX/2 ) y += XYMAX;
if( (y - Ycen) >= XYMAX/2 ) y -= XYMAX;
if( y < Yl || y > Yh ) continue;
row = y - Yl + 1;
col = (x - Xl)*3 + 1;
if( Ship.shp_own == 0 ) col += 2;
mvcrsr(row, col);
putchar(toupper(Stype[Ship.shp_type]));
}
shipok = OK;
}
if( shipok == OK ) linebuf[0] = '\n';
if( linebuf[0] != '\n' ) continue;
while( (c = onmap()) != '\n' ) {
switch( c ) {
case '\t':
prship();
break;
case 'i':
prshplst();
break;
case 'I':
prshpsum();
break;
}
}
}
}
donav()
{
int shipok;
char c, onmap();
Pathl = 0;
prorder();
prshpnum();
while( prompt("nav>") != NULL ) {
shipok = ERROR;
if( linebuf[0] == '.' ) break;
if( linebuf[0] == '\n' ) ;
else if( linebuf[0] == ',' ) {
strcpy(Shiplist,",");
shipok = OK;
}
else if( isalpha(linebuf[0]) ) {
Shiplist[0] = linebuf[0];
Shiplist[1] = '\0';
shipok = OK;
}
else if( sscanf(linebuf,"%120[0123456789/]",Shiplist) == 1 ) {
if( Shiplist[0] != '\0' &&
sscanf(Shiplist,"%d",&Shpnum) == 1 ) shipok=OK;
}
if( shipok == OK ) {
linebuf[0] = '\n';
prnav();
}
if( linebuf[0] != '\n' ) continue;
while( (c = onmap()) != '\n' ) {
switch(c) {
case TAB:
prship();
break;
case 'i':
prshplst();
break;
case 'I':
prshpsum();
break;
case PLUS:
addsec();
break;
case MINUS:
delsec();
break;
case SPACE:
if( Pathl == 0 ) break;
if( addsec() != OK ) break;
if( strchr(Shiplist, ',') != NULL ) {
sprintf(Shiplist, "%d,%d",
Pathx[0], Pathy[0]);
}
fprintf(fdscrpt,"nav %s ", Shiplist);
moveit();
fprintf(fdscrpt, "\ne\n");
break;
}
}
}
}
moveit()
{
int i, ix, iy, row, col;
row = Pathy[0] - Yl + 1;
col = (Pathx[0] - Xl)*3 + 2;
mvcrsr(row, col);
putchar('@');
mvcrsr(row, col);
for( i = 1; i < Pathl; i++ ) {
ix = Pathx[i] - Pathx[i-1];
if( ix < -1 ) ix += XYMAX;
if( ix > 1 ) ix -= XYMAX;
iy = Pathy[i] - Pathy[i-1];
if( iy < -1 ) iy += XYMAX;
if( iy > 1 ) iy -= XYMAX;
fprintf(fdscrpt, "%s", Movdir[(ix+1)*3 + (iy+1)]);
row = Pathy[i] - Yl + 1;
col = (Pathx[i] - Xl)*3 + 2;
mvcrsr(row, col);
putchar('@');
mvcrsr(row, col);
}
}
prfunc()
{
mvcrsr(1, Censtrt);
printf("Func: %-3s", Fchar[Func]);
}
prcoord()
{
mvcrsr(2, Censtrt);
printf("Center: %3d,%-3d", Xcen, Ycen);
}
prdes()
{
mvcrsr(3, Censtrt);
printf("Desig: %c ", Desig);
}
prrsrc()
{
mvcrsr(3, Censtrt);
printf("Resource: %c ", Rchar[Rsrc]);
}
prthresh()
{
mvcrsr(4, Censtrt);
printf("Thresh: %-3d", Thresh);
}
prquant()
{
mvcrsr(4, Censtrt);
printf("Quant: %-4d", Quant);
}
prorder()
{
mvcrsr(3, Censtrt);
printf("Order %-8s", Sorder);
}
prshpnum()
{
mvcrsr(4, Censtrt);
printf("Ship: %-5d", Shpnum);
}
prnav()
{
char *p, out[8];
int i;
mvcrsr(4, Censtrt);
p = Shiplist;
for( i = 0; i < 7; i++ ) {
if( *p == '\0' || *p == '/' ) break;
out[i] = *p++;
}
out[i] = '\0';
printf("Ship: %-5s", out);
}
prship()
{
short mbl;
if( getship(&Ship, Shpnum) == ERROR ) return;
mvcrsr(5, Censtrt);
printf(" ");
mvcrsr(6, Censtrt);
printf("%c%5d,%-3d %3d ",
toupper(Stype[ Ship.shp_type ]),
Ship.shp_xp, Ship.shp_yp,
Ship.shp_own);
mvcrsr(7, Censtrt);
/* kluge to handle unsigned characters (so ship.h doesn't have to change) */
if( (mbl = Ship.shp_mbl) > 127 ) mbl -= 256;
printf("%3d%% %c %3d ",
Ship.shp_effc,
Ship.shp_fleet,
mbl);
mvcrsr(8, Censtrt);
if( Ship.shp_type == S_CAR ) {
printf("%3d %3d %2d %3d ",
Ship.shp_crew, Ship.shp_shels,
Ship.shp_gun, Ship.shp_plns);
} else {
printf("%3d %3d %2d ",
Ship.shp_crew, Ship.shp_shels,
Ship.shp_gun);
}
}
prshpsum()
{
int num, frlist[TMAXNO+1], foelist[TMAXNO+1];
int i;
rewind( fdship );
num = 0;
for( i = 0; i <= TMAXNO; i++ ) {
frlist[i] = foelist[i] = 0;
}
while( getship(&Ship, num++) != ERROR ) {
if( Ship.shp_effc == 0 ) continue;
if( (Ship.shp_xp - Xcur)%XYMAX != 0 ) continue;
if( (Ship.shp_yp - Ycur)%XYMAX != 0 ) continue;
if( Foe != 0 && Ship.shp_own != 0 &&
Foe != Ship.shp_own ) continue;
if( Ship.shp_own == 0 ) {
frlist[Ship.shp_type]++;
} else {
foelist[Ship.shp_type]++;
}
}
mvcrsr(5, Censtrt);
printf("%2.0dc %2.0db %2.0dd %2.0dt",
frlist[S_CAR], frlist[S_BAT], frlist[S_DES], frlist[S_TEN]);
mvcrsr(6, Censtrt);
printf("%2.0ds %2.0dp %2.0dm %2.0df",
frlist[S_SUB], frlist[S_PT ], frlist[S_MIN], frlist[S_FRE]);
mvcrsr(7, Censtrt);
printf("%2.0dc %2.0db %2.0dd %2.0dt",
foelist[S_CAR], foelist[S_BAT], foelist[S_DES], foelist[S_TEN]);
mvcrsr(8, Censtrt);
printf("%2.0ds %2.0dp %2.0dm %2.0df",
foelist[S_SUB], foelist[S_PT ], foelist[S_MIN], foelist[S_FRE]);
}
prshplst()
{
int num, field, frfld, foefld;
int i;
rewind(fdship);
num = 0;
frfld = 0;
foefld = 21;
while( getship(&Ship, num++) != ERROR ) {
if( Ship.shp_effc == 0 ) continue;
if( (Ship.shp_xp - Xcur)%XYMAX != 0 ) continue;
if( (Ship.shp_yp - Ycur)%XYMAX != 0 ) continue;
if( Foe != 0 && Ship.shp_own != 0 &&
Foe != Ship.shp_own ) continue;
for( i=0; i<=TMAXNO && Sorder[i]!='\0'; i++ ) {
if( Sorder[i] == Stype[Ship.shp_type]) break;
}
if( Sorder[i] != Stype[Ship.shp_type]) continue;
if( Ship.shp_own == 0 ) {
field = (frfld > 20) ? 20 : frfld++;
} else {
field = (foefld > 41) ? 41 : foefld++;
}
mvcrsr(10 + field/3, Censtrt + (field%3)*5);
printf("%c%-4d",Stype[Ship.shp_type], num-1);
}
for( ; frfld <= 20; frfld++ ) {
mvcrsr(10 + frfld/3, Censtrt + (frfld%3)*5);
printf(" ");
}
for( ; foefld <= 41; foefld++ ) {
mvcrsr(10 + foefld/3, Censtrt + (foefld%3)*5);
printf(" ");
}
}
addsec()
{
int i;
if( Func == MOV || Func == NAV ) {
i = (Pathl == 0) ? 0 : Pathl - 1;
if( Pathl != 0 &&
adjacent(Xcur,Ycur,Pathx[i],Pathy[i]) != OK ) {
return(ERROR);
}
if( Pathl == 0 || Xcur != Pathx[i] || Ycur != Pathy[i] ) {
Pathx[Pathl] = Xcur;
Pathy[Pathl] = Ycur;
Pathl++;
putchar('@');
}
}
Xlast = Xcur;
Ylast = Ycur;
return(OK);
}
delsec()
{
if( Func == MOV || Func == NAV ) {
getsec(&s, secno(Xcur, Ycur));
putchar(s.s_des);
if( Pathl <= 0 ) return;
Pathl--;
if( Pathl <= 0 ) return;
Xcur = Pathx[Pathl-1];
Ycur = Pathy[Pathl-1];
}
}
adjacent(x, y, xl, yl)
int x, y, xl, yl;
{
int xdiff, ydiff;
xdiff = x - xl;
if( xdiff < 0 ) xdiff = -xdiff;
if( xdiff == (XYMAX-1) ) xdiff = 1;
ydiff = y - yl;
if( ydiff < 0 ) ydiff = -ydiff;
if( ydiff == (XYMAX-1) ) ydiff = 1;
if( (xdiff == 0 || xdiff == 1) &&
(ydiff == 0 || ydiff == 1) ) return(OK);
return(ERROR);
}
prmap()
{
int height, width, xm, ym, row, col, nosect;
clrscrn();
prfunc();
prcoord();
fflush(stdout);
sleep(1); /* to make some terminals work at 9600 baud */
height = Termh - 3;
width = Termw - CENSW - 4;
row = 1;
Yl = Ycen - height/2;
Yh = Ycen + height/2;
Xl = Xcen - width/6;
Xh = Xcen + width/6;
for( ym = Yl; ym <= Yh; ym++ ) {
col = 1;
nosect = TRUE;
for( xm = Xl; xm <= Xh; xm++ ) {
getsec(&s, secno(xm, ym));
if( s.s_des != '\0' && s.s_des != ' ' ) {
if( nosect == TRUE ) {
mvcrsr(row, col);
nosect = FALSE;
}
if( s.s_coun != 0 && s.s_coun != 99 ) {
if( s.s_des != '?' ) {
if(Foe==0 || s.s_coun==98) {
putchar('?');
} else {
printf("%1d",
s.s_coun%10);
}
} else {
putchar(' ');
}
putchar(s.s_des);
putchar(' ');
} else if( s.s_coun == 99 ) {
putchar('~');
putchar(s.s_des);
putchar(' ');
} else if( s.s_coun == 0 ) {
if( Func == DEL ) {
putchar(Rtdirl[(int)(s.s_del[Rsrc]&017)]);
} else {
putchar(' ');
}
if( s.s_des == '.' && s.s_rsrc[SHL] != 0 ) {
putchar(':');
} else {
putchar(s.s_des);
}
if( Func == DEL ) {
putchar(Rtdirr[(int)(s.s_del[Rsrc]&017)]);
} else {
putchar(' ');
}
}
} else {
nosect = TRUE;
}
col += 3;
}
row++;
}
mvcrsr((Ycen - Yl), (Xcen - Xl)*3);
}
prcen()
{
char amntstr[8], thstr[8];
int i, xcur, ycur;
xcur = Xcur; ycur = Ycur;
if( Xcur < -XYMAX/2 ) xcur = Xcur + XYMAX;
if( Xcur > XYMAX/2 ) xcur = Xcur - XYMAX;
if( Ycur < -XYMAX/2 ) ycur = Ycur + XYMAX;
if( Ycur > XYMAX/2 ) ycur = Ycur - XYMAX;
mvcrsr(9, Censtrt);
if( s.s_des == '\0' ) s.s_des = ' ';
printf("%c%5d,%-3d %3d", s.s_des, xcur, ycur, s.s_coun);
}
prfcen()
{
int i, thrsh;
char amntstr[8], thstr[8];
mvcrsr(10, Censtrt);
printf(" ");
mvcrsr(11, Censtrt);
printf("%3d%%%10d", s.s_eff, s.s_mob);
mvcrsr(12, Censtrt);
printf("m%4d gm%4d", s.s_min, s.s_gold);
mvcrsr(13, Censtrt);
printf(" ");
for( i = 0; i <= BAR; i++ ) {
mvcrsr(14+i, Censtrt);
sprintf(amntstr, "%d", s.s_rsrc[i]);
if( *amntstr == '0' ) *amntstr = '.';
thrsh = (s.s_del[i] >> 4) & 017;
thrsh *= 8;
if( s.s_des == 'u' && i == CIV ) thrsh *= 10;
if( s.s_des == 'b' && i == BAR ) thrsh *= 4;
if( s.s_des == 'w' && (i==SHL || i==GUN ||
i==ORE) ) thrsh *= 10;
sprintf(thstr, "%d ", thrsh);
if( *thstr == '0' ) *thstr = '.';
printf("%c%5s%3s%5s ", Rchar[i], amntstr, Deldir[(int)(s.s_del[i]&017)], thstr);
}
mvcrsr(22, Censtrt);
printf("prod%4d %c%c", s.s_prod, s.s_ckpt, s.s_def);
}
char
onmap()
{
int row, col;
char c;
rawmode();
if( Func != SHP ) {
getsec(&s, secno(Xcur, Ycur));
prcen();
}
row = Ycur - Yl + 1;
col = (Xcur - Xl)*3 + 2;
mvcrsr(row, col);
while( c = getchar() ) {
switch( c ) {
case LF:
case CR:
ckdmode();
return('\n');
case TAB:
case 'i':
case 'I':
case PLUS:
case MINUS:
case SPACE:
return(c);
}
switch( c ) {
case UPLEFT:
case LEFT :
case DNLEFT:
case VILEFT:
if( Xcur <= Xl ) break;
Xcur--;
col -= 3;
break;
case UPRIGHT:
case RIGHT :
case DNRIGHT:
case VIRIGHT:
if( Xcur >= Xh ) break;
Xcur++;
col += 3;
break;
case DOWN:
case UP:
case VIDN:
case VIUP:
break;
default:
continue;
}
switch( c ) {
case UPLEFT:
case UP :
case UPRIGHT:
case VIUP:
if( Ycur <= Yl ) break;
Ycur--;
row--;
break;
case DNLEFT:
case DOWN :
case DNRIGHT:
case VIDN:
if( Ycur >= Yh ) break;
Ycur++;
row++;
break;
}
getsec(&s, secno(Xcur, Ycur));
prcen();
mvcrsr(row, col);
}
}
@//E*O*F ./EHELP/ehelp.c//
chmod u=rw,g=r,o=r ./EHELP/ehelp.c
echo x - ./EHELP/Makefile
sed 's/^@//' > "./EHELP/Makefile" <<'@//E*O*F ./EHELP/Makefile//'
INSDIR=..
LIBDIR=../_unix.O
GENLIB=$(LIBDIR)/genlib.a
TERMLIB=$(LIBDIR)/termlib.a
HDRDIR=../hdrs
HEADERS= \
$(HDRDIR)/emp.h \
$(HDRDIR)/ship.h
CFLAGS= -c -O
ehelp: $(INSDIR)/ehelp
$(INSDIR)/ehelp: _unix.O/ehelp.o $(GENLIB) $(TERMLIB)
$(CC) -o $(INSDIR)/ehelp _unix.O/ehelp.o $(GENLIB) $(TERMLIB)
_unix.O/ehelp.o: ehelp.c $(HEADERS)
$(CC) $(CFLAGS) -I$(HDRDIR) ehelp.c
@mv ehelp.o _unix.O/ehelp.o
clean:
rm -f _unix.O/*.o
clobber: clean
rm -f $(INSDIR)/ehelp
FRC:
@//E*O*F ./EHELP/Makefile//
chmod u=rw,g=r,o=r ./EHELP/Makefile
echo mkdir - ./EHELP/_unix.O
mkdir ./EHELP/_unix.O
chmod u=rwx,g=rx,o=rx ./EHELP/_unix.O
echo x - ./EHELP/_unix.O/ehelp.o
sed 's/^@//' > "./EHELP/_unix.O/ehelp.o" <<'@//E*O*F ./EHELP/_unix.O/ehelp.o//'
@//E*O*F ./EHELP/_unix.O/ehelp.o//
chmod u=rw,g=r,o=r ./EHELP/_unix.O/ehelp.o
exit 0