|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T h
Length: 14632 (0x3928) Types: TextFile Names: »help.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/X/Xconq/help.c«
/* 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); } } }