--- /dev/null
+/* %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",
+ "<ctrl-L>: redraw screen"
+};
+int cmd_lines = 19;
+
+char *help_user[] = {
+ "USER MODE",
+ "QWE",
+ "A D movement directions",
+ "ZXC",
+ "<space>: sit",
+ "Build: change city production",
+ "Fill: set func to fill",
+ "Grope: set func to explore",
+ "Help: display this text",
+ "I <dir>: 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 <piece> <func>: set city func",
+ "Y: set func to attack",
+ "<ctrl-L>: 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 <dir>: 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 <piece> <func>: set city func",
+ "Y: set func to attack",
+ "<ctrl-L>: redraw screen",
+ "?: describe piece"
+};
+int edit_lines = 22;
--- /dev/null
+/* %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 <stdio.h>
+#include <stdlib.h>
+#include <curses.h>
+#include <ctype.h>
+
+#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 ();
+}
+
+
+