DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T h

⟦37645e2a5⟧ TextFile

    Length: 14632 (0x3928)
    Types: TextFile
    Names: »help.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/X/Xconq/help.c« 

TextFile

/* Copyright (c) 1987, 1988  Stanley T. Shebs, University of Utah. */
/* This program may be used, copied, modified, and redistributed freely */
/* for noncommercial purposes, so long as this notice remains intact. */

/* RCS $Header: help.c,v 1.1 88/06/21 12:30:12 shebs Exp $ */

/* This file is devoted to commands and other functions related specifically */
/* to help.  Almost all of the xconq help code is here. */

/* At least in X, the help window covers most of the xconq display, so */
/* total redraws are necessary.  This can be slow - fix would be to do */
/* per-window redrawing only as need, and place help window to cover as few */
/* of the other windows as possible (especially world map). */

#include "config.h"
#include "misc.h"
#include "period.h"
#include "side.h"
#include "unit.h"
#include "map.h"

extern int helpwinlines;

/* Display the news file on stdout if it exists, be silent if it doesn't. */
/* (Used only during program startup.) */

maybe_dump_news()
{
    FILE *fp;

    make_pathname(XCONQLIB, NEWSFILE, "", spbuf);
    if ((fp = fopen(spbuf, "r")) != NULL) {
	while (fgets(spbuf, BUFSIZE-1, fp) != NULL) {
	    fputs(spbuf, stdout);
	}
	fclose(fp);
    }
}

/* The general help command.  It first lists the available commands, */
/* then a legend to map display, then the current news about xconq, then */
/* details about the period/units.  Player can page screens back and forth, */
/* which explains some odd index adjusts at bottom of loop. */

x_help(side)
Side *side;
{
    int i = side->reqvalue2;
    char opt = side->reqch;

    init_wprintf(side, NULL);
    switch (opt) {
    case ' ':
    case 'n':
	if (i < 4+period.numutypes) i++;
	break;
    case '-':
	if (i > 0) i--;
	break;
    default:
	conceal_help(side);
	redraw(side);
	return;
    }
    switch (i) {
    case 0:
	command_help(side);
	break;
    case 1:
	legend_help(side);
	break;
    case 2:
	make_pathname(XCONQLIB, NEWSFILE, "", spbuf);
	if (!show_file(side, spbuf)) {
	    wprintf(side, "No news is good news.");
	}
	break;
    case 3:
	describe_mapfiles(side);
	break;
    case 4:
	describe_period(side);
	break;
    default:
	/* i guaranteed to be in right range */
	describe_utype(side, i - 5);
	break;
    }
    ask_help_char(side);
    request_input(side, NULL, x_help);
    side->reqvalue2 = i;
}

/* The command proper must request a character for whether to go to next */
/* or previous screen, or to quit entirely. */

do_help(side, n)
Side *side;
int n;
{
    if (reveal_help(side)) {
	init_wprintf(side, NULL);
	command_help(side);
	ask_help_char(side);
	request_input(side, NULL, x_help);
	side->reqvalue2 = 0;
    }
}

/* Prompt for a char from help window. */

ask_help_char(side)
Side *side;
{
    char *help = "[Space bar to continue, '-' for prev, all else quits]";

    draw_fg_text(side, side->help, 0, (helpwinlines-1)*side->fh, help);
}

/* Generate a legend for all the various symbols and pictures. */
/* (Does not include cursor box or tiny side numbers.) */

legend_help(side)
Side *side;
{
    int t, u, tcol = 2 * side->margin + side->hw;
    int spacing = side->hh + 4 * side->margin;
    int offset = side->hh/4, second = 30*side->fw;

    /* first column of things is constant for all periods */
    draw_blast_icon(side, side->help,
		    side->margin, 0*spacing, 'b', side->enemycolor);
    draw_fg_text(side, side->help, tcol, 0*spacing+offset, "miss");
    draw_blast_icon(side, side->help,
		    side->margin, 1*spacing, 'c', side->enemycolor);
    draw_fg_text(side, side->help, tcol, 1*spacing+offset, "hit");
    draw_blast_icon(side, side->help,
		    side->margin, 2*spacing, 'd', side->enemycolor);
    draw_fg_text(side, side->help, tcol, 2*spacing+offset, "kill");
    for_all_terrain_types(t) {
	draw_hex_icon(side, side->help,
		      side->margin, (t+3)*spacing,
		      (side->monochrome ? side->fgcolor : side->hexcolor[t]),
		      (side->monochrome ? ttypes[t].tchar : HEX));
	draw_fg_text(side, side->help,
		     tcol, (t+3)*spacing+offset, ttypes[t].name);
    }
    for_all_unit_types(u) {
	draw_unit_icon(side, side->help,
		       second, u*spacing, u, side->fgcolor);
	draw_fg_text(side, side->help,
		     second+tcol, u*spacing+offset, utypes[u].name);
    }
}

