From: Eric S. Raymond Date: Mon, 27 Sep 2004 15:12:54 +0000 (+0000) Subject: Initial revision X-Git-Tag: 1.7~4 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=1dd22911de365b648d9e132f1276f2172d426fde;p=vms-empire.git Initial revision --- diff --git a/data.c b/data.c new file mode 100644 index 0000000..a20de1f --- /dev/null +++ b/data.c @@ -0,0 +1,264 @@ +/* %W% %G% %U% - (c) Copyright 1987, 1988 Chuck Simmons */ + +/* + * Copyright (C) 1987, 1988 Chuck Simmons + * + * See the file COPYING, distributed with empire, for restriction + * and warranty information. + */ + +/* +Static data. + +One of our hopes is that changing the types of pieces that +exist in the game is mostly a matter of modifying this file. +However, see also the help routine, empire.h, and empire.doc. +*/ + +#include "empire.h" + +/* +Piece attributes. Notice that the Transport is allowed only one hit. +In the previous version of this game, the user could easily win simply +by building armies and troop transports. We attempt to alleviate this +problem by making transports far more fragile. We have also increased +the range of a fighter from 20 to 30 so that fighters will be somewhat +more useful. +*/ + +piece_attr_t piece_attr[] = { + {'A', /* character for printing piece */ + "army", /* name of piece */ + "army", /* nickname */ + "an army", /* name with preceding article */ + "armies", /* plural */ + "+", /* terrain */ + 5, /* units to build */ + 1, /* strength */ + 1, /* max hits */ + 1, /* movement */ + 0, /* capacity */ + INFINITY}, /* range */ + + /* + For fighters, the range is set to an even multiple of the speed. + This allows user to move fighter, say, two turns out and two + turns back. + */ + + {'F', "fighter", "fighter", "a fighter", "fighters", + ".+", 10, 1, 1, 8, 0, 32}, + + {'P', "patrol boat", "patrol", "a patrol boat", "patrol boats", + ".", 15, 1, 1, 4, 0, INFINITY}, + + {'D', "destroyer", "destroyer", "a destroyer", "destroyers", + ".", 20, 1, 3, 2, 0, INFINITY}, + + {'S', "submarine", "submarine", "a submarine", "submarines", + ".", 20, 3, 2, 2, 0, INFINITY}, + + {'T', "troop transport", "transport", "a troop transport", "troop transports", + ".", 30, 1, 1, 2, 6, INFINITY}, + + {'C', "aircraft carrier", "carrier", "an aircraft carrier", "aircraft carriers", + ".", 30, 1, 8, 2, 8, INFINITY}, + + {'B', "battleship", "battleship", "a battleship", "battleships", + ".", 40, 2, 10, 2, 0, INFINITY}, + + {'Z', "satellite", "satellite", "a satellite", "satellites", + ".+", 50, 0, 1, 10, 0, 500} +}; + +/* Direction offsets. */ + +int dir_offset [] = {-MAP_WIDTH, /* north */ + -MAP_WIDTH+1, /* northeast */ + 1, /* east */ + MAP_WIDTH+1, /* southeast */ + MAP_WIDTH, /* south */ + MAP_WIDTH-1, /* southwest */ + -1, /* west */ + -MAP_WIDTH-1}; /* northwest */ + +/* Names of movement functions. */ + +char *func_name[] = {"none", "random", "sentry", "fill", "land", + "explore", "load", "attack", "load", "repair", + "transport", + "W", "E", "D", "C", "X", "Z", "A", "Q"}; + +/* The order in which pieces should be moved. */ +int move_order[] = {SATELLITE, TRANSPORT, CARRIER, BATTLESHIP, + PATROL, SUBMARINE, DESTROYER, ARMY, FIGHTER}; + +/* types of pieces, in declared order */ +char type_chars[] = "AFPDSTCBZ"; + +/* Lists of attackable objects if object is adjacent to moving piece. */ + +char tt_attack[] = "T"; +char army_attack[] = "O*TACFBSDP"; +char fighter_attack[] = "TCFBSDPA"; +char ship_attack[] = "TCBSDP"; + +/* Define various types of objectives */ + +move_info_t tt_explore = { /* water objectives */ + COMP, /* home city */ + " ", /* objectives */ + {1} /* weights */ +}; +move_info_t tt_load = { /* land objectives */ + COMP, "$", {1} +}; + +/* +Rationale for 'tt_unload': + + Any continent with four or more cities is extremely attractive, +and we should grab it quickly. A continent with three cities is +fairly attractive, but we are willing to go slightly out of our +way to find a better continent. Similarily for two cities on a +continent. At one city on a continent, things are looking fairly +unattractive, and we are willing to go quite a bit out of our way +to find a better continent. + + Cities marked with a '0' are on continents where we already +have cities, and these cities will likely fall to our armies anyway, +so we don't need to dump armies on them unless everything else is +real far away. We would prefer to use unloading transports for +taking cities instead of exploring, but we are willing to explore +if interesting cities are too far away. + + It has been suggested that continents containing one city +are not interesting. Unfortunately, most of the time what the +computer sees is a single city on a continent next to lots of +unexplored territory. So it dumps an army on the continent to +explore the continent and the army ends up attacking the city +anyway. So, we have decided we might as well send the tt to +the city in the first place and increase the speed with which +the computer unloads its tts. +*/ + +move_info_t tt_unload = { + COMP, "9876543210 ", {1, 1, 1, 1, 1, 1, 11, 21, 41, 101, 61} +}; + +/* + '$' represents loading tt must be first + 'x' represents tt producing city + '0' represnets explorable territory +*/ +move_info_t army_fight = { /* land objectives */ + COMP, "O*TA ", {1, 1, 1, 1, 11} +}; +move_info_t army_load = { /* water objectives */ + COMP, "$x", {1, W_TT_BUILD} +}; + +move_info_t fighter_fight = { + COMP, "TCFBSDPA ", {1, 1, 5, 5, 5, 5, 5, 5, 9} +}; +move_info_t ship_fight = { + COMP, "TCBSDP ", {1, 1, 3, 3, 3, 3, 21} +}; +move_info_t ship_repair = { + COMP, "X", {1} +}; + +move_info_t user_army = { + USER, " ", {1} +}; +move_info_t user_army_attack = { + USER, "*Xa ", {1, 1, 1, 12} +}; +move_info_t user_fighter = { + USER, " ", {1} +}; +move_info_t user_ship = { + USER, " ", {1} +}; +move_info_t user_ship_repair = { + USER, "O", {1} +}; + +/* +Various help texts. +*/ + +char *help_cmd[] = { + "COMMAND MODE", + "Auto: enter automove mode", + "City: give city to computer", + "Date: print round", + "Examine: examine enemy map", + "File: print map to file", + "Give: give move to computer", + "Help: display this text", + "J: enter edit mode", + "Move: make a move", + "N: give N moves to computer", + "Print: print a sector", + "Quit: quit game", + "Restore: restore game", + "Save: save game", + "Trace: save movie in empmovie.dat", + "Watch: watch movie", + "Zoom: display compressed map", + ": redraw screen" +}; +int cmd_lines = 19; + +char *help_user[] = { + "USER MODE", + "QWE", + "A D movement directions", + "ZXC", + ": sit", + "Build: change city production", + "Fill: set func to fill", + "Grope: set func to explore", + "Help: display this text", + "I : set func to dir", + "J: enter edit mode", + "Kill: set func to awake", + "Land: set func to land", + "Out: leave automove mode", + "Print: redraw screen", + "Random: set func to random", + "Sentry: set func to sentry", + "Upgrade: set func to repair", + "V : set city func", + "Y: set func to attack", + ": redraw screen", + "?: describe piece" +}; +int user_lines = 22; + +char *help_edit[] = { + "EDIT MODE", + "QWE", + "A D movement directions", + "ZXC", + "Build: change city production", + "Fill: set func to fill", + "Grope: set func to explore", + "Help: display this text", + "I : set func to dir", + "Kill: set func to awake", + "Land: set func to land", + "Mark: mark piece", + "N: set dest for marked piece", + "Out: exit edit mode", + "Print: print sector", + "Random: set func to random", + "Sentry: set func to sentry", + "Upgrade: set func to repair", + "V : set city func", + "Y: set func to attack", + ": redraw screen", + "?: describe piece" +}; +int edit_lines = 22; diff --git a/term.c b/term.c new file mode 100644 index 0000000..e1d09d9 --- /dev/null +++ b/term.c @@ -0,0 +1,458 @@ +/* %W% %G% %U% - (c) Copyright 1987, 1988 Chuck Simmons */ + +/* + * Copyright (C) 1987, 1988 Chuck Simmons + * + * See the file COPYING, distributed with empire, for restriction + * and warranty information. + */ + +/* +term.c -- this file contains various routines used to control the +user communications area of the terminal. This area consists of +the top 3 lines of the terminal where messages are displayed to the +user and input is acquired from the user. + +There are two types of output in this area. One type is interactive +output. This consists of a prompt line and an error message line. +The other type of output is informational output. The user must +be given time to read informational output. + +Whenever input is received, the top three lines are cleared and the +screen refreshed as the user has had time to read these lines. We +also clear the 'need_delay' flag, saying that the user has read the +information on the screen. + +When information is to be displayed, if the 'need_delay' flag is set, +we refresh the screen and pause momentarily to give the user a chance +to read the lines. The new information is then displayed, and the +'need_delay' flag is set. +*/ + +#include +#include +#include +#include + +#include "empire.h" +#include "extern.h" + +static int need_delay; +static FILE *my_stream; +void +/* VARARGS1 */ +pdebug (s, a, b, c, d, e, f, g, h) +char *s; +int a, b, c, d, e, f, g, h; +{ + if (!print_debug) return; + comment (s, a, b, c, d, e, f, g, h); +} + +/* +Here are routines that handle printing to the top few lines of the +screen. 'topini' should be called at initialization, and whenever +we finish printing information to the screen. +*/ + +void +topini() +{ + info (0, 0, 0); +} +/* +Write a message to one of the top lines. +*/ + +void +/* VARARGS2 */ +topmsg(linep, buf, a, b, c, d, e, f, g, h) +int linep; +char *buf; +int a, b, c, d, e, f, g, h; +{ + if (linep < 1 || linep > NUMTOPS) + linep = 1; + (void) move (linep - 1, 0); + + if (buf != NULL && strlen (buf) > 0) + addprintf (buf, a, b, c, d, e, f, g, h); + + (void) clrtoeol (); +} + +void +topmsg1 (linep, buf, a, b, c, d, e, f, g, h) +int linep; +char *buf; +char *a; +int b, c, d, e, f, g, h; +{ + if (linep < 1 || linep > NUMTOPS) + linep = 1; + (void) move (linep - 1, 0); + + if (buf != NULL && strlen (buf) > 0) + addprintf1 (buf, a, b, c, d, e, f, g, h); + + (void) clrtoeol (); +} +void +topmsg2 (linep, buf, a, b, c, d, e, f, g, h) +int linep; +char *buf; +char *a, *e, *f; +int b, c, d, g, h; +{ + if (linep < 1 || linep > NUMTOPS) + linep = 1; + (void) move (linep - 1, 0); + + if (buf != NULL && strlen (buf) > 0) + addprintf2 (buf, a, b, c, d, e, f, g, h); + + (void) clrtoeol (); +} +/* +Print a prompt on the first message line. +*/ + +void +/* VARARGS1 */ +prompt (buf, a, b, c, d, e, f, g, h) +char *buf; +int a,b,c,d,e,f,g,h; +{ + topmsg (1, buf, a, b, c, d, e, f, g, h); +} +void +prompt1 (buf, a, b, c, d, e, f, g, h) +char *buf, *a; +int b,c,d,e,f,g,h; +{ + topmsg1 (1, buf, a, b, c, d, e, f, g, h); +} +void +prompt2 (buf, a, b, c, d, e, f, g, h) +char *buf, *a, *e, *f; +int b,c,d,g,h; +{ + topmsg2 (1, buf, a, b, c, d, e, f, g, h); +} + +/* +Print an error message on the second message line. +*/ + +void +/* VARARGS1 */ +error (buf, a, b, c, d, e, f, g, h) +char *buf; +int a, b, c, d, e, f, g, h; +{ + topmsg (2, buf, a, b, c, d, e, f, g, h); +} + +/* +Print out extra information. +*/ + +void +/* VARARGS1 */ +extra (buf, a, b, c, d, e, f, g, h) +char *buf; +int a, b, c, d, e, f, g, h; +{ + topmsg (3, buf, a, b, c, d, e, f, g, h); +} + +/* +Print out a generic error message. +*/ + +void +huh () +{ + error ("Type H for Help.",0,0,0,0,0,0,0,0); +} + +/* +Display information on the screen. If the 'need_delay' flag is set, +we force a delay, then print the information. After we print the +information, we set the need_delay flag. +*/ + +void +info (a, b, c) +char *a, *b, *c; +{ + if (need_delay) delay (); + topmsg (1, a,0,0,0,0,0,0,0,0); + topmsg (2, b,0,0,0,0,0,0,0,0); + topmsg (3, c,0,0,0,0,0,0,0,0); + need_delay = (a || b || c); +} + +void +set_need_delay () { + need_delay = 1; +} + +void +comment (buf, a, b, c, d, e, f, g, h) +char *buf; +int a, b, c, d, e, f, g, h; +{ + if (need_delay) delay (); + topmsg (1, 0,0,0,0,0,0,0,0,0); + topmsg (2, 0,0,0,0,0,0,0,0,0); + topmsg (3, buf, a, b, c, d, e, f, g, h); + need_delay = (buf != 0); +} + +void +comment1 (buf, a, b, c, d, e, f, g, h) +char *buf, *a; +int b, c, d, e, f, g, h; +{ + if (need_delay) delay (); + topmsg1 (1, 0,0,0,0,0,0,0,0,0); + topmsg1 (2, 0,0,0,0,0,0,0,0,0); + topmsg1 (3, buf, a, b, c, d, e, f, g, h); + need_delay = (buf != 0); +} + +/* kermyt begin */ +void +ksend (buf, a, b, c, d, e, f, g, h) +char *buf; +int a,b,c,d,e,f,g,h; +{ + if(!(my_stream=fopen("info_list.txt","a"))) + { + error("Cannot open info_list.txt",0,0,0,0,0,0,0,0); + return; + } + fprintf(my_stream, buf, a, b, c, d, e, f, g, h); + fclose(my_stream); + return; +} +void +ksend1 (buf, a, b, c, d, e, f, g, h) +char *buf, *a; +int b,c,d,e,f,g,h; +{ + if(!(my_stream=fopen("info_list.txt","a"))) + { + error("Cannot open info_list.txt",0,0,0,0,0,0,0,0); + return; + } + fprintf(my_stream, buf, a, b, c, d, e, f, g, h); + fclose(my_stream); + return; +} +/* kermyt end */ +/* +Get a string from the user, echoing characters all the while. +*/ + +void +get_str (buf, sizep) +char *buf; +int sizep; +{ + (void) echo(); + get_strq(buf, sizep); + (void) noecho(); +} + +/* +Get a string from the user, ignoring the current echo mode. +*/ + +void +get_strq (buf, sizep) +char *buf; +int sizep; +{ + sizep = sizep; /* size of buf, currently unused */ + + (void) nocrmode (); + (void) refresh (); + (void) getstr (buf); + need_delay = FALSE; + info (0, 0, 0); + (void) crmode (); +} + +/* +Get a character from the user and convert it to uppercase. +*/ + +char +get_chx() +{ + char c; + + c = get_cq (); + + if (islower(c)) + return (upper(c)); + else + return (c); +} + +/* +Input an integer from the user. +*/ + +int +getint (message) +char *message; +{ + char buf[STRSIZE]; + char *p; + + for (;;) { /* until we get a legal number */ + prompt (message,0,0,0,0,0,0,0,0); + get_str (buf, sizeof (buf)); + + for (p = buf; *p; p++) { + if (*p < '0' || *p > '9') { + error ("Please enter an integer.",0,0,0,0,0,0,0,0); + break; + } + } + if (*p == 0) { /* no error yet? */ + if (p - buf > 7) /* too many digits? */ + error ("Please enter a small integer.",0,0,0,0,0,0,0,0); + else return (atoi (buf)); + } + } +} + +/* +Input a character from the user with echoing. +*/ + +char +get_c () +{ + char c; /* one char and a null */ + + (void) echo (); + c = get_cq (); + (void) noecho (); + return (c); +} + +/* +Input a character quietly. +*/ + +char +get_cq () +{ + char c; + + (void) crmode (); + (void) refresh (); + c = getch (); + topini (); /* clear information lines */ + (void) nocrmode (); + return (c); +} + +/* +Input a yes or no response from the user. We loop until we get +a valid response. We return TRUE iff the user replies 'y'. +*/ + +int +getyn (message) +char *message; +{ + char c; + + for (;;) { + prompt (message,0,0,0,0,0,0,0,0); + c = get_chx (); + + if (c == 'Y') return (TRUE); + if (c == 'N') return (FALSE); + + error ("Please answer Y or N.",0,0,0,0,0,0,0,0); + } +} + +/* +Input an integer in a range. +*/ + +int +get_range (message, low, high) +char *message; +int low, high; +{ + int result; + + for (;;) { + result = getint (message); + + if (result >= low && result <= high) return (result); + + error ("Please enter an integer in the range %d..%d.",low, high,0,0,0,0,0,0); + } +} + +/* +Print a screen of help information. +*/ + +void +help (text, nlines) +char **text; +int nlines; +{ + int i, r, c; + int text_lines; + + text_lines = (nlines + 1) / 2; /* lines of text */ + + clear_screen (); + + pos_str (NUMTOPS, 1, text[0],0,0,0,0,0,0,0,0); /* mode */ + pos_str (NUMTOPS, 41, "See empire.doc for more information.",0,0,0,0,0,0,0,0); + + for (i = 1; i < nlines; i++) { + if (i > text_lines) + pos_str (i - text_lines + NUMTOPS + 1, 41, text[i],0,0,0,0,0,0,0,0); + else pos_str (i + NUMTOPS + 1, 1, text[i],0,0,0,0,0,0,0,0); + } + + pos_str (text_lines + NUMTOPS + 2, 1, "--Piece---Yours-Enemy-Moves-Hits-Cost",0,0,0,0,0,0,0,0); + pos_str (text_lines + NUMTOPS + 2, 41, "--Piece---Yours-Enemy-Moves-Hits-Cost",0,0,0,0,0,0,0,0); + + for (i = 0; i < NUM_OBJECTS; i++) { + if (i >= (NUM_OBJECTS+1)/2) { + r = i - (NUM_OBJECTS+1)/2; + c = 41; + } + else { + r = i; + c = 1; + } + pos_str1 (r + text_lines + NUMTOPS + 3, c,"%-12s%c %c%6d%5d%6d", + piece_attr[i].nickname, + piece_attr[i].sname, + tolower (piece_attr[i].sname), + piece_attr[i].speed, + piece_attr[i].max_hits, + piece_attr[i].build_time,0,0); //FLAG + + } + (void) refresh (); +} + + +