/* This command provides a short note about the current hex.  It is */
/* useful as a supplement to the general help command. */

do_ident(side, n)
Side *side;
int n;
{
    char view = side_view(side, side->curx, side->cury);
    char t = terrain_at(side->curx, side->cury);
    Side *side2;

    if (view == UNSEEN) {
	notify(side, "You see unexplored territory");
    } else if (view == EMPTY) {
	notify(side, "You see unoccupied %s", ttypes[t].name);
    } else {
	side2 = side_n(vside(view));
	notify(side, "You see a %s %s (in the %s)",
	       (side2 == NULL ? "neutral" : side2->name),
	       utypes[vtype(view)].name, ttypes[t].name);
    }
}

/* Dump out the characteristics of a single unit type.  This works by */
/* jumping into the help loop, so all the other types can be looked at also. */

x_unit_info(side)
Side *side;
{
    int u;

    if ((u = find_unit_char(side->reqch)) >= 0) {
	if (u != NOTHING) {
	    if (reveal_help(side)) {
		init_wprintf(side, NULL);
		describe_utype(side, u);
		ask_help_char(side);
		request_input(side, NULL, x_help);
		side->reqvalue2 = u;
	    }
	}
	clear_prompt(side);
    } else {
	request_input(side, NULL, x_unit_info);
    }
}

/* The command proper just prompts and issues the request. */

do_unit_info(side, n)
Side *side;
int n;
{
    ask_unit_type(side, "Details on which unit type?", NULL);
    request_input(side, NULL, x_unit_info);
}

/* Spit out all the general period parameters in a readable fashion. */

describe_period(side)
Side *side;
{
    int u, r, t, i;

    wprintf(side, "This period is named \"%s\".", period.name);
    wprintf(side, "");
    wprintf(side,
	"It includes %d unit types, %d resource types, and %d terrain types.",
	    period.numutypes, period.numrtypes, period.numttypes);
    wprintf(side, "First unit type is %s, first product type is %s.",
	    (period.firstutype == NOTHING ? "none" :
	     utypes[period.firstutype].name),
	    (period.firstptype == NOTHING ? "none" :
	     utypes[period.firstptype].name));
    wprintf(side, "");
    wprintf(side,
	    "Countries are %d hexes across, between %d and %d hexes apart.",
	    period.countrysize, period.mindistance, period.maxdistance);
    wprintf(side, "Known area is %d hexes across.", period.knownradius);
    wprintf(side, "Default scale is %d km/hex.", period.scale);
    if (period.allseen)
	wprintf(side, "All units are always seen by all sides.");
    wprintf(side, "");
    if (period.counterattack)
	wprintf(side, "Defender always gets a counter-attack.");
    else
	wprintf(side, "Defender does not get a counter-attack.");
    wprintf(side, "Neutral units add %d%% to defense, hit over %d is a nuke.",
	    period.neutrality, period.nukehit);
    if (period.efficiency > 0)
	wprintf(side, "Unit recycling is %d%% efficient.", period.efficiency);
    wprintf(side, "");
    for_all_terrain_types(t) {
	wprintf(side, "Terrain:  %c  %s (%s)",
		ttypes[t].tchar, ttypes[t].name, ttypes[t].color);
    }
    wprintf(side, "");
    for_all_resource_types(r) {
	wprintf(side, "Resource: %c  %s (%s)",
		' ', rtypes[r].name, rtypes[r].help);
    }
    wprintf(side, "");
    for_all_unit_types(u) {
	wprintf(side, "Unit:     %c  %s (%s)",
		utypes[u].uchar, utypes[u].name, utypes[u].help);
    }
    wprintf(side, "");
    if (period.notes != NULL) {
	for (i = 0; period.notes[i] != NULL; ++i) {
	    wprintf(side, "%s", period.notes[i]);
	}
    }
}

/* Full details on the given type of unit.  This may be used either for */
/* online help or for building a descriptive file.  The icon will only */
/* show up for online help, otherwise the display calls have no effect. */

describe_utype(side, u)
Side *side;
int u;
{
    int r, t, u2;

    wprintf(side, "     '%c' %s      (territory value %d)",
	    utypes[u].uchar, utypes[u].name, utypes[u].territory);
    wprintf(side, "            %s", utypes[u].help);
    if (utypes[u].bitmapname != NULL)
	wprintf(side, "     bitmap \"%s\"", utypes[u].bitmapname);
    else 
	wprintf(side, "");
    draw_hex_icon(side, side->help, side->margin, side->margin,
		  side->fgcolor, HEX);
    draw_unit_icon(side, side->help, side->margin, side->margin,
		   u, side->bgcolor);
    wprintf(side, "Init: %d in country, %d/10000 hexes density, %s.",
	    utypes[u].incountry, utypes[u].density,
	    (utypes[u].named ? "named" : "unnamed"));
    wprintf(side, "Maximum speed %d hexes/turn, %d%% under control. %s %s",
	    utypes[u].speed, utypes[u].control,
	    (utypes[u].onemove ? "(auto)" : ""),
	    (utypes[u].jumpmove ? "(jumps)" : ""));
    wprintf(side, "%d HP, crippled at %d HP, chance to retreat %d%%.",
	    utypes[u].hp, utypes[u].crippled, utypes[u].retreat);
    wprintf(side, "%d%% extra for start up, %d%% extra for R&D.",
	    utypes[u].startup, utypes[u].research);
    wprintf(side, "%d extra moves used up by an attack.",
	    utypes[u].hittime);
    wprintf(side,
        "%d%% to succumb to siege, %d%% to revolt, attrition damage %d HP.",
	    utypes[u].siege, utypes[u].revolt, utypes[u].attdamage);
    if (utypes[u].seerange == 1) {
	wprintf(side, "Chance to see others %d%%.", utypes[u].seebest);
    } else {
	wprintf(side, "Chance to see %d%% at 1 hex, to %d%% at %d hexes.",
		utypes[u].seebest, utypes[u].seeworst, utypes[u].seerange);
    }
    wprintf(side, "Own visibility is %d.", utypes[u].visibility);
    if (utypes[u].volume > 0 || utypes[u].holdvolume > 0)
	wprintf(side, "Volume is %d, volume of hold is %d.",
		utypes[u].volume, utypes[u].holdvolume);
    wprintf(side, "%s %s",
	    (utypes[u].changeside ? "Can be made to change sides." : ""),
	    (utypes[u].disband ? "Can be disbanded and sent home." : ""));
    wprintf(side, "%s %s",
	    (utypes[u].maker ? "Builds units all the time." : ""),
	    (utypes[u].selfdestruct ? "Hits by self-destruction." : ""));
    wprintf(side, "");
    wprintf(side, "%s",
	    "  Resource   ToBui  Prod Store  Eats ToMov  Hits HitBy");
    wprintf(side, "%s",
	    "               (0)   (0)   (0)   (0)   (0)   (0)   (0)");
    for_all_resource_types(r) {
	sprintf(spbuf, "%10s: ", rtypes[r].name);
	append_number(spbuf, utypes[u].tomake[r], 0);
	append_number(spbuf, utypes[u].produce[r], 0);
	append_number(spbuf, utypes[u].storage[r], 0);
	append_number(spbuf, utypes[u].consume[r], 0);
	append_number(spbuf, utypes[u].tomove[r], 0);
	append_number(spbuf, utypes[u].hitswith[r], 0);
	append_number(spbuf, utypes[u].hitby[r], 0);
	wprintf(side, "%s", spbuf);
    }
    wprintf(side, "");
    wprintf(side, "%s",
	    "   Terrain  Slowed Rand% Hide% Defn% Prod% Attr% Acdn%");
    wprintf(side, "%s",
	    "               (-)   (0)   (0)   (0)   (0)   (0)   (0)");
    for_all_terrain_types(t) {
	sprintf(spbuf, "%10s: ", ttypes[t].name);
	append_number(spbuf, utypes[u].moves[t], -1);
	append_number(spbuf, utypes[u].randommove[t], 0);
	append_number(spbuf, utypes[u].conceal[t], 0);
	append_number(spbuf, utypes[u].defense[t], 0);
	append_number(spbuf, utypes[u].productivity[t], 0);
	append_number(spbuf, utypes[u].attrition[t], 0);
	append_number(spbuf, utypes[u].accident[t], 0);
	wprintf(side, "%s", spbuf);
    }
    wprintf(side, "");
    wprintf(side, "%s%s",
	    "     Hit%  Damg  Cap% Guard  Pro%",
	    " Holds Enter Leave  Mob% Bridg Build   Fix");
    wprintf(side, "%s%s",
	    "      (0)   (0)   (0)   (0)   (0)",
	    "   (0)   (1)   (0) (100)   (0)   (0)   (0)");
    for_all_unit_types(u2) {
	sprintf(spbuf, "%c: ", utypes[u2].uchar);
	append_number(spbuf, utypes[u].hit[u2], 0);
	append_number(spbuf, utypes[u].damage[u2], 0);
	append_number(spbuf, utypes[u].capture[u2], 0);
	append_number(spbuf, utypes[u].guard[u2], 0);
	append_number(spbuf, utypes[u].protect[u2], 0);
	append_number(spbuf, utypes[u].capacity[u2], 0);
	append_number(spbuf, utypes[u].entertime[u2], 1);
	append_number(spbuf, utypes[u].leavetime[u2], 0);
	append_number(spbuf, utypes[u].mobility[u2], 100);
	append_number(spbuf, utypes[u].bridge[u2], 0);
	append_number(spbuf, utypes[u].make[u2], 0);
	append_number(spbuf, utypes[u].repair[u2], 0);
	wprintf(side, "%s", spbuf);
    }
    wprintf(side, "");
}

/* A simple table-printing utility. Blanks out default values so they don't */
/* clutter the table. */

append_number(buf, value, dflt)
char *buf;
int value, dflt;
{
    if (value != dflt) {
	sprintf(tmpbuf, "%5d ", value);
	strcat(buf, tmpbuf);
    } else {
	strcat(buf, "      ");
    }
}

/* Dump assorted information into files, so they can be studied at leisure, */
/* or by people with screens too small for online help. */

do_printables(side, n)
Side *side;
int n;
{
    int u;

    init_wprintf(side, CMDFILE);
    command_help(side);
    finish_wprintf();
    notify(side, "Dumped commands to \"%s\".", CMDFILE);
    init_wprintf(side, PARMSFILE);
    describe_period(side);
    for_all_unit_types(u) {
	wprintf(side, "--------------------------------------------------");
	wprintf(side, "");
	describe_utype(side, u);
	wprintf(side, "");
    }
    finish_wprintf();
    notify(side, "Dumped period data to \"%s\".", PARMSFILE);
    dump_view(side);
    notify(side, "Dumped current view to \"%s\".", VIEWFILE);
}

/* Put the current view into a file. */

dump_view(side)
Side *side;
{
    char ch1, ch2;
    int x, y, i, view, vs;
    Side *side2;
    FILE *fp;

    if ((fp = fopen(VIEWFILE, "w")) != NULL) {
	for (y = world.height-1; y >= 0; --y) {
	    for (i = 0; i < y; ++i) fputc(' ', fp);
	    for (x = 0; x < world.width; ++x) {
		view = side_view(side, x, y);
		if (view == UNSEEN) {
		    ch1 = ch2 = ' ';
		} else if (view == EMPTY) {
		    ch1 = ttypes[terrain_at(x, y)].tchar;
		    ch2 = (side->showmode == BORDERHEX ? ' ' : ch1);
		} else {
		    ch1 = utypes[vtype(view)].uchar;
		    vs = vside(view);
		    side2 = side_n(vside(view));
		    ch2 = (side2 ? ((side == side2) ? ' ' : vs + '0') : '`');
		}
		fputc(ch1, fp);
		fputc(ch2, fp);
	    }
	    fprintf(fp, "\n");
	}
    } else {
	notify(side, "Can't open \"%s\"!!", VIEWFILE);
    }
}

/* This kicks in on a unit type prompt.  Just give barest details, rely */
/* on general help for full unit descriptions.  This could be spiffier */
/* and use the help window, but getting the interaction right is just too */
/* hard... */

help_unit_type(side)
Side *side;
{
    int u;

    for_all_unit_types(u) {
	if (side->bvec[u]) {
	    notify(side, " %c  %s;  %s",
		   utypes[u].uchar, utypes[u].name, utypes[u].help);
	}
    }
}