shebs@utah-cs.UUCP (Stanley Shebs) (07/21/88)
This is the first official patch to version 5 of xconq. It is primarily bug fixes, but it also includes some new smarts for machine players (try "xconq -m steppes -e 6"), and a new scenario "monster", which features monsters stomping on buildings and starting fires (unfortunately the bitmaps are for X11 only, although making X10 ones would not be hard). There are quite a few changes in the code: * Tweaked config.h to account for System V and DG/UX. * Fixed save bug where transports not written out before their occupants. * Fixed machine player bug where dead units were looked at sometimes. * Fixed standing order bug where null pointers dereferenced sometimes. * Fixed area operation bug where very large arguments caused coredumps. * Fixed machine player bug where it couldn't resign if no moving units left. * Fixed display bug where captured unit was not redrawn after capture. * Fixed X bug where window movement/iconification wedged other players. * Fixed X11 bug where unit type could not be selected with mouse. * Fixed X11 interface to use the default screen rather than 0. * Fixed init bug where particular terrain types had to be on map. * Fixed init bug where some units with "all-seen" not visible until they move. * Fixed save bug where numbering of units is too high after restoring. * Changed to-move so absence of move resource immobilizes rather than kills. * Changed to-make to specify total amount, to be amortized over schedule. * Changed period word "spy" to "spy-chance". * Changed some messages to be suppressed if message string empty. * Rewrote parts of machine player code: - Production governed by needs of groups. - Resignation based on possibility to win rather than weight of territory. - Doesn't build hundreds of bases in the standard period. * Added more accurate control over flashing of current position. * Added a command 'v' to "re-flash" the current position. * Added some more unit aliveness tests, for paranoia's sake. * Added a compiletime option to deal with stupid X11 servers. * Sped up disaster handling slightly. * Increased size of unit state window slightly. * Made the monochrome test be for <= 2 colors instead of == 2 colors. * Simplified the listing of the winning alliance. To install these patches, first put your Makefile and config.h into safe places where they won't be overwritten. Then unpack the kit into your xconq sources; this will install new versions of config.h and mplay.c, as well as several periods in the library directory. The patch file, xconq.patch1 contains all the source code patches. Run patch(1) on it, merge the new Makefile config.h with your old options, and recompile everything. What you will end up with is officially version 5.1. I want to thank everyone who sent in bug reports and fixes. Not every reported problem has been resolved (see the ToDo for what remains), but I wanted to somewhat timely on these most important fixes. As always, flames, comments, and suggestions welcome - there's still another couple megabytes of space on the disk... stan shebs shebs@cs.utah.edu #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 2)." # Contents: config.h lib/future.per mplay.c # Wrapped by shebs@defun.utah.edu on Wed Jul 20 17:08:58 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f config.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"config.h\" else echo shar: Extracting \"config.h\" \(6706 characters\) sed "s/^X//" >config.h <<'END_OF_config.h' X/* Copyright (c) 1987, 1988 Stanley T. Shebs, University of Utah. */ X/* This program may be used, copied, modified, and redistributed freely */ X/* for noncommercial purposes, so long as this notice remains intact. */ X X/* RCS $Header: config.h,v 1.5 88/07/20 16:05:05 shebs Exp $ */ X X/* This file has several things that can be fiddled with; generally, */ X/* the more interesting things to tweak are closer to the front of the file. */ X/* Xconq is no longer wired to X; in fact, the specific graphics interface */ X/* is unknown until link time, and does not affect compilation. */ X X/* Just a couple places where we care about machine type - but the main */ X/* program does assume argc/argv interface, which is a problem for micros. */ X X#define UNIX X X/* These are wishful thinking at the moment. */ X/* #define ATARI */ X/* #define MAC */ X X#define BSD /* Berkeley Unix and probably Ultrix too */ X/* #define HPUX */ /* HP's mishmash of features */ X/* #define SYSV */ /* Darth Vader's favorite Unix */ X/* #define DGUX */ /* Data General is almost like BSD */ X X#ifdef BSD X#define SELECT2 /* Can use select(2) to wait on several at once. */ X#define USECRMODE /* Use crmode() for raw mode in curses. */ X#endif X X#ifdef HPUX X#define SELECT2 /* Can use select(2) to wait on several at once. */ X#define USECBREAK /* Use cbreak() for raw mode in curses. */ X#endif X X#ifdef SYSV X#define USECBREAK /* Use cbreak() for raw mode in curses. */ X#endif X X#ifdef DGUX X#define SELECT2 /* Can use select(2) to wait on several at once. */ X#define USECRMODE /* Use crmode() for raw mode in curses. */ X#endif DGUX X X#include <stdio.h> X#include <ctype.h> X X#ifdef DGUX X#include <string.h> /* To get malloc declaration */ X#endif DGUX X X/* This is where predefined maps/scenarios/periods/fonts can be found. */ X X#ifndef XCONQLIB X#define XCONQLIB "/usr/games/lib/xconq" X#endif XCONQLIB X X/* The newsfile always lives in the lib directory. */ X X#define NEWSFILE "xconq.news" X X/* This file is a list of mapfiles to exhibit in menus; it will always be */ X/* in the lib directory. There are no automatic constructors for this */ X/* file, since it should contain only well-tested files added after careful */ X/* deliberation. */ X X#define MAPFILEFILE "mapfiles" X X/* The name of the savefile. It will be put in the current directory. */ X X#define SAVEFILE "save.xconq" X X/* This file gets the parameter listing for the period in use. */ X/* It will also be created in the current directory. */ X X#define PARMSFILE "parms.xconq" X X/* This file gets the game statistics when it's all over. */ X/* It will also be created in the current directory. */ X X#define STATSFILE "stats.xconq" X X/* This file gets a printout of the side's view. */ X X#define VIEWFILE "view.xconq" X X/* This file gets a list of commands as they appear in the help window. */ X X#define CMDFILE "cmds.xconq" X X/* Default random map sizes. Adjust these to taste - 60x60 is a moderate */ X/* length game, 30x30 is short, 360x120 is L-O-N-G ! */ X X#define DEFAULTWIDTH 60 X#define DEFAULTHEIGHT 30 X X/* Absolute maximum number of sides that can play. This limit can only be */ X/* extended by changing the representation of views of players from bytes */ X/* to something larger, thereby doubling (at least) space requirements. */ X X#define MAXSIDES 7 X X/* Absolute maximum number of kinds of units. (same restriction as above) */ X X#define MAXUTYPES 30 X X/* Maximum number of types of natural resources. This number can be set */ X/* higher, in fact I think the only limitation is that there won't be */ X/* enough distinct chars, but more rtypes means larger unit objects. */ X X#define MAXRTYPES 6 X X/* Maximum number of terrain types. Must be fewer than 256, but also */ X/* limited by display capabilities. */ X X#define MAXTTYPES 20 X X/* Maximum number of random side names that can be defined. */ X X#define MAXSNAMES 200 X X/* Maximum number of random unit names that can be defined. */ X X#define MAXUNAMES 1000 X X/* The maximum number of mapfiles that can be in menus. (Not a limit on the */ X/* total number of files that can exist, however.) */ X X#define MAXMAPMENU 100 X X/* The maximum number of mapfiles that can be loaded into a game (recursive */ X/* loads are not performed and not counted). */ X X#define MAXLOADED 16 X X/* Default game length in turns. */ X X#define DEFAULTTURNS 1000 X X/* Number of messages displayed at one time. No upper limit I believe, */ X/* but too many won't fit on the screen. The actual numbers of lines */ X/* displayed can be changed by the player, subject to limitations on the */ X/* screen space available. */ X X#define MAXNOTES 10 X X/* Default color of text and icons - 0 is for white on black, 1 */ X/* is for black on white. Should be set appropriately for the most */ X/* common monochrome display (color displays always do white on black). */ X/* This is also settable by the player, so the default is just for */ X/* convenience of the majority. */ X X#define BLACKONWHITE 0 X X/* When true, displays will use more graphics and less text. This can */ X/* also be toggled by players individually. */ X X#define GRAPHICAL 0 X X/* The default fonts can be altered by users, so these are just hints. */ X/* These options do not necessarily apply to non-X versions. */ X X#define TEXTFONT "9x15" X#define ICONFONT "xconq" X X/* All names, phrases, and messages must be able to fit in statically */ X/* allocated buffers of this size. */ X X#define BUFSIZE 120 X X/* If defined, a statistics file is written at the end of the game. */ X/* The numbers therein are only for serious gamers, and the files can */ X/* be embarassing clutter in your directory! */ X X#define STATISTICS X X/* Initial limit on units and cities that can be active at one time. If */ X/* growable option is enabled, will try to grow the array to hold more. */ X X#define INITMAXUNITS 1000 X/* #define GROWABLE */ X X/* When this is enabled, machine players will be able to examine humans' */ X/* units rather more closely than is possible in reverse. In particular, */ X/* a machine will know just where the human units are, as well as their */ X/* current attributes (like hit points). */ X X/* #define CHEAT */ X X/* When the eye needs to be drawn to a particular spot on the screen, */ X/* the X interfaces will briefly flash an X. The time is set by this */ X/* value, which is measured in milliseconds that the X is visible, and */ X/* the flashing can be disabled entirely by supplying 0 here. */ X X#define DELAY 100 X X/* Some X11 servers die if too much is written between output flushes. */ X/* This can be used with any graphics system with a similar problem; */ X/* this option does not affect correctness, but may impact performance. */ X X#define STUPIDFLUSH END_OF_config.h if test 6706 -ne `wc -c <config.h`; then echo shar: \"config.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/future.per -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/future.per\" else echo shar: Extracting \"lib/future.per\" \(9272 characters\) sed "s/^X//" >lib/future.per <<'END_OF_lib/future.per' XXconq 0 -+---- Futuristic period from Jay Scott XPeriod 0 X X"around 2200 AD" period-name X X"h" "hovercar" "easily built, moves fast and captures cities" utype X"g" "groundcar" "slow but tough, captures cities" utype X"s" "saucer" "moves fast, easy to build, but short range" utype X"d" "destroyer" "heavy aircraft that defeats subs and saucers" utype X"c" "constructor" "builds bases anywhere" utype X"m" "mother ship" "carries aircraft and ground units" utype X"t" "transport sub" "quickly built, carries ground units" utype X"a" "attack sub" "attacks cities and carries rockets" utype X"R" "rocket" "missile that can kill most units and hit cities" utype X"/" "base" "airstrip + port but no production" utype X"*" "town" "produces but easily captured and may revolt" utype X"@" "city" "metropolis - hard to capture" utype X X"F" "fuel" "used for both movement and combat" rtype X X"." "sea" "sky blue" ttype X"," "shallows" "cyan" ttype X"=" "swamp" "dark gray" ttype X"+" "plains" "green" ttype X"%" "forest" "forest green" ttype X"~" "desert" "yellow" ttype X"^" "mountains" "sienna" ttype X"_" "ice" "white" ttype X":" "vacuum" "black" ttype X Xtrue [ swamp vacuum ] dark X Xt* t* nuked ; most terrain won't actually change Xdesert [ plains forest ] nuked Xmountains ice nuked X X[ 0 69 70 70 70 70 95 99 0 ] t* min-alt X[ 69 70 72 95 95 95 99 100 0 ] t* max-alt X[ 0 0 50 20 80 0 0 0 0 ] t* min-wet X[ 100 100 100 80 100 20 100 100 0 ] t* max-wet X Xice edge-terrain X X[ / * @ ] "cities" define X[ h g s d c m t a R ] "movers" define X X"hovcraft" h icon-name X"tank" g icon-name X"saucer" s icon-name X"delta" d icon-name X"builder" c icon-name X"mothrship" m icon-name X"sub" t icon-name X"sub" a icon-name X"rocket" R icon-name X"saucerpad" / icon-name X"town22" * icon-name X"city22" @ icon-name X X[ 1 5 25 ] cities territory X X[ 0 2 1 ] cities in-country X100 * density X@ first-unit Xh first-product X100 [ plains ] [ * @ ] favored X X[ 4 6 2 10 10 20 7 12 8 ] movers @ make X[ 4 6 2 10 10 20 7 12 8 ] movers * make X3 / c make Xtrue [ * @ ] maker X20 u* startup X50 [ d m ] startup X100 c startup X300 R startup X X10 fuel cities produce X[ 30 40 16 16 30 40 200 150 30 500 1000 2000 ] fuel u* storage X1 [ s d ] fuel consume X1 u* fuel consume ; not plausible, but helps machine players X X-1 u* movers out-length ; so low-capacity units don't lose fuel X X100 t* cities productivity X X[ 3 1 8 4 3 6 2 3 10 ] movers speed X X0 plains h moves X1 shallows h moves X0 [ plains desert ] g moves X0 t* [ s d c m ] moves X0 [ sea shallows ] [ t a ] moves X0 t* R moves X0 t* / moves ; allows base to be constructed on any terrain X X1 fuel movers to-move X X[ 6 4 10 2 1 ] [ h g s d c ] m capacity X4 R a capacity X[ 2 1 ] [ h g ] t capacity X10 u* / capacity X100 u* [ * @ ] capacity X X0 [ t a ] visibility Xtrue cities always-seen X X[ 1 1 1 2 2 5 2 2 1 10 20 40 ] u* hp X X[ 65 60 40 50 50 50 5 5 50 99 99 99 ] u* h hit X[ 80 60 50 40 50 50 10 10 50 99 99 99 ] u* g hit X[ 50 40 70 10 70 90 10 10 99 99 99 99 ] u* s hit X[ 10 10 65 20 70 70 50 50 20 99 99 99 ] u* d hit X[ 20 20 10 5 20 10 0 0 20 0 0 0 ] u* c hit X[ 15 10 20 5 40 40 0 0 30 0 0 0 ] u* m hit X[ 0 0 0 0 0 0 0 0 0 0 0 0 ] u* t hit X[ 40 60 10 10 20 20 60 20 0 99 99 99 ] u* a hit X[ 99 99 60 80 90 90 70 70 20 99 99 99 ] u* R hit X[ 10 10 10 20 0 0 0 10 0 0 0 0 ] u* / hit X[ 30 30 30 40 0 0 0 20 0 0 0 0 ] u* / hit X[ 50 50 50 50 0 0 0 50 0 0 0 0 ] u* / hit X X1 u* u* damage X3 cities a damage X4 u* R damage X10 cities R damage X2 u* @ damage X X[ 80 70 20 ] cities h capture X[ 90 80 30 ] cities g capture X Xtrue R self-destruct X X1 fuel u* hits-with X1 fuel u* hit-by X Xtrue movers can-disband Xtrue / can-disband X Xtrue cities neutral X X-50 neutrality X Xbegin{notes} XA science fiction xconq period. XIt's weirder and wilder than the historical periods provided with the game. XLots of things happen faster, so the game is often shorter. X XThis is in the public domain. X X ----- ----- the units ----- ----- X XHovercar. A fast-moving ground unit that easily captures towns. A Xhovercar floats on an antigravity field, so it can maneuver easily Xeven in mountainous terrain or shallow water (though not deep ocean). XHovercars are invaluable in an invasion for their ability to take Xcities quickly, but they are easily destroyed by flying saucers or Xgroundcars. X XGroundcar. A slow-moving unit which travels on treads, like today's Xtanks. It can afford to carry a large shield generator, which makes Xit tough to destroy. It can negotiate forests by pushing down the Xtrees, or burning them away with its gun, but it can't move in Xmountains. Groundcars are ideal for defending your homeland from Xinvasion. If you have enough on hand, you can often bounce back even Xafter many of your towns are captured. X XSaucer. The flying saucer is a weak but fast-moving aircraft. Saucers Xare very cheap to produce; one use is to overwhelm stronger units with Xmob attacks. They can even bombard a city to rubble, unless there's Xa Defender around. Saucers are also good for recon, within their limited Xrange. X XDefender. A heavy, delta-wing aircraft that's your only safe defense Xagainst the enemy's swarms of saucers. It uses aerodynamic lift to Xsupplement its drive, allowing it to carry relatively massive Xantisubmarine equipment. But it's an easy target for ground units. X XConstructor. An automated airborn factory that can build a base from Xon-site materials in only one turn. It can build a base anywhere, even Xon water or ice. That means, for instance, that you can build bridges Xbetween islands for ground units. The constructor is the only way Xto produce the sophisticated equipment needed for a twenty-second Xcentury base (you don't know how hard it is to refuel those saucers :-). XBut it's vulnerable to attack, especially from saucers. X XMother ship. Expensive to build, but the only way to mount a major Xinvasion. A mother ship can carry lots of saucers, lots of ground Xunits, a couple Defenders and a constructor, all at once. (The constructor Xis useful for building stepping stone bases toward the enemy.) XA mass attack is sure to bring down a mother ship, so it deserves Xsaucer patrols--but you may have to forego patrols if you're trying Xfor a surprise invasion. X XTransport sub. Carries only a few ground units, but much cheaper to Xproduce than a mother ship. This is how you get your troops to another Xisland early in the game. And since, like subs in the WWII period, Xit's invisible until bumped into, it's good for sneak raids on isolated Xoutposts. A transport submarine can't attack anything by itself. X XAttack sub. Strong against transport subs, and, if they're on the coast, Xground units and cities. It stays underwater and pokes its weapons out, Xwhich makes it relatively invulnerable to counterattack. It's faster Xthan a transport sub, and good for wide-ranging exploration. And to top Xit off, it can carry several rockets to within easy range of enemy cities. XOn the other hand, all submarines have to be careful of Defenders. X XRocket. Actually a remotely guided missile, which does a lot of damage Xto its target but vaporizes itself in the process. One rocket is Xenough to take out most units--it's not quite enough by itself Xto down a mother ship. Three rockets together are sufficient to pound Xa town back to a base. Only occasionally will a rocket miss its target. XBesides stomping cities, they're useful for eliminating enemy groundcars Xand Defenders just before an invasion. Since rockets are easily Xshot down if spied in mid-flight, it's sensible to launch them from Xattack subs near their targets. [Because of the way xconq works, Xmessages about rockets don't always make sense.] X X ----- ----- strategy ----- ----- X XThe game is designed so you need to have at least a few of every Xkind of unit to do well in a full game. (You may be able to get by Xwithout transport subs if you start out on a big continent.) If Xanybody finds they can consistently do well without some kind of unit, XI want to hear how so I can fix it! X XEvery unit has at least one nemesis which can destroy it relatively Xeasily. Your goal should be to fight every battle at an advantage, Xpitting each unit against its natural prey--saucers against hovercars, Xdefenders against saucers, hovercars against defenders. X XRockets ensure that the game doesn't drag on too long. Invasion is Xrisky, but when it works the invader wins quickly. Rockets by contrast Xare a slow but steady way to nibble at the enemy production base. X XMachine players are especially easy to defeat in this period. If you're Xlucky enough to start near one, you can blitz it with hovercars and Xsaucers and win in short order. It takes longer if you're far from Xthe robot. Gaining air superiority is usually the first step. X XThe game hasn't been played by enough people for me to tell what Xstrategies are best in different circumstances. If I've done my Xjob well, the best plan will depend in detail on the opponent and Xthe situation, and you'll have to think hard. X XI'd appreciate any comments. X X Jay Scott, August 1987. X ...bpa!swatsun!scott X ...seismo!bpa!swatsun!scott Xend{notes} X Xend X END_OF_lib/future.per if test 9272 -ne `wc -c <lib/future.per`; then echo shar: \"lib/future.per\" unpacked with wrong size! fi # end of overwriting check fi if test -f mplay.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"mplay.c\" else echo shar: Extracting \"mplay.c\" \(35452 characters\) sed "s/^X//" >mplay.c <<'END_OF_mplay.c' X/* Copyright (c) 1987, 1988 Stanley T. Shebs, University of Utah. */ X/* This program may be used, copied, modified, and redistributed freely */ X/* for noncommercial purposes, so long as this notice remains intact. */ X X/* RCS $Header: mplay.c,v 1.3 88/07/20 16:07:59 shebs Exp $ */ X X/* This file implements all of machine strategy. Not much room for fancy */ X/* tricks, just solid basic play. The code emphasizes avoidance of mistakes */ X/* instead of strategic brilliance, so machine behavior is akin to bulldozer */ X/* plodding. Nevertheless, bulldozers can be very effective when they */ X/* outnumber the human players... */ X X/* It is also very important to prevent infinite loops, so no action of the */ X/* machine player is 100% certain. */ X X#include "config.h" X#include "misc.h" X#include "dir.h" X#include "period.h" X#include "side.h" X#include "unit.h" X#include "map.h" X#include "global.h" X X/* Maximum number of unit groups that can be maintained. Need groups for */ X/* both offense and defense. */ X X#define MAXGROUPS 80 X X/* the non-group */ X X#define NOGROUP 0 X X/* Goals for both groups and individuals. */ X X#define NOGOAL 0 X#define DRIFT 1 X#define HITTARGET 2 X#define CAPTARGET 3 X#define BESIEGE 4 X#define OCCUPYHEX 5 X#define EXPLORE 6 X#define DEFEND 7 X#define LOAD 8 X#define APPROACH 9 X#define RELOAD 10 X X/* Groups organize machine player activity at the multiple-unit level. */ X Xtypedef struct a_group { X short goal; /* the intended purpose of the group */ X short priority; /* how important the group is */ X short x, y; /* a relevant location */ X short etype; /* type of a unit there (or NOTHING) */ X short area; /* radius of relevance of group activity */ X short member[MAXUTYPES]; /* number of each type in group */ X short need[MAXUTYPES]; /* what group wants but doesn't have */ X} Group; X X/* This structure is where machine sides keep all the plans and planning */ X/* related data. */ X/* Group 0 is never actually used (a sort of a dummy for various purposes). */ X Xtypedef struct a_plan { X short estimate[MAXSIDES][MAXUTYPES]; /* estimated numbers of units */ X short allies[MAXSIDES][MAXUTYPES]; /* strength of other alliances */ X short cx, cy; /* "centroid" of all our units */ X short lastreplan; /* last turn we rechecked the plans */ X short demand[MAXUTYPES]; /* worth of each utype w.r.t. strategy */ X Group group[MAXGROUPS]; /* all the groups that can be formed */ X} Plan; X X/* Encapsulate some pointer-chasing and casting messiness. */ X X#define side_plan(s) ((Plan *) (s)->plan) X X/* Malloced integer array accessors and modifers. */ X X#define aref(m,x,y) ((m)[(x)+world.width*(y)]) X X#define aset(m,x,y,v) ((m)[(x)+world.width*(y)] = (v)) X Xint evaluate_hex(), maximize_worth(); X Xchar groupbuf[BUFSIZE]; /* buffer for group debugging print */ Xchar shortbuf[BUFSIZE]; /* buffer for short unit description */ X X/* General collections of numbers used by all machine players. */ X Xint fraction[MAXTTYPES]; /* percentages of terrain types in world */ Xint bhw[MAXUTYPES][MAXUTYPES]; /* basic worth for hitting */ Xint bcw[MAXUTYPES][MAXUTYPES]; /* basic worth for capturing */ Xint maxoccupant[MAXUTYPES]; /* total capacity of a transport */ Xint *localworth; /* for evaluation of nearby hexes */ X Xint bestworth = -10000, bestx, besty; X XUnit *munit; /* Unit being decided about */ X XSide *mside; /* Side whose unit is being decided about */ X X/* List out data about a group (very compactly). */ X Xchar * Xgroup_desig(plan, g) XPlan *plan; Xint g; X{ X int e = plan->group[g].etype; X X sprintf(groupbuf, "group %d goal %d pri %d ->%d,%d %d (%c)", X g, plan->group[g].goal, plan->group[g].priority, X plan->group[g].x, plan->group[g].y, plan->group[g].area, X (e == NOTHING ? ' ' : utypes[e].uchar)); X return groupbuf; X} X X/* Short unreadable but greppable listing of unit. */ X Xchar * Xunit_desig(unit) XUnit *unit; X{ X sprintf(shortbuf, "s%d %d %c (%d,%d)", X side_number(unit->side), unit->number, utypes[unit->type].uchar, X unit->x, unit->y); X return shortbuf; X} X X/* Init used by all machine players. Precompute useful information */ X/* relating to unit types in general, and that usually gets referenced */ X/* in inner loops. */ X Xinit_mplayers() X{ X int u, u2, t, g; X Side *side, *side2; X X localworth = (int *) malloc(world.width*world.height*sizeof(int)); X for_all_terrain_types(t) { X fraction[t] = ((ttypes[t].maxalt - ttypes[t].minalt) * X (ttypes[t].maxwet - ttypes[t].minwet)) / 100; X } X for_all_unit_types(u) { X maxoccupant[u] = 0; X for_all_unit_types(u2) { X bhw[u][u2] = basic_hit_worth(u, u2); X bcw[u][u2] = basic_capture_worth(u, u2); X maxoccupant[u] += utypes[u].capacity[u2]; X } X } X /* tell us about how things rated */ X if (Debug) { X for_all_terrain_types(t) { X printf("%3d%% ", fraction[t]); X } X printf("\n\n"); X for_all_unit_types(u) { X for_all_unit_types(u2) printf("%5d", bhw[u][u2]); X printf("\n"); X } X printf("\n"); X for_all_unit_types(u) { X for_all_unit_types(u2) printf("%5d", bcw[u][u2]); X printf("\n"); X } X printf("\n"); X } X /* For all sides, because human might use "robot" option */ X for_all_sides(side) { X side->plan = (long) (Plan *) malloc(sizeof(Plan)); X side_plan(side)->cx = side_plan(side)->cy = 0; X for (g = 0; g < MAXGROUPS; ++g) { X side_plan(side)->group[g].goal = NOGROUP; X side_plan(side)->group[g].priority = 0; X } X side_plan(side)->lastreplan = -100; X } X} X X/* A crude estimate of the payoff of one unit type hitting on another type. */ X/* This is just for general estimation, since actual worth may depend on */ X/* damage already sustained, unit's goals, etc. */ X Xbasic_hit_worth(u, e) Xint u, e; X{ X int worth, anti; X X worth = utypes[u].hit[e] * min(utypes[e].hp, utypes[u].damage[e]); X if (utypes[e].hp > utypes[u].damage[e]) { X worth /= utypes[e].hp; X } X if (period.counterattack) { X anti = utypes[e].hit[u] * min(utypes[u].hp, utypes[e].damage[u]); X if (utypes[u].hp > utypes[e].damage[u]) { X anti /= utypes[u].hp; X } X } X worth -= anti; X return worth; X} X X/* A crude estimate of the payoff of one unit type trying to capture. */ X Xbasic_capture_worth(u, e) Xint u, e; X{ X int worth = 0, anti = 0; X X if (could_capture(u, e)) { X worth += utypes[u].capture[e] * utypes[u].hp; X } X return worth; X} X X/* At the beginning of each turn, can make plans and review the situation. */ X/* This should be frequent at first, but rather expensive to do always, */ X/* so only some chance of doing it on a random turn. */ X Xinit_machine_turn(side) XSide *side; X{ X if (global.time < 20 || probability(30)) make_strategy(side); X if (global.time < 20 || probability(50)) review_groups(side); X if (global.time > 20 || probability(20)) decide_resignation(side); X} X X/* Strategy is based on a study of the entire world map, looking for */ X/* duties and opportunities. */ X Xmake_strategy(side) XSide *side; X{ X int u, i, g, x, y, view, etype, x0, x1, x2, y1, y2, choice; X int pri, sumx = 0, sumy = 0, n = 0; X Plan *plan = side_plan(side); X Side *side2, *eside; X X for_all_sides(side2) { X for_all_unit_types(u) { X plan->estimate[side_number(side2)][u] = 0; X } X } X for (y = 0; y < world.height; ++y) { X for (x = 0; x < world.width; ++x) { X view = side_view(side, x, y); X if (view != EMPTY && view != UNSEEN) { X if (side == side_n(vside(view))) { X sumx += x; sumy += y; n++; X } X } X } X } X if (n > 0) { X plan->cx = sumx / n; plan->cy = sumy / n; X } X for (y = 0; y < world.height; ++y) { X for (x = 0; x < world.width; ++x) { X view = side_view(side, x, y); X if (view != EMPTY && view != UNSEEN) { X eside = side_n(vside(view)); X etype = vtype(view); X if (!allied_side(side, eside)) { X choice = attack_type(etype); X if (eside == NULL && choice == HITTARGET) { X /* uncapturable neutrals are basically dull */ X } else if (!find_group(side, choice, x, y)) { X pri = 100 - (100 * distance(x, y, plan->cx, plan->cy)) X / world.width; X form_group(side, choice, pri+1, x, y, 0, etype); X } X } else { X if (!mobile(etype) && !defended(side, x, y)) { X form_group(side, DEFEND, 1, x, y, 3, NOTHING); X } X } X if (eside) plan->estimate[side_number(eside)][etype]++; X } X } X } X if (!world.known) { X if (!find_group(side, EXPLORE, -1, -1)) { X x0 = 0 + random(world.width/3); X x1 = world.width/3 + random(world.width/3); X x2 = (2*world.width)/3 + random(world.width/3); X y1 = 0 + random(world.height/3); X y2 = (2*world.height)/3 + random(world.height/3); X form_group(side, EXPLORE, 1, x0, y1, 3, NOTHING); X form_group(side, EXPLORE, 1, x1, y1, 3, NOTHING); X form_group(side, EXPLORE, 1, x2, y1, 3, NOTHING); X form_group(side, EXPLORE, 1, x0, y2, 3, NOTHING); X form_group(side, EXPLORE, 1, x1, y2, 3, NOTHING); X form_group(side, EXPLORE, 1, x2, y2, 3, NOTHING); X } X } X /* should form a hex occupation group if hex mentioned in win/lose */ X} X X/* Decides if unit has nothing covering it. */ X Xdefended(side, x, y) XSide *side; Xint x, y; X{ X int g; X Plan *plan = side_plan(side); X X for (g = 1; g < MAXGROUPS; ++g) { X if ((plan->group[g].goal == DEFEND) && X (distance(x, y, plan->group[g].x, plan->group[g].y) <= X plan->group[g].area)) X return TRUE; X } X return FALSE; X} X X/* Review existing groups and get rid of useless ones. Start by recomputing */ X/* the members, since we don't update when units die or get transferred. */ X/* (Since at beginning of turn, all units known to be alive.) */ X Xreview_groups(side) XSide *side; X{ X int g, u, u2, e, view, ideal; X Plan *plan = side_plan(side); X Group *group; X Unit *unit; X X for_all_unit_types(u) { X plan->demand[u] = 0; X } X for (g = 1; g < MAXGROUPS; ++g) { X for_all_unit_types(u) { X plan->group[g].member[u] = 0; X plan->group[g].need[u] = 0; X } X } X for_all_units(unit) { X if (unit->side == side) plan->group[unit->group].member[unit->type]++; X } X for (g = 1; g < MAXGROUPS; ++g) { X group = &(plan->group[g]); X switch (group->goal) { X case NOGROUP: X /* a non-existent group */ X break; X case HITTARGET: X view = side_view(side, group->x, group->y); X if (view == EMPTY || view == UNSEEN || X side_n(vside(view)) == NULL || X allied_side(side, side_n(vside(view)))) { X disband_group(side, g); X } else { X for_all_unit_types(u) { X if (could_hit(u, group->etype)) { X e = group->etype; X if (utypes[u].damage[e] > 0) { X ideal = (2 * utypes[e].hp * utypes[u].hit[e]) / X utypes[u].damage[e]; X } else { X ideal = 0; X } X group->need[u] = ideal - group->member[u]; X for_all_unit_types(u2) { X if (could_carry(u2, u)) { X ideal = 1; X group->need[u2] = ideal - group->member[u2]; X } X } X } X } X } X break; X case CAPTARGET: X view = side_view(side, group->x, group->y); X if (view == EMPTY || view == UNSEEN || X allied_side(side, side_n(vside(view)))) { X disband_group(side, g); X } else { X for_all_unit_types(u) { X if (could_capture(u, group->etype)) { X ideal = 200 / utypes[u].capture[group->etype]; X group->need[u] = ideal - group->member[u]; X for_all_unit_types(u2) { X if (could_carry(u2, u)) { X ideal = 1; X group->need[u2] = ideal - group->member[u2]; X } X } X } X } X } X break; X case EXPLORE: X view = side_view(side, group->x, group->y); X if (view != UNSEEN) { X disband_group(side, g); X } else { X for_all_unit_types(u) { X if (mobile(u)) ideal = 3; X group->need[u] = ideal - group->member[u]; X for_all_unit_types(u2) { X if (could_carry(u2, u)) { X ideal = 1; X group->need[u2] = ideal - group->member[u2]; X } X } X } X } X break; X case DEFEND: X for_all_unit_types(u) { X ideal = 3; X group->need[u] = ideal - group->member[u]; X } X break; X case OCCUPYHEX: X /* occupying should only end if no longer a victory condition */ X break; X default: X case_panic("group goal", group->goal); X break; X } X } X for (g = 1; g < MAXGROUPS; ++g) { X for_all_unit_types(u) { X plan->demand[u] = group->priority * group->need[u]; X } X } X} X X/* Sometimes there is no point in going on, but be careful not to be too */ X/* pessimistic. Right now we only give up if no hope at all. */ X Xdecide_resignation(side) XSide *side; X{ X int u, u2, sn1, inrunning = FALSE, opposed, own, odds, chance = 0; X Side *side1, *side2; X Plan *plan = side_plan(side); X X for_all_sides(side1) { X sn1 = side_number(side1); X for_all_unit_types(u) { X plan->allies[sn1][u] = plan->estimate[sn1][u]; X for_all_sides(side2) { X if (side1 != side2 && allied_side(side1, side2)) { X plan->allies[sn1][u] += X plan->estimate[side_number(side2)][u]; X } X } X } X } X if (global.numconds == 0) { X for_all_unit_types(u) { X own = plan->allies[side_number(side)][u]; X for_all_unit_types(u2) { X if (could_make(u, u2) && mobile(u2)) X inrunning = TRUE; X for_all_sides(side1) { X if (enemy_side(side, side1)) { X opposed = plan->allies[side_number(side1)][u2]; X if (own > 0 && opposed > 0) { X if (could_capture(u, u2) && mobile(u)) X inrunning = TRUE; X if (could_hit(u, u2) && mobile(u)) X inrunning = TRUE; X } X } X } X } X } X /* should use chance for doubtful situations, like relative strength */ X if (!inrunning || probability(chance)) resign_game(side, NULL); X } else { X /* could get pretty complicated... */ X } X} X X/* When forming a group, first pick out an unused group, then bump a lower */ X/* priority group if there's too many. If it's of lower or equal priority, */ X/* then don't form the group at all (failure on equal priorities reduces */ X/* fickleness). */ X Xform_group(side, goal, priority, x, y, area, etype) XSide *side; Xint goal, priority, x, y, area, etype; X{ X int g, u; X Plan *plan = side_plan(side); X X for (g = 1; g < MAXGROUPS; ++g) { X if (plan->group[g].goal == NOGROUP) break; X } X if (g == MAXGROUPS) { X for (g = 1; g < MAXGROUPS; ++g) { X if (priority > plan->group[g].priority) { X disband_group(side, g); X break; X } X } X } X if (g < MAXGROUPS) { X plan->group[g].goal = goal; X plan->group[g].priority = priority; X plan->group[g].x = x; X plan->group[g].y = y; X plan->group[g].area = area; X plan->group[g].etype = etype; X for_all_unit_types(u) { X plan->group[g].member[u] = 0; X plan->group[g].need[u] = 0; X } X if (Debug) printf("%d: s%d form %s\n", global.time, X side_number(side), group_desig(plan, g)); X return g; X } else { X return 0; X } X} X X/* When group's goal accomplished, release the units for other activities. */ X/* Not very efficient to scan all units, but simpler and safer than links. */ X/* (All units are known to be alive here.) */ X Xdisband_group(side, g) XSide *side; Xint g; X{ X Unit *unit; X Plan *plan = side_plan(side); X X if (Debug) printf("%d: s%d disband %s\n", global.time, X side_number(side), group_desig(plan, g)); X plan->group[g].goal = NOGROUP; X plan->group[g].priority = 0; X for_all_units(unit) { X if (unit->side == side && unit->group == g) { X unit->group = NOGROUP; X unit->goal = NOGOAL; X if (Debug) printf("%d: %s released from group %d\n", X global.time, unit_desig(unit), g); X } X } X} X X/* Given a goal and argument, see if a group already exists like that. */ X/* (-1 values serve as unbound variables.) */ X Xfind_group(side, goal, x, y) XSide *side; Xint goal, x, y; X{ X int g; X X for (g = 1; g < MAXGROUPS; ++g) { X if ((side_plan(side)->group[g].goal == goal) && X (x == -1 || side_plan(side)->group[g].x == x) && X (y == -1 || side_plan(side)->group[g].y == y)) X return g; X } X return 0; X} X X/* Decide whether a change of product is desirable. */ X Xchange_machine_product(unit) XUnit *unit; X{ X int u = unit->type; X X if (Freeze) { X return FALSE; X } else if (utypes[u].maker) { X if (producing(unit)) { X if ((unit->built > 5) || X ((utypes[u].make[unit->product] * unit->built) > 50)) { X return TRUE; X } X } else { X return TRUE; X } X } X return FALSE; X} X X/* Machine algorithm for deciding what a unit should build. This routine */ X/* must return the type of unit decided upon. Variety of production is */ X/* important, as is favoring types which can leave the builder other than */ X/* on a transport. Capturers of valuable units are also highly preferable. */ X Xmachine_product(unit) XUnit *unit; X{ X int u = unit->type, u2, type, t, d, x, y, value, bestvalue, besttype, tmp; X int adjterr[MAXTTYPES]; X X mside = unit->side; X for_all_terrain_types(t) adjterr[t] = 0; X for_all_directions(d) { X x = wrap(unit->x + dirx[d]); y = unit->y + diry[d]; X adjterr[terrain_at(x, y)]++; X } X besttype = period.firstptype; X bestvalue = 0; X tmp = FALSE; X for_all_unit_types(u2) { X if (could_make(u, u2)) { X value = side_plan(mside)->demand[u2]; X if (mobile(u2)) { X for_all_terrain_types(t) { X if (could_move(u2, t)) { X value += adjterr[t] * fraction[t]; X tmp = TRUE; X } X } X } X if (mside->building[u2] > 0) value /= (mside->building[u2] + 1); X /* might want to adjust by number of existing units? */ X value = (value * (100 - build_time(unit, u2))) / 100; X if (tmp && value > bestvalue) { X besttype = u2; X bestvalue = value; X } X } X } X type = besttype; X /* safety check */ X if (!could_make(unit->type, type)) type = NOTHING; X if (Debug) printf("%d: %s will now build %s units\n", X global.time, unit_desig(unit), X (type == NOTHING ? "no" : utypes[type].name)); X return type; X} X X/* Decide on and make a move or set orders for a machine player. */ X Xmachine_move(unit) XUnit *unit; X{ X munit = unit; X mside = unit->side; X if (Freeze) { X order_sentry(unit, 1); X } else if (humanside(mside)) { X unit->goal = DRIFT; X if (maybe_return_home(unit)) return; X if (probability(50) && short_term(unit)) return; X search_for_best_move(unit); X } else { X if (unit->group == NOGROUP) decide_group(unit); X if (unit->goal == NOGOAL) decide_goal(unit); X if (maybe_return_home(unit)) return; X if (probability(50) && short_term(unit)) return; X search_for_best_move(unit); X } X} X X/* Picking the correct units for a group is essential to its success. */ X/* We rate the unit for its suitability for each group based on the needs */ X/* of the group and the capabilities and proximity of the unit. */ X Xdecide_group(unit) XUnit *unit; X{ X int g, u = unit->type, t, suitability, best = 0, bestgroup = 0, dist; X Plan *plan = side_plan(unit->side); X X for (g = 1; g < MAXGROUPS; ++g) { X suitability = max(0, plan->group[g].need[u]) * plan->group[g].priority; X switch (plan->group[g].goal) { X case NOGROUP: X break; X case HITTARGET: X case CAPTARGET: X dist = distance(unit->x, unit->y, X plan->group[g].x, plan->group[g].y); X suitability -= (suitability * dist) / world.width; X break; X case EXPLORE: X suitability = 1; X if (!mobile(unit->type)) suitability = -100; X break; X case DEFEND: X suitability = 1; X break; X case OCCUPYHEX: X /* assign a group capable of reaching the hex */ X break; X default: X case_panic("group goal", plan->group[g].goal); X break; X } X if (suitability > best) { X best = suitability; X bestgroup = g; X } X } X unit->group = bestgroup; X unit->goal = NOGOAL; X plan->group[bestgroup].member[unit->type]++; X if (Debug) printf("%d: %s assigned to %s\n", global.time, X unit_desig(unit), group_desig(plan, bestgroup)); X} X X/* Set up goals for units that need them. */ X/* Goals should differ according to unit's role in group... */ X Xdecide_goal(unit) XUnit *unit; X{ X int x, y, area; X Plan *plan = side_plan(unit->side); X X x = plan->group[unit->group].x; y = plan->group[unit->group].y; X switch (plan->group[unit->group].goal) { X case NOGOAL: X /* dubious */ X unit->goal = DRIFT; X unit->gx = unit->gy = 0; X break; X case HITTARGET: X if (could_hit(unit->type, plan->group[unit->group].etype)) { X unit->goal = HITTARGET; X } else if (probability(fullness(unit))) { X unit->goal = APPROACH; X } else { X unit->goal = LOAD; X } X unit->gx = x; unit->gy = y; X break; X case CAPTARGET: X if (could_capture(unit->type, plan->group[unit->group].etype)) { X unit->goal = CAPTARGET; X } else if (probability(fullness(unit))) { X unit->goal = APPROACH; X } else { X unit->goal = LOAD; X } X unit->gx = x; unit->gy = y; X break; X case EXPLORE: X unit->goal = APPROACH; X area = plan->group[unit->group].area; X unit->gx = x + random(2*area) - area; X unit->gy = y + random(2*area) - area; X break; X case DEFEND: X unit->goal = DRIFT; X area = plan->group[unit->group].area; X unit->gx = x + random(2*area) - area; X unit->gy = y + random(2*area) - area; X break; X case OCCUPYHEX: X unit->goal = APPROACH; X unit->gx = x; unit->gy = y; X break; X default: X case_panic("group goal", plan->group[unit->group].goal); X break; X } X if (Debug) printf("%d: %s in %s gets goal %d->%d,%d\n", global.time, X unit_desig(unit), group_desig(plan, unit->group), X unit->goal, unit->gx, unit->gy); X} X X/* See if the location has a unit that can take us in for refueling */ X/* (where's the check for refueling ability?) */ X Xhaven_p(x, y) Xint x, y; X{ X Unit *unit = unit_at(x, y); X X return ((unit != NULL && mside == unit->side && alive(unit) && X can_carry(unit, munit) && !might_be_captured(unit))); X} X X/* See if the location has a unit that can repair us */ X Xshop_p(x, y) Xint x, y; X{ X Unit *unit = unit_at(x, y); X X return (unit != NULL && munit->side == unit->side && alive(unit) && X can_carry(unit, munit) && could_repair(unit->type, munit->type) && X !might_be_captured(unit)); X} X X/* See if we're in a bad way, either on supply or hits, and get to safety */ X/* if possible. If not, then move on to other actions. */ X/* Can't be 100% though, there might be some problem preventing move */ X Xmaybe_return_home(unit) XUnit *unit; X{ X int u = unit->type, ux = unit->x, uy = unit->y, ox, oy, range, success; X X if (low_supplies(unit) && probability(98)) { X range = range_left(unit); X if (Debug) printf("%s should get supplies - ", unit_desig(unit)); X if ((range * range < numunits) ? X (search_area(ux, uy, range, haven_p, &ox, &oy)) : X (find_closest_unit(ux, uy, range, haven_p, &ox, &oy))) { X order_moveto(unit, ox, oy); X unit->orders.flags |= SHORTESTPATH; X unit->orders.flags &= X ~(ENEMYWAKE|NEUTRALWAKE|SUPPLYWAKE|ATTACKUNIT); X if (Debug) printf("will resupply at %d,%d\n", ox, oy); X return TRUE; X } else { X if (Debug) printf("but can't\n"); X } X } X if (cripple(unit) && probability(98)) { X /* note that crippled units cannot repair themselves */ X if (Debug) printf("%s badly damaged - ", unit_desig(unit)); X if (unit->transport && could_repair(u, unit->transport->type)) { X if (Debug) printf("%s will repair\n", unit_desig(unit->transport)); X order_sentry(unit, 1); X return TRUE; X } else { X range = range_left(unit); X if ((range * range < numunits) ? X (search_area(ux, uy, range, haven_p, &ox, &oy)) : X (find_closest_unit(ux, uy, range, shop_p, &ox, &oy))) { X order_moveto(unit, ox, oy); X unit->orders.flags &= ~SHORTESTPATH; X unit->orders.flags &= X ~(ENEMYWAKE|NEUTRALWAKE|SUPPLYWAKE|ATTACKUNIT); X if (Debug) printf("will repair at %d,%d\n", ox, oy); X return TRUE; X } else { X if (Debug) printf("but no place to repair\n"); X } X } X } X if (out_of_ammo(unit) >= 0 && probability(80)) { X if (Debug) printf("%s should reload - ", unit_desig(unit)); X range = range_left(unit); X if ((range * range < numunits) ? X (search_area(ux, uy, range, haven_p, &ox, &oy)) : X (find_closest_unit(ux, uy, range, haven_p, &ox, &oy))) { X order_moveto(unit, ox, oy); X unit->orders.flags &= ~SHORTESTPATH; X unit->orders.flags &= X ~(ENEMYWAKE|NEUTRALWAKE|SUPPLYWAKE|ATTACKUNIT); X if (Debug) printf("will go to %d,%d\n", ox, oy); X return TRUE; X } else { X if (Debug) printf("but can't\n"); X } X } X return FALSE; X} X X/* Return the distance that we can go by shortest path before running out */ X/* of important supplies. Will return at least 1, since we can *always* */ X/* move one hex to safety. This is a worst-case routine, too complicated */ X/* to worry about units getting refreshed by terrain or whatever. */ X Xrange_left(unit) XUnit *unit; X{ X int u = unit->type, r, least = 12345; X X for_all_resource_types(r) { X if (utypes[u].tomove[r] > 0) least = min(least, unit->supply[r]); X if (utypes[u].consume[r] > 0) X least = min(least, unit->supply[r] / utypes[u].consume[r]); X } X return (least == 12345 ? 1 : least); X} X X/* Do short-range planning. Only thing here is intended to be for defenders */ X/* protecting a small area (5 moves is arb, should derive from defense */ X/* group area). */ X Xshort_term(unit) XUnit *unit; X{ X int u = unit->type, ux = unit->x, uy = unit->y, range; X X switch (unit->goal) { X case DRIFT: X range = min(10, 5 * utypes[u].speed); X if (probability(90)) { X bestworth = -10000; X apply_to_area(ux, uy, range, evaluate_hex); X apply_to_area(ux, uy, range, maximize_worth); X if (bestworth >= 0) { X if (Debug) printf("drifting to %d,%d (worth %d)\n", X bestx, besty, bestworth); X order_moveto(unit, bestx, besty); X unit->orders.flags &= ~SHORTESTPATH; X return TRUE; X } X } X break; X case LOAD: X case APPROACH: X case HITTARGET: X case CAPTARGET: X break; X default: X case_panic("unit goal", munit->goal); X break; X } X return FALSE; X} X X/* Search for most favorable odds anywhere in the area, but only for */ X/* the remaining moves in this turn. Multi-turn tactics is elsewhere. */ X Xsearch_for_best_move(unit) XUnit *unit; X{ X int ux = unit->x, uy = unit->y, range = unit->movesleft, goal; X X if (!mobile(unit->type)) { X order_sentry(unit, 100); X return; X } X if (Debug) printf("%d: %s ", global.time, unit_desig(unit)); X bestworth = -10000; X apply_to_area(ux, uy, range, evaluate_hex); X apply_to_area(ux, uy, range, maximize_worth); X if (bestworth >= 0) { X if (unit->transport != NULL && mobile(unit->transport->type)) { X if (Debug) printf("sleeping on transport\n"); X order_sentry(unit, 5); X } else if ((ux == bestx && uy == besty) || !can_move(unit)) { X if (Debug) printf("staying put\n"); X order_sentry(unit, 1); X } else if (probability(90)) { X if (Debug) printf("moving to %d,%d (worth %d)\n", X bestx, besty, bestworth); X order_moveto(unit, bestx, besty); X unit->orders.flags &= ~SHORTESTPATH; X } else { X if (Debug) printf("hanging around\n"); X order_sentry(unit, random(5)); X } X } else { X goal = unit->goal; X /* jam alternative sometimes... */ X if (probability(95)) goal = DRIFT; X switch (goal) { X case DRIFT: X if (can_produce(unit) && unit->transport == NULL && X probability(90)) { X if (Debug) printf("going to build something\n"); X set_product(unit, machine_product(unit)); X set_schedule(unit); X order_sentry(unit, unit->schedule+1); X } else if (probability(90)) { X if (Debug) printf("going in random direction\n"); X order_movedir(unit, random_dir(), random(3)+1); X } else { X if (Debug) printf("hanging around\n"); X order_sentry(unit, random(4)+1); X } X break; X case LOAD: X if (unit->occupant != NULL) { X if (Debug) printf("starting off to goal\n"); X unit->goal = APPROACH; X order_moveto(unit, unit->gx, unit->gy); X } else { X if (bestworth >= 0) { X if (Debug) printf("loading at %d,%d (worth %d)\n", X bestworth, bestx, besty); X order_moveto(unit, bestx, besty); X unit->orders.flags &= ~SHORTESTPATH; X } else { X if (Debug) printf("moving slowly about\n"); X order_movedir(unit, random_dir(), 1); X } X } X break; X case APPROACH: X case HITTARGET: X case CAPTARGET: X if (unit->transport != NULL) { X if (unit->transport->group == unit->group) { X if (Debug) printf("riding in transport\n"); X order_sentry(unit, 4); X } else if (!can_move(unit)) { X if (Debug) printf("waiting to get off\n"); X order_sentry(unit, 2); X } else { X if (Debug) printf("leaving for %d,%d\n", X unit->gx, unit->gy); X order_moveto(unit, unit->gx, unit->gy); X } X } else { X if (Debug) printf("approaching %d,%d\n", unit->gx, unit->gy); X order_moveto(unit, unit->gx, unit->gy); X } X break; X default: X case_panic("unit goal", munit->goal); X break; X } X } X} X X/* Given a position nearby the unit, evaluate it with respect to goals, */ X/* general characteristics, and so forth. -10000 is very bad, 0 is OK, */ X/* 10000 or so is best possible. */ X X/* Should downrate hexes within reach of enemy retaliation. */ X/* Should downrate hexes requiring supply consumption to enter/occupy. */ X Xevaluate_hex(x, y) Xint x, y; X{ X bool adjhex, ownhex; X int view, etype, dist, worth = 0; X int terr = terrain_at(x, y); X Side *es; X Unit *eunit; X X view = side_view(mside, x, y); X dist = distance(munit->x, munit->y, x, y); X adjhex = (dist == 1); X ownhex = (dist == 0); X X if (y <= 0 || y >= world.height-1) { X worth = -10000; X } else { X switch (munit->goal) { X case DRIFT: X if (ownhex) { X worth = -1; X } else if (view == UNSEEN) { X worth = random(100) / dist; X } else if (view == EMPTY) { X worth = -100; X if (impassable(munit, x, y)) worth -= 900; X } else { X es = side_n(vside(view)); X etype = vtype(view); X if (es == NULL) { X if (could_capture(munit->type, etype)) { X worth = 20000 / dist; X } else { X worth = -10000; X } X } else if (!allied_side(mside, es)) { X worth = 200 + attack_worth(munit, etype); X worth += threat(mside, etype, x, y); X worth /= dist; X } else { X worth = 0; X } X } X break; X case LOAD: X if (ownhex || view == UNSEEN || view == EMPTY) { X worth = -1; X } else { X es = side_n(vside(view)); X if (mside == es) { X if ((eunit = unit_at(x, y)) != NULL) { X if (eunit->group == munit->group) { X worth = 4000; X worth /= dist; X } X } X } else { X worth = -100; X } X } X break; X case APPROACH: X case HITTARGET: X case CAPTARGET: X if (ownhex) { X worth = -100; X } else if (view == UNSEEN) { X worth = random(100) / dist; X } else if (view == EMPTY) { X if (impassable(munit, x, y)) worth -= 900; X } else if (x == munit->gx && y == munit->gy) { X worth = 10000; X } else { X es = side_n(vside(view)); X etype = vtype(view); X if (es == NULL) { X if (could_capture(munit->type, etype)) { X worth = 20000 / dist; X } else { X worth = -10000; X } X } else if (!allied_side(mside, es)) { X worth = 200 + attack_worth(munit, etype); X worth += threat(mside, etype, x, y); X worth /= dist; X } else { X es = side_n(vside(view)); X if (mside == es) { X if ((eunit = unit_at(x, y)) != NULL) { X if (eunit->group == munit->group && X eunit->goal == LOAD && X could_carry(eunit->type, munit->type)) { X worth = 4000; X worth /= dist; X } X } X } else { X worth = -100; X } X } X } X break; X default: X case_panic("unit goal", munit->goal); X break; X } X } X if ((munit->gx > 0 || munit->gy > 0) && X (distance(x, y, munit->gx, munit->gy) < X distance(munit->x, munit->y, munit->gx, munit->gy))) { X worth += 1000; X } X worth -= 100; X worth += utypes[munit->type].productivity[terr]; X aset(localworth, x, y, worth); X} X X/* Scan evaluated area looking for best overall hex. */ X Xmaximize_worth(x, y) Xint x, y; X{ X int worth; X X worth = aref(localworth, x, y); X if (worth >= 0) { X if (worth > bestworth) { X bestworth = worth; bestx = x; besty = y; X } else if (worth == bestworth && flip_coin()) { X bestworth = worth; bestx = x; besty = y; X } X } X} X X/* This is a heuristic estimation of the value of one unit type hitting */ X/* on another. Should take cost of production into account as well as the */ X/* chance and significance of any effect. */ X Xattack_worth(unit, etype) XUnit *unit; Xint etype; X{ X int utype = unit->type, worth; X X worth = bhw[utype][etype]; X if (utypes[utype].damage[etype] >= utypes[etype].hp) X worth *= 2; X if (utypes[etype].damage[utype] >= unit->hp) X worth /= (could_capture(utype, etype) ? 1 : 4); X if (could_capture(utype, etype)) worth *= 4; X return worth; X} X X X/* Support functions. */ X X/* True if unit is in immediate danger of being captured. */ X/* Needs check on capturer transport being seen. */ X Xmight_be_captured(unit) XUnit *unit; X{ X int d, x, y; X Unit *unit2; X X for_all_directions(d) { X x = wrap(unit->x + dirx[d]); y = unit->y + diry[d]; X if (((unit2 = unit_at(x, y)) != NULL) && X (enemy_side(unit->side, unit2->side)) && X (could_capture(unit2->type, unit->type))) return TRUE; X } X return FALSE; X} X X/* Return true if the given unit type at given position is threatened. */ X Xthreat(side, u, x0, y0) XSide *side; Xint u, x0, y0; X{ X int d, x, y, view, thr = 0; X Side *side2; X X for_all_directions(d) { X x = wrap(x0 + dirx[d]); y = y0 + diry[d]; X view = side_view(side, x, y); X if (view != UNSEEN && view != EMPTY) { X side2 = side_n(vside(view)); X if (allied_side(side, side2)) { X if (could_capture(u, vtype(view))) thr += 1000; X if (bhw[u][vtype(view)] > 0) thr += 100; X } X } X } X return thr; X} X X/* Test if unit can move out into adjacent hexes. */ X Xcan_move(unit) XUnit *unit; X{ X int d, x, y; X X for_all_directions(d) { X x = wrap(unit->x + dirx[d]); y = limit(unit->y + diry[d]); X if (could_move(unit->type, terrain_at(x, y))) return TRUE; X } X return FALSE; X} X X/* Returns the type of missing supplies. */ X Xout_of_ammo(unit) XUnit *unit; X{ X int u = unit->type, r; X X for_all_resource_types(r) { X if (utypes[u].hitswith[r] > 0 && unit->supply[r] <= 0) X return r; X } X return (-1); X} X X/* Returns the type of attack to plan for. (Should balance relative */ X/* effectiveness of each type of attack.) */ X Xattack_type(e) Xint e; X{ X int u; X X if (utypes[e].surrender > 0 || utypes[e].siege > 0) return BESIEGE; X for_all_unit_types(u) if (could_capture(u, e)) return CAPTARGET; X return HITTARGET; X} X X/* True if the given unit is a sort that can build other units. */ X Xcan_produce(unit) XUnit *unit; X{ X int p; X X for_all_unit_types(p) { X if (could_make(unit->type, p)) return TRUE; X } X return FALSE; X} X X/* Return percentage of capacity. */ X Xfullness(unit) XUnit *unit; X{ X int u = unit->type, o, cap = 0, num = 0, vol = 0; X Unit *occ; X X for_all_unit_types(o) cap += utypes[u].capacity[o]; X for_all_occupants(unit, occ) { X num++; X vol += utypes[occ->type].volume; X } X if (utypes[u].holdvolume > 0) { X return ((100 * vol) / utypes[u].holdvolume); X } else if (cap > 0) { X return ((100 * num) / cap); X } else { X fprintf(stderr, "Fullness ???\n"); X } X} X Xfind_closest_unit(x0, y0, maxdist, pred, rxp, ryp) Xint x0, y0, maxdist, (*pred)(), *rxp, *ryp; X{ X Unit *unit; X X for_all_units(unit) { X if (alive(unit) && distance(x0, y0, unit->x, unit->y) <= maxdist) { X if ((*pred)(unit->x, unit->y)) { X *rxp = unit->x; *ryp = unit->y; X return TRUE; X } X } X } X return FALSE; X} END_OF_mplay.c if test 35452 -ne `wc -c <mplay.c`; then echo shar: \"mplay.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 1 \(of 2\). cp /dev/null ark1isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0
shebs@utah-cs.UUCP (Stanley Shebs) (07/21/88)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 2 (of 2)." # Contents: lib/beirut.per lib/breath.b11 lib/fire.b11 lib/fireman.b11 # lib/flattop.per lib/monster.b11 lib/monster.b11 lib/monster.per # lib/monster.scn lib/starwars.per xconq.patch1 # Wrapped by shebs@defun.utah.edu on Wed Jul 20 17:09:00 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f lib/beirut.per -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/beirut.per\" else echo shar: Extracting \"lib/beirut.per\" \(2050 characters\) sed "s/^X//" >lib/beirut.per <<'END_OF_lib/beirut.per' XXconq 0 -+---- The heroic fighters of Beirut XPeriod 0 X X; buildings should be able to be neutral after revolt X; death squads should be as fast as leaders and shouldn't retreat X; and should be able to take over buildings. X; no capturing if leader if they are win/lose condition. X X"Beirut 1982" period-name X X0 scale ; well under 1 km per hex... X X"m" "militia" "hide and fight from building to building" utype X"d" "death squad" "hit people and not buildings" utype X"l" "leader" "an individual" utype X"c" "car bomb" "destroys buildings" utype X"t" "tank" "also destroys buildings and other things" utype X"B" "building" "good for hiding out" utype X X; hostages rtype? X X"." "sea" "sky blue" ttype X"," "beach" "yellow" ttype X"+" "street" "light gray" ttype X"^" "junkheap" "sienna" ttype X"=" "fields" "green" ttype X"%" "trees" "forest green" ttype X Xtrue junkheap dark X X[ 0 20 25 35 80 90 ] t* min-alt X[ 20 25 35 80 90 100 ] t* max-alt X X"soldiers" m icon-name X"45" d icon-name X"man" l icon-name X"auto" c icon-name X"tank" t icon-name X"city20" B icon-name X X[ m d l c t ] "movers" define X[ c t ] "vehicles" define X[ sea ] "water" define X[ beach street junkheap fields trees ] "land" define X X1 B territory X10 l territory X X[ 5 1 1 2 2 1 ] u* in-country X3000 B density X100 street movers favored X100 junkheap B favored X X; 100 t* u* favored X X5 country-size X5 country-min-distance X;10 country-max-distance X X100 B revolt X X[ 1 1 2 3 3 ] movers speed X X0 land [ m d l ] moves X0 [ beach street ] vehicles moves X X2 [ m d l ] B capacity X X0 d visibility Xtrue B already-seen X Xtrue all-seen X X[ 1 1 1 1 2 10 ] u* hp X X[ 50 50 50 50 50 50 ] u* m hit X[ 5 50 70 20 20 0 ] u* d hit X[ 0 20 50 0 20 0 ] u* l hit X[ 90 90 90 90 90 90 ] u* c hit X[ 90 90 90 90 90 90 ] u* t hit X[ 10 10 10 10 0 0 ] u* B hit X X1 u* u* damage X1 B t damage X[ 2 10 ] [ t B ] c damage X X-100 neutrality X Xtrue c self-destruct X X100 B m capture X100 c m capture X; 50 l m capture X50 t m capture X X[ 20 80 90 0 0 ] movers retreat X X;30 m control X X50 [ m d ] B protect X90 B m protect X Xtrue B neutral X Xend END_OF_lib/beirut.per if test 2050 -ne `wc -c <lib/beirut.per`; then echo shar: \"lib/beirut.per\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/breath.b11 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/breath.b11\" else echo shar: Extracting \"lib/breath.b11\" \(281 characters\) sed "s/^X//" >lib/breath.b11 <<'END_OF_lib/breath.b11' X#define breath_width 16 X#define breath_height 16 Xstatic char breath_bits[] = { X 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x92, 0x00, 0x54, 0x00, 0x94, 0x00, X 0x64, 0x01, 0x48, 0x03, 0x5a, 0x0d, 0xd4, 0xf2, 0xa8, 0x7a, 0xf0, 0x0f, X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; END_OF_lib/breath.b11 if test 281 -ne `wc -c <lib/breath.b11`; then echo shar: \"lib/breath.b11\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/fire.b11 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/fire.b11\" else echo shar: Extracting \"lib/fire.b11\" \(275 characters\) sed "s/^X//" >lib/fire.b11 <<'END_OF_lib/fire.b11' X#define fire_width 16 X#define fire_height 16 Xstatic char fire_bits[] = { X 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x01, 0x60, 0x01, X 0x70, 0x03, 0x78, 0x03, 0x38, 0x03, 0xd8, 0x01, 0xd8, 0x02, 0x58, 0x02, X 0x70, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}; END_OF_lib/fire.b11 if test 275 -ne `wc -c <lib/fire.b11`; then echo shar: \"lib/fire.b11\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/fireman.b11 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/fireman.b11\" else echo shar: Extracting \"lib/fireman.b11\" \(284 characters\) sed "s/^X//" >lib/fireman.b11 <<'END_OF_lib/fireman.b11' X#define fireman_width 16 X#define fireman_height 16 Xstatic char fireman_bits[] = { X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, X 0x00, 0x00, 0xee, 0x3f, 0xfe, 0x3f, 0xfe, 0x3f, 0xfe, 0x7f, 0x0c, 0x1c, X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; END_OF_lib/fireman.b11 if test 284 -ne `wc -c <lib/fireman.b11`; then echo shar: \"lib/fireman.b11\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/flattop.per -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/flattop.per\" else echo shar: Extracting \"lib/flattop.per\" \(2947 characters\) sed "s/^X//" >lib/flattop.per <<'END_OF_lib/flattop.per' XXconq 0 -+---- Carrier operations in the Pacific XPeriod 0 X X"WW II, in the Pacific, aboard a carrier" period-name X X"f" "fighter" "" utype X"d" "dive bomber" "" utype X"t" "torpedo bomber" "" utype X"p" "PBY" "" utype X"D" "destroyer" "" utype X"S" "submarine" "" utype X"E" "escort carrier" "" utype X"r" "light cruiser" "" utype X"R" "heavy cruiser" "" utype X"C" "carrier" "" utype X"B" "battleship" "" utype X"/" "base" "" utype X X"o" "fuel" "how to get around" rtype X"a" "ammo" "small stuff" rtype X"A" "shell" "8 to 16 inch" rtype X"b" "bomb" "iron bombs" rtype X"!" "torps" "death to ships" rtype X X"." "sea" "sky blue" ttype X"," "atoll" "cyan" ttype X"+" "island" "forest green" ttype X X[ 0 96 98 ] t* min-alt X[ 96 98 100 ] t* max-alt X X95 alt-roughness X Xsea default-terrain Xsea edge-terrain X X"1e" f icon-name X"1e" d icon-name X"torpbombr" t icon-name X"pby" p icon-name X"dd" D icon-name X"ca" r icon-name X"sub" S icon-name X"cv" E icon-name X"cv" C icon-name X"ca" R icon-name X"bb" B icon-name X"airbase" / icon-name X X[ f d t p ] "air" define X[ r R B ] "heavy" define X[ E C ] "carriers" define X[ D S E r R C B ] "ships" define X[ o a A b ! ] "stuff" define X X100 sea ships favored X100 [ atoll island ] / favored X X4 country-size X30 country-min-distance X32 country-max-distance X X[ 8 8 8 4 6 2 4 2 2 2 2 1 ] u* in-country X Xtrue / always-seen X X500 [ fuel ammo ] ships storage X20 fuel air storage X40 fuel p storage X2 a air storage X0 a p storage X2 b d storage X2 ! t storage X10 ! [ D S ] storage X50 [ b ! ] C storage X25 [ b ! ] E storage X50 A heavy storage X1000 r* / storage X X3 fuel air consume X X9 air speed X6 p speed X3 ships speed ; gross simplification X X0 t* air moves X0 t* p moves X0 sea ships moves X2 atoll ships moves X X1 fuel u* to-move X X4 air E capacity X8 air C capacity X100 u* / capacity X100 u* u* enter-time X1 air volume X4 E hold-volume X8 C hold-volume X100 / hold-volume X X10 S visibility X X[ 5 5 5 5 10 10 20 ] ships hp X100 / hp X X50 u* u* hit X80 air f hit X60 f f hit X0 u* p hit X20 carriers f hit X20 air S hit X70 S D hit X100 / u* hit X0 / [ S E C ] hit X10 u* carriers hit X X1 u* u* damage X3 u* heavy damage X4 ships [ t D S ] damage X10 [ C B ] [ t D S ] damage X10 / B damage X X1 a air hits-with X1 a [ E C ] hits-with X1 b d hits-with X1 ! [ t D S ] hits-with X1 A heavy hits-with X X1 [ b ! ] ships hit-by X1 a air hit-by X1 A u* hit-by X X50 air carriers protect X X"sinks" ships destroy-message X"shoots down" air destroy-message X X; 0 air control X Xbegin{notes} XThis is a somewhat expanded version of the navy in the standard period. XEach side commands a large fleet, and the sole objective is to wipe out Xthe enemy's fleet. There are different kinds of planes and ships, but Xnothing else. X XSpeeds of ships are uniform, so that formations work better (don't want Xthe carriers outstripping their escorts). X XYou do *not* get complete control over the aircraft! Those undisciplined Xpilots just do what they feel like doing, and only take about half their Xorders. Xend{notes} X Xend END_OF_lib/flattop.per if test 2947 -ne `wc -c <lib/flattop.per`; then echo shar: \"lib/flattop.per\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/monster.b11 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/monster.b11\" else echo shar: Extracting \"lib/monster.b11\" \(284 characters\) sed "s/^X//" >lib/monster.b11 <<'END_OF_lib/monster.b11' X#define monster_width 16 X#define monster_height 16 Xstatic char monster_bits[] = { X 0x00, 0x00, 0x2e, 0x00, 0x1e, 0x00, 0x58, 0x00, 0x38, 0x00, 0x7e, 0x01, X 0xf0, 0x00, 0xf8, 0x02, 0xf8, 0x01, 0xf0, 0x0b, 0xe0, 0x07, 0x60, 0x0e, X 0x78, 0x38, 0x14, 0xe0, 0x00, 0x00, 0x00, 0x00}; END_OF_lib/monster.b11 if test 284 -ne `wc -c <lib/monster.b11`; then echo shar: \"lib/monster.b11\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/monster.b11 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/monster.b11\" else echo shar: Extracting \"lib/monster.b11\" \(284 characters\) sed "s/^X//" >lib/monster.b11 <<'END_OF_lib/monster.b11' X#define monster_width 16 X#define monster_height 16 Xstatic char monster_bits[] = { X 0x00, 0x00, 0x2e, 0x00, 0x1e, 0x00, 0x58, 0x00, 0x38, 0x00, 0x7e, 0x01, X 0xf0, 0x00, 0xf8, 0x02, 0xf8, 0x01, 0xf0, 0x0b, 0xe0, 0x07, 0x60, 0x0e, X 0x78, 0x38, 0x14, 0xe0, 0x00, 0x00, 0x00, 0x00}; END_OF_lib/monster.b11 if test 284 -ne `wc -c <lib/monster.b11`; then echo shar: \"lib/monster.b11\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/monster.per -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/monster.per\" else echo shar: Extracting \"lib/monster.per\" \(3410 characters\) sed "s/^X//" >lib/monster.per <<'END_OF_lib/monster.per' XXconq 0 -+---- Save Tokyo from the fire-breathing monsters! XPeriod 0 X X"Tokyo 1962" period-name X X0 scale ; well under 1 km per hex... X X"m" "monster" "breathes fire and stomps on buildings" utype X"b" "fire breath" "burns things up" utype X"f" "fire" "burns things up" utype X"p" "panic-stricken mob" "helpless civilians, mostly just get in the way" utype X"F" "fire department" "puts out fires" utype X"g" "national guard" "does battle with the monster" utype X"B" "building" "good for hiding out" utype X X"e" "energy" "required to make fires move" rtype X X; hostages rtype? X X"." "sea" "sky blue" ttype X"," "beach" "yellow" ttype X"+" "street" "light gray" ttype X"^" "junkheap" "sienna" ttype X"=" "fields" "green" ttype X"%" "trees" "forest green" ttype X Xtrue junkheap dark X X[ 0 20 25 35 80 90 ] t* min-alt X[ 20 25 35 80 90 100 ] t* max-alt X X"monster" m icon-name X"breath" b icon-name X"fire" f icon-name X"man" p icon-name X"fireman" F icon-name X"soldiers" g icon-name X"city20" B icon-name X X X[ m b f p F g ] "movers" define X[ sea ] "water" define X[ beach street junkheap fields trees ] "land" define X X[ b f ] "fires" define X X1 B territory X100 m territory X X[ 1 0 0 10 3 3 10 ] u* in-country X100 street movers favored X100 junkheap B favored X X; 100 t* u* favored X X5 country-size X5 country-min-distance X;10 country-max-distance X X; 100 B revolt X X3000 t* fires attrition X5000 street fires attrition X2000 junkheap fires attrition X X1 fires attrition-damage X"" fires attrition-message X X1 e m produce X100 t* m productivity X1 e m storage X1 e b storage X1 f b make X100 t* f productivity X5 b m make Xtrue b maker Xtrue m maker X X[ 1 1 1 1 2 2 ] movers speed X X0 land movers moves X-1 t* F moves X0 street F moves X1 e b to-move X X1 [ p F g ] B capacity X2 f b capacity X2 b m capacity X Xtrue B already-seen Xtrue all-seen X X[ 100 5 5 1 2 5 6 ] u* hp X X[ 50 50 50 50 100 80 100 ] u* m hit X[ 0 0 0 40 40 40 90 ] u* b hit X[ 0 0 0 40 0 40 90 ] u* f hit X[ 0 10 10 0 0 0 0 ] u* p hit X[ 0 90 90 0 0 0 0 ] u* F hit X[ 80 40 40 0 0 0 0 ] u* g hit X[ 10 20 20 0 0 0 0 ] u* B hit X X1 u* u* damage X4 m g damage X5 f F damage X2 b F damage X3 B m damage X6 B b damage X3 B f damage X X X"extinguishes" fires destroy-message X"massacres" p destroy-message X"wipes out" g destroy-message X"wipes out" F destroy-message X"flattens" B destroy-message X X[ 05 0 90 50 20 ] movers retreat X X0 p control X0 f control X X50 [ p F g ] B protect X X; this doesn't work X; false f free-move X X2 [ m B ] named ; special hack to display names only X Xclear-unit-names X"Godzilla" uname X"Rodan" uname X"Mothra" uname X"Megalon" uname X"Gajira" uname X"Aspidra" uname X"Reptilicus" uname X"Gamera" uname X Xbegin{notes} X XTypically, one would set up a scenario with one or more monsters on Xone side, and mobs, fire departments, and national guards on the Xother. The machine players work best if buildings are neutral. Note Xthat the monster can easily defeat national guards one after another, Xand that the most successful strategy for the "human" side is to Xattack the monster with several units at once. The monster can use Xfires as a barricade to keep the national guards from getting close Xenough to attack. Destroying buildings is fun but not very useful. X XNote that the bitmaps are defined in X11 format and won't work in X10. X XSandra Loosemore (sandra@cs.utah.edu) is the person to blame for this Xpiece of silliness (well, Stan aided and abetted). X Xend{notes} Xend END_OF_lib/monster.per if test 3410 -ne `wc -c <lib/monster.per`; then echo shar: \"lib/monster.per\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/monster.scn -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/monster.scn\" else echo shar: Extracting \"lib/monster.scn\" \(2218 characters\) sed "s/^X//" >lib/monster.scn <<'END_OF_lib/monster.scn' XXconq 1 --++++ Save Tokyo from the fire-breathing monsters! Xmonster.per XMap 40 20 0 1 0 X40. X40. X++5.,6+21.5+ X^^+4.,+3^+^+20.+^^+1^ X^^+,3.,++^^+^^5+15.+3^1+ X4+4,+^+^+^^+3^++14.5+ X=%=6+^^5+3^+%+13.+^+=1% X%==+^+^^+^^+^+==4+=%+12.+^^+1= X=3+^^+^^3+^^+=+^^+=%=+11.+^^2+ X++^+^^+^^++^+^^++^^+==%=+11.3+1^ X^+^^7+^^3+^+^+=%%=+12.+2^ X^+3^+^^+==+^^+3^++%3=+13.+1^ X6+^^+=%=3+3^+%%4+14.1+ X+3^5+%=4%7+18. X.++^3+^^+%=3%+5,19. X3.++^^+^++4=+24. X4.+^^+^+^5+24. X5.+^3+^^+27. X6.++,,3+27. X40. XGlobals 0 200 1 0 2 0 X0 1 0 200 0 X0 1000 1000 0 0 0 0 X0 1 0 200 1 X0 0 0 1000 1000 0 1000 XSides 2 1 0 XGiant XJapanese XUnits 126 1 0 Xm Godzilla 14,12 0 XB * 1,6 -1 XB * 0,8 -1 Xp * 1,7 1 XB * 2,6 -1 XB * 3,5 -1 Xp * 4,4 1 XB * 5,3 -1 XB City*Hall 6,2 -1 XB * 0,9 -1 XB * 3,6 -1 XB Courthouse 5,4 -1 XB * 6,3 -1 XF * 1,9 1 XB * 2,8 -1 XB * 6,4 -1 Xg * 8,2 1 XB * 2,9 -1 XB Capitalists*Trust 3,8 -1 XF * 5,6 1 XB * 8,3 -1 Xg * 9,2 1 Xg * 10,1 1 Xp * 0,12 1 XB * 2,10 -1 XB * 3,9 -1 XB * 4,8 -1 XB * 7,5 -1 XB * 8,4 -1 XB * 10,2 -1 Xg * 11,1 1 XB * 6,7 -1 XB * 8,5 -1 XB Sears 10,3 -1 XB * 11,2 -1 Xg * 12,1 1 Xp * 1,13 1 XB * 4,10 -1 XB * 6,8 -1 XB * 7,7 -1 XB * 0,15 -1 XB * 4,11 -1 XB Mormon*Temple 5,10 -1 XB * 7,8 -1 Xp * 9,6 1 XB * 0,16 -1 XB Hi-Rise*Apts 1,15 -1 XF * 2,14 1 XB * 4,12 -1 XB * 5,11 -1 Xp * 6,10 1 XF * 13,3 1 XB * 1,16 -1 XB * 6,12 -1 XB Last*National*Bank 7,11 -1 XB * 8,10 -1 Xp * 9,9 1 Xp * 6,13 1 XB * 7,12 -1 XB * 8,11 -1 XB * 11,9 -1 XB * 12,8 -1 Xp * 13,7 1 XB * 9,12 -1 Xp * 10,11 1 XB Smiths 11,10 -1 XB * 12,9 -1 XB * 13,8 -1 Xp * 8,14 1 XB * 9,13 -1 XB * 10,12 -1 XB * 15,7 -1 XB * 9,14 -1 XB * 10,13 -1 XB * 13,10 -1 Xp * 14,9 1 XB * 15,8 -1 XB * 16,7 -1 XB K-Mart 12,12 -1 XB * 13,11 -1 XB * 14,10 -1 XB * 16,8 -1 XB * 17,7 -1 XB * 9,16 -1 XB * 10,15 -1 XB * 11,14 -1 XB * 16,9 -1 XB * 17,8 -1 XB * 10,16 -1 XB * 11,15 -1 Xp * 18,8 1 Xp * 10,17 1 XB * 11,16 -1 XB * 13,14 -1 XB Fawlty*Towers 17,10 -1 XB Hilton*Tokyo 18,9 -1 XB * 13,15 -1 XB * 14,14 -1 XB * 17,11 -1 XB * 18,10 -1 XB * 13,16 -1 XB * 14,15 -1 XB * 16,13 -1 XB * 18,11 -1 XB * 16,14 -1 XB * 17,13 -1 XB * 17,14 -1 XB * 18,13 -1 Xp * 19,12 1 XB * 18,14 -1 XB * 36,11 -1 XB * 38,9 -1 XB * 39,8 -1 XB * 36,12 -1 XB * 37,11 -1 XB * 39,9 -1 XB * 36,13 -1 XB * 37,12 -1 XB * 39,10 -1 XB * 36,15 -1 XF * 37,14 1 XB * 36,16 -1 XB * 37,15 -1 XB * 37,16 -1 XB * 38,15 -1 XB * 39,16 -1 END_OF_lib/monster.scn if test 2218 -ne `wc -c <lib/monster.scn`; then echo shar: \"lib/monster.scn\" unpacked with wrong size! fi # end of overwriting check fi if test -f lib/starwars.per -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"lib/starwars.per\" else echo shar: Extracting \"lib/starwars.per\" \(3673 characters\) sed "s/^X//" >lib/starwars.per <<'END_OF_lib/starwars.per' XXconq 0 -+---- Star Wars, sort of XPeriod 0 X X"long long ago in a galaxy far far away" period-name X X"s" "stormtrooper" "" utype X"w" "walker" "" utype X"h" "hovercraft" "" utype X"x" "x-wing fighter" "" utype X"t" "tie fighter" "" utype X"y" "y-wing fighter-bomber" "" utype X"C" "cruiser" "" utype X"D" "death star" "" utype X"d" "death beam" "" utype X"*" "town" "" utype X"@" "city" "" utype X X"trooper" s icon-name X"walker" w icon-name X"hovcraft" h icon-name X"xwing" x icon-name X"tiefightr" t icon-name X"ywing" y icon-name X"impcruisr" C icon-name X"deathstar" D icon-name X"deathray" d icon-name X"town22" * icon-name X"city30" @ icon-name X X"F" "fuel" "basic motive power" rtype X X"." "sea" "sky blue" ttype X"+" "plains" "green" ttype X"%" "forest" "forest green" ttype X"~" "desert" "yellow" ttype X"^" "mountains" "sienna" ttype X"_" "ice" "white" ttype X":" "vacuum" "black" ttype X Xtrue vacuum dark X Xt* t* nuked ; most terrain won't actually change Xdesert [ plains forest ] nuked Xmountains ice nuked X X[ 0 70 70 70 95 99 0 ] t* min-alt X[ 70 95 95 95 99 100 0 ] t* max-alt X[ 0 20 80 0 0 0 0 ] t* min-wet X[ 100 80 100 20 100 100 0 ] t* max-wet X Xvacuum edge-terrain X X[ * @ ] "cities" define X[ D * @ ] "makers" define X[ s w h x t y C D d @ ] "movers" define X[ sea ] "water" define X[ plains forest desert mountains ] "land" define X X1 cities named X[ 10 5 25 ] makers territory X X1 @ in-country X3 * in-country X100 * density X@ first-unit Xs first-product X20 land * favored X40 plains * favored X100 plains @ favored X8 country-min-distance X48 country-max-distance X X; no disasters yet X X[ 4 6 6 5 5 8 15 40 0 0 0 ] u* @ make X[ 4 6 6 5 5 8 15 40 0 0 0 ] u* * make X3 d D make X1 makers maker X20 u* startup X; no special resources to make X1 u* makers repair X10 [ C D ] [ C D ] repair X X20 fuel cities produce X[ 30 30 30 20 22 35 200 1000 2 100 100 ] fuel u* storage X100 t* cities productivity X X[ 3 4 6 9 8 7 6 5 2 1 ] movers speed X X0 land s moves X0 land w moves X0 ice w moves X0 t* D moves X0 t* [ h C ] moves X0 t* [ x t y ] moves X0 t* d moves X0 t* @ moves X-1 vacuum @ moves X X1 fuel movers to-move X0 fuel s to-move X X10 u* * capacity X20 u* @ capacity X[ 2 1 6 4 4 2 ] [ s w h x t y ] C capacity X[ 5 3 8 8 4 4 1 3 ] [ s w h x t y C d ] D capacity X X1 cities always-seen X X[ 1 2 1 1 1 2 10 40 1 20 40 ] u* hp X X[ 65 40 30 20 20 30 10 5 0 3 5 ] u* s hit X[ 75 59 39 20 20 30 20 10 0 3 5 ] u* w hit X[ 50 60 80 20 20 30 0 0 0 3 5 ] u* h hit X[ 40 35 80 80 80 80 20 5 0 40 40 ] u* x hit X[ 40 25 80 80 80 80 20 5 0 40 40 ] u* t hit X[ 20 35 50 50 50 50 50 25 0 75 75 ] u* y hit X[ 20 25 80 80 80 80 80 50 0 90 90 ] u* C hit X[ 20 25 80 80 80 80 80 50 0 90 90 ] u* D hit X100 u* d hit X[ 30 20 60 80 90 50 50 50 0 0 0 ] u* * hit X[ 50 40 60 80 90 50 50 50 0 0 0 ] u* @ hit X X1 u* u* damage X2 w [ C D ] damage X3 [ C D ] [ C D ] damage X4 [ C D ] cities damage X5 C [ x t y ] damage X10 D D damage X20 D [ x t y ] damage X49 u* d damage X X50 nuke-hit ; death rays are not nukes? X X-50 neutrality X X1 d self-destruct X X[ 50 30 ] cities s capture X[ 40 15 ] cities w capture X10% cities w protect X50% cities s protect Xtrue cities s bridge X X1 fuel u* hits-with X1 fuel u* hit-by X X1 [ * @ ] always-seen X X1 movers can-disband X X1 cities neutral X Xtrue movers changes-side Xtrue cities changes-side X X"defeats" [ s w ] destroy-message X"shoots down" [ x t y ] destroy-message X"flattens" cities destroy-message X Xbegin{notes} XOriginally designed as a test, and so we could fly Death Stars around. XAdditional plausibility supplied by Alan Wexelblat <wex%sw.MCC.COM@MCC.COM>. Xend{notes} X Xend X X END_OF_lib/starwars.per if test 3673 -ne `wc -c <lib/starwars.per`; then echo shar: \"lib/starwars.per\" unpacked with wrong size! fi # end of overwriting check fi if test -f xconq.patch1 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"xconq.patch1\" else echo shar: Extracting \"xconq.patch1\" \(33991 characters\) sed "s/^X//" >xconq.patch1 <<'END_OF_xconq.patch1' Xdiff xconq5.0/Makefile xconq/Makefile X5c5 X< # RCS $Header: Makefile,v 1.1 88/06/21 13:49:15 shebs Exp $ X--- X> # RCS $Header: Makefile,v 1.2 88/07/18 22:06:05 shebs Exp $ X67c67 X< cc -o xconq $(CFLAGS) $(OBJ) X10.o $(X10LIB) X--- X> $(CC) -o xconq $(CFLAGS) $(OBJ) X10.o $(X10LIB) X72c72 X< cc -o x11conq $(CFLAGS) $(OBJ) X11.o $(X11LIB) X--- X> $(CC) -o x11conq $(CFLAGS) $(OBJ) X11.o $(X11LIB) X77c77 X< cc -o cconq $(CFLAGS) $(OBJ) curses.o $(CURSESLIB) X--- X> $(CC) -o cconq $(CFLAGS) $(OBJ) curses.o $(CURSESLIB) X82c82 X< per2c <lib/$(PERIOD).per >$(PERIOD).c X--- X> ./per2c <lib/$(PERIOD).per >$(PERIOD).c X87c87 X< cc -o per2c $(CFLAGS) per2c.o period.o X--- X> $(CC) -o per2c $(CFLAGS) per2c.o period.o X90c90 X< cc -o hexify $(CFLAGS) hexify.o X--- X> $(CC) -o hexify $(CFLAGS) hexify.o X111c111 X< X--- X> X148c148 X< (cd lib; fc xconq.bdf; fc standard.bdf) X--- X> (cd lib; fc xconq.bdf >xconq.snf; fc standard.bdf >standard.snf) Xdiff xconq5.0/ToDo xconq/ToDo X3c3 X< Try *again* to get display updating to work for captured always-seen units. X--- X> Fix occasional problem where screen is not scrolled over to cursor. X5c5,6 X< Fix loss of first input character after reconfiguring display. X--- X> Fix lack of terrain drawing when passing by hidden unit on unseen terrain X> in mono mode. X7c8 X< Fix to not fail if favorite terrain type is not present on the map. X--- X> Fix oddities due to fiddling with help windows. X9c10 X< Fix save/restore of counts so they don't get incremented twice. X--- X> Fix bogus unit name that can appear during attack of self-destructing unit. X11c12 X< Eliminate redraw of unit info during another displayed side's turn. X--- X> Fix ambiguity in occupant death messages if attacker and defender occupied. X13c14,15 X< Make machine players adjust construction to current situation better. X--- X> Change mode switching so multi-input commands not aborted when another X> player's turn is over. X14a17,18 X> Add ability to randomly name unnamed "named" units read from mapfiles. X> X19,20d22 X< Fix machine player attached to iconified window (wedges other players). X< X25,26c27 X< Fix Sun bug causing display of char 0 instead of usual box-shaped cursor. X< (Appears to be due to server rather than library?) X--- X> Add period words for ability of attack to steal (or give?) resources. X27a29,34 X> Add period word for hidden unit not to be revealed until after it has attacked. X> X> Add an index of words and word types to period manual. X> X> Add a capability for outlines of hexes in monochrome. X> X32,33d38 X< Implement view coverage of hex due to population. X< X34a40,42 X> X> Eliminate redraw of unit info during another displayed side's turn, X> and generally reduce text window traffic. Xdiff xconq5.0/X10.c xconq/X10.c X5c5 X< /* RCS $Header: X10.c,v 1.1 88/06/21 12:29:56 shebs Exp $ */ X--- X> /* RCS $Header: X10.c,v 1.3 88/07/19 11:11:35 shebs Exp $ */ X27a28,29 X> Font open_font(); /* To keep some systems happy */ X> X621a624 X> side->reqtype = GARBAGE; X623,664c626,634 X< while (TRUE) { X< XNextEvent(&evt); X< switch (evt.type) { X< case KeyPressed: X< buf = XLookupMapping(&evt, &nchar); X< if (nchar > 0) { X< side->reqtype = KEYBOARD; X< side->reqch = *buf; X< if (Debug) printf("Host %s returns key '%c'\n", X< side->host, side->reqch); X< return; X< } X< break; X< case ButtonPressed: X< XQueryMouse(side->map, &rawx, &rawy, &dummy); X< XQueryMouse(side->state, &rux, &ruy, &dummy); X< if (rux < 0) { X< side->reqtype = MAPPOS; X< deform(side, rawx, rawy, &(side->reqx), &(side->reqy)); X< if (Debug) printf("Host %s returns map %d %d\n", X< side->host, side->reqx, side->reqy); X< } else { X< side->reqtype = UNITTYPE; X< side->requtype = ruy / max(side->hh, side->fh); X< if (Debug) printf("Host %s returns unit type %d\n", X< side->host, side->requtype); X< } X< return; X< case ExposeRegion: X< /* Too much work to be clever about redrawing part of screen */ X< case ExposeWindow: X< if (evt.window == side->main) { X< flush_input(side); X< redraw(side); X< } X< if (Debug) printf("Host %s exposes itself\n", side->host); X< /* Test so machines with screens don't wedge everybody else... */ X< if (!humanside(side)) return; X< break; X< default: X< case_panic("event type", evt.type); X< break; X--- X> XNextEvent(&evt); X> switch (evt.type) { X> case KeyPressed: X> buf = XLookupMapping(&evt, &nchar); X> if (nchar > 0) { X> side->reqtype = KEYBOARD; X> side->reqch = *buf; X> if (Debug) printf("Host %s returns key '%c'\n", X> side->host, side->reqch); X665a636,663 X> break; X> case ButtonPressed: X> XQueryMouse(side->map, &rawx, &rawy, &dummy); X> XQueryMouse(side->state, &rux, &ruy, &dummy); X> if (rux < 0) { X> side->reqtype = MAPPOS; X> deform(side, rawx, rawy, &(side->reqx), &(side->reqy)); X> if (Debug) printf("Host %s returns map %d %d\n", X> side->host, side->reqx, side->reqy); X> } else { X> side->reqtype = UNITTYPE; X> side->requtype = ruy / max(side->hh, side->fh); X> if (Debug) printf("Host %s returns unit type %d\n", X> side->host, side->requtype); X> } X> break; X> case ExposeRegion: X> /* Too much work to be clever about redrawing part of screen */ X> case ExposeWindow: X> if (evt.window == side->main) { X> flush_input(side); X> redraw(side); X> } X> if (Debug) printf("Host %s exposes itself\n", side->host); X> break; X> default: X> case_panic("event type", evt.type); X> break; X777c775 X< flash_position(side, sx, sy) X--- X> flash_position(side, sx, sy, tm) X779c777 X< int sx, sy; X--- X> int sx, sy, tm; X781c779 X< int i, sx1, sy1, sx2, sy2; X--- X> int sx1, sy1, sx2, sy2; X783,794c781,794 X< sx1 = sx - 50 + side->hw/2; sy1 = sy + 50 + side->hch/2; X< sx2 = sx + 50 + side->hw/2; sy2 = sy - 50 + side->hch/2; X< XLine(side->map, sx1, sy1, sx2, sy2, X< 1, 1, side->owncolor, GXinvert, AllPlanes); X< XLine(side->map, sx1, sy2, sx2, sy1, X< 1, 1, side->owncolor, GXinvert, AllPlanes); X< flush_output(side); X< for (i = 0; i < DELAY; ++i); X< XLine(side->map, sx1, sy1, sx2, sy2, X< 1, 1, side->owncolor, GXinvert, AllPlanes); X< XLine(side->map, sx1, sy2, sx2, sy1, X< 1, 1, side->owncolor, GXinvert, AllPlanes); X--- X> if (tm > 0) { X> sx1 = sx - 50 + side->hw/2; sy1 = sy + 50 + side->hch/2; X> sx2 = sx + 50 + side->hw/2; sy2 = sy - 50 + side->hch/2; X> XLine(side->map, sx1, sy1, sx2, sy2, X> 1, 1, side->owncolor, GXinvert, AllPlanes); X> XLine(side->map, sx1, sy2, sx2, sy1, X> 1, 1, side->owncolor, GXinvert, AllPlanes); X> flush_output(side); X> nap(tm); X> XLine(side->map, sx1, sy1, sx2, sy2, X> 1, 1, side->owncolor, GXinvert, AllPlanes); X> XLine(side->map, sx1, sy2, sx2, sy1, X> 1, 1, side->owncolor, GXinvert, AllPlanes); X> } X880a881 X> char *title; Xdiff xconq5.0/X11.c xconq/X11.c X7c7 X< /* RCS $Header: X11.c,v 1.1 88/06/21 12:30:00 shebs Exp $ */ X--- X> /* RCS $Header: X11.c,v 1.3 88/07/19 11:10:03 shebs Exp $ */ X146d145 X< #define DELAY 100000 X244c243,244 X< 50, 3, 100, 100, X--- X> 50, 3, X> display_width(side), display_height(side), X260c260 X< return ((19 * XDisplayWidth(sdd(), 0)) / 20); X--- X> return ((19 * XDisplayWidth(sdd(), DefaultScreen(sdd()))) / 20); X266c266 X< return ((19 * XDisplayHeight(sdd(), 0)) / 20); X--- X> return ((19 * XDisplayHeight(sdd(), DefaultScreen(sdd()))) / 20); X367c367 X< DefaultDepth(sdd(), 0) ); X--- X> DefaultDepth(sdd(), DefaultScreen(sdd()))); X369c369 X< DefaultDepth(sdd(), 0) ); X--- X> DefaultDepth(sdd(), DefaultScreen(sdd()))); X424c424 X< XQueryColors(dpy, DefaultColormap(dpy, 0), defs, 2); X--- X> XQueryColors(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), defs, 2); X563c563,564 X< /* Specify the sorts of input that will be allowed. */ X--- X> /* Specify the sorts of input that will be allowed - main window needs to */ X> /* see mouse buttons so unit type selection works right. */ X569c570,571 X< XSelectInput(sdd(), side->map, ButtonPressMask|ExposureMask); X--- X> XSelectInput(sdd(), side->map, ButtonPressMask|ExposureMask); X> XSelectInput(sdd(), side->state, ButtonPressMask|ExposureMask); X657c659,663 X< display_colors(side) Side *side; { return XDisplayCells(sdd(), 0); } X--- X> display_colors(side) X> Side *side; X> { X> return XDisplayCells(sdd(), DefaultScreen(sdd())); X> } X659c665,669 X< white_color(side) Side *side; { return WhitePixel(sdd(), 0); } X--- X> white_color(side) X> Side *side; X> { X> return WhitePixel(sdd(), DefaultScreen(sdd())); X> } X661c671,675 X< black_color(side) Side *side; { return BlackPixel(sdd(), 0); } X--- X> black_color(side) X> Side *side; X> { X> return BlackPixel(sdd(), DefaultScreen(sdd())); X> } X673c687,688 X< XAllocNamedColor(sdd(), DefaultColormap(sdd(), 0), name, &avail, &c); X--- X> XAllocNamedColor(sdd(), DefaultColormap(sdd(), DefaultScreen(sdd())), name, X> &avail, &c); X743,772c758,762 X< while (TRUE) { X< XNextEvent(sdd(), &evt); X< switch (evt.type) { X< case KeyPress: X< if (evt.xkey.window != side->main && X< evt.xkey.window != side->help) X< return FALSE; X< nchar = XLookupString(&evt, buf, BUFSIZE, NULL, NULL); X< if (nchar > 0) { X< side->reqtype = KEYBOARD; X< side->reqch = *buf; X< if (Debug) printf("Host %s returns key '%c'\n", X< side->host, side->reqch); X< return; X< } X< break; X< case ButtonPress: X< if (evt.xbutton.window == side->map) { X< rawx = evt.xbutton.x; rawy = evt.xbutton.y; X< side->reqtype = MAPPOS; X< deform(side, rawx, rawy, &(side->reqx), &(side->reqy)); X< if (Debug) printf("Host %s returns map %d %d\n", X< side->host, side->reqx, side->reqy); X< } else if (evt.xbutton.window == side->state) { X< rawx = evt.xbutton.x; rawy = evt.xbutton.y; X< side->reqtype = UNITTYPE; X< side->requtype = rawy / max(side->hh, side->fh); X< if (Debug) printf("Host %s returns unit type %d\n", X< side->host, side->requtype); X< } X--- X> side->reqtype = GARBAGE; X> XNextEvent(sdd(), &evt); X> switch (evt.type) { X> case KeyPress: X> if (evt.xkey.window != side->main && evt.xkey.window != side->help) X774,785c764,769 X< case Expose: X< if (evt.xexpose.window == side->main || X< evt.xexpose.window == side->map) { X< flush_input(side); X< redraw(side); X< } X< if (Debug) printf("Host %s exposes itself\n", side->host); X< return FALSE; X< break; X< default: X< case_panic("event type", evt.type); X< break; X--- X> nchar = XLookupString(&evt, buf, BUFSIZE, NULL, NULL); X> if (nchar > 0) { X> side->reqtype = KEYBOARD; X> side->reqch = *buf; X> if (Debug) printf("Host %s returns key '%c'\n", X> side->host, side->reqch); X786a771,797 X> break; X> case ButtonPress: X> if (evt.xbutton.window == side->map) { X> rawx = evt.xbutton.x; rawy = evt.xbutton.y; X> side->reqtype = MAPPOS; X> deform(side, rawx, rawy, &(side->reqx), &(side->reqy)); X> if (Debug) printf("Host %s returns map %d %d\n", X> side->host, side->reqx, side->reqy); X> } else if (evt.xbutton.window == side->state) { X> rawx = evt.xbutton.x; rawy = evt.xbutton.y; X> side->reqtype = UNITTYPE; X> side->requtype = rawy / max(side->hh, side->fh); X> if (Debug) printf("Host %s returns unit type %d\n", X> side->host, side->requtype); X> } X> break; X> case Expose: X> if (evt.xexpose.window == side->main || X> evt.xexpose.window == side->map) { X> flush_input(side); X> redraw(side); X> } X> if (Debug) printf("Host %s exposes itself\n", side->host); X> break; X> default: X> case_panic("event type", evt.type); X> break; X864a876,878 X> #ifdef STUPIDFLUSH X> XFlush(sdd()); X> #endif STUPIDFLUSH X903a918,920 X> #ifdef STUPIDFLUSH X> XFlush(sdd()); X> #endif STUPIDFLUSH X909c926 X< flash_position(side, sx, sy) X--- X> flash_position(side, sx, sy, tm) X911c928 X< int sx, sy; X--- X> int sx, sy, tm; X913c930 X< int i, sx1, sy1, sx2, sy2; X--- X> int sx1, sy1, sx2, sy2; X915,922c932,941 X< sx1 = sx - 50 + side->hw/2; sy1 = sy + 50 + side->hch/2; X< sx2 = sx + 50 + side->hw/2; sy2 = sy - 50 + side->hch/2; X< XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy1, sx2, sy2); X< XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy2, sx2, sy1); X< flush_output(side); X< for (i = 0; i < DELAY; ++i); X< XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy1, sx2, sy2); X< XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy2, sx2, sy1); X--- X> if (tm > 0) { X> sx1 = sx - 50 + side->hw/2; sy1 = sy + 50 + side->hch/2; X> sx2 = sx + 50 + side->hw/2; sy2 = sy - 50 + side->hch/2; X> XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy1, sx2, sy2); X> XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy2, sx2, sy1); X> flush_output(side); X> nap(tm); X> XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy1, sx2, sy2); X> XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy2, sx2, sy1); X> } X1092a1112,1114 X> #ifdef STUPIDFLUSH X> XFlush(sdd()); X> #endif STUPIDFLUSH X1110c1132 X< XBell(sdd(), 0); X--- X> XBell(sdd(), DefaultScreen(sdd())); Xdiff xconq5.0/attack.c xconq/attack.c X5c5 X< /* RCS $Header: attack.c,v 1.2 88/06/28 10:38:26 shebs Exp $ */ X--- X> /* RCS $Header: attack.c,v 1.3 88/07/17 16:18:22 shebs Exp $ */ X382a383 X> draw_hex(ps, px, py, TRUE); XOnly in xconq: config.h Xdiff xconq5.0/curses.c xconq/curses.c X5c5 X< /* RCS $Header: curses.c,v 1.1 88/06/21 12:30:04 shebs Exp $ */ X--- X> /* RCS $Header: curses.c,v 1.2 88/07/17 15:26:31 shebs Exp $ */ X75c75 X< #ifdef HPUX X--- X> #ifdef USECBREAK X77,78c77,78 X< #endif HPUX X< #ifdef BSD X--- X> #endif USECBREAK X> #ifdef USECRMODE X80c80 X< #endif BSD X--- X> #endif USECRMODE X281c281 X< flash_position(side, x, y) Side *side; int x, y; {} X--- X> flash_position(side, x, y, tm) Side *side; int x, y, tm; {} Xdiff xconq5.0/custom.ms xconq/custom.ms X28a29,35 X> Since they are mostly read by variations on C's \fIscanf\fP function, X> the format is rather rigid; numbers may not be omitted, no blank lines X> are allowed (but whitespace between numbers on a line is OK), X> and mistakes will not always be recognized. X> The one general exception is the period description, which is read by X> a lexical analyzer, which allows free-format input. Other more specific X> exceptions will be noted below. X202c209,210 X< To lose, must be at or below that number for any one of the types X--- X> To lose, must be at or below that many for \fIall\fP unit types X> simultaneously X203a212,214 X> To make this condition apply to only one unit type, set all the other X> numbers to very low (for win condition) or very high (for lose condition) X> values, outside the range normally occurring during a game. X386,390d396 X< The \fBto-make\fP word actually specifies the amount of resource to be X< consumed each turn, rather than the total, which can be a problem for X< small resource amounts and long construction times. This will probably X< be changed to a total amount at some point in the future. X< .LP X393d398 X< Xdiff xconq5.0/do.c xconq/do.c X5c5 X< /* RCS $Header: do.c,v 1.1 88/06/21 12:30:06 shebs Exp $ */ X--- X> /* RCS $Header: do.c,v 1.2 88/07/17 17:08:59 shebs Exp $ */ X707a708,719 X> /* Flicker on the current position, in case it's not easily visible. */ X> X> do_flash(side, n) X> Side *side; X> int n; X> { X> int sx, sy; X> X> xform(side, unwrap(side, side->curx), side->cury, &sx, &sy); X> flash_position(side, sx, sy, 1000); X> } X> X754c766 X< sort_units(); X--- X> sort_units(TRUE); Xdiff xconq5.0/draw.c xconq/draw.c X5c5 X< /* RCS $Header: draw.c,v 1.1 88/06/21 12:30:08 shebs Exp $ */ X--- X> /* RCS $Header: draw.c,v 1.3 88/07/18 17:10:44 shebs Exp $ */ X469c469 X< flash_position(side, sx, sy); X--- X> flash_position(side, sx, sy, DELAY); Xdiff xconq5.0/ginit.c xconq/ginit.c X5c5 X< /* RCS $Header: ginit.c,v 1.1 88/06/21 12:30:10 shebs Exp $ */ X--- X> /* RCS $Header: ginit.c,v 1.2 88/07/15 14:56:16 shebs Exp $ */ X113c113 X< 20 * side->fw, period.numutypes*max(side->hh, side->fh)); X--- X> 22 * side->fw, period.numutypes*max(side->hh, side->fh)); X195c195 X< side->monochrome = (display_colors(side) == 2); X--- X> side->monochrome = (display_colors(side) <= 2); Xdiff xconq5.0/init.c xconq/init.c X5c5 X< /* RCS $Header: init.c,v 1.2 88/06/28 10:06:13 shebs Exp $ */ X--- X> /* RCS $Header: init.c,v 1.5 88/07/20 14:29:13 shebs Exp $ */ X31a32 X> bool inopen[MAXUTYPES]; /* true if unit type need not be occ at start */ X33d33 X< int favterr[MAXUTYPES]; /* "favorite terrain" of each unit type */ X138c138,139 X< if (utypes[unit->type].alreadyseen || X--- X> if (period.allseen || X> utypes[unit->type].alreadyseen || X152a154,155 X> /* More code to initialize views of area. */ X> X221a225 X> /* Favorite terrains are sorted by order of preference. */ X225c229 X< int u, t, i; X--- X> int i; X228,235d231 X< for_all_unit_types(u) { X< favterr[u] = 0; /* doesn't really matter which one */ X< for_all_terrain_types(t) { X< if (utypes[u].favored[t] > utypes[u].favored[favterr[u]]) X< favterr[u] = t; X< } X< } X< /* Check for existence of favorite terrain on map */ X247c243 X< int x0, y0, u, i, num, first = period.firstutype, numleft[MAXUTYPES]; X--- X> int x0, y0, u, t, i, num, first = period.firstutype, numleft[MAXUTYPES]; X250a247,253 X> /* Precompute some important info */ X> for_all_unit_types(u) { X> inopen[u] = FALSE; X> for_all_terrain_types(t) { X> if (utypes[u].favored[t] > 0) inopen[u] = TRUE; X> } X> } X308c311 X< int tries, x, y, diam = (2 * period.countrysize + 1); X--- X> int tries, x, y, diameter = (2 * period.countrysize + 1); X313c316 X< y = random(world.height - diam) + period.countrysize; X--- X> y = random(world.height - diameter) + period.countrysize; X321c324 X< max(world.width, world.height), good_place, cxp, cyp)) { X--- X> world.width/2+world.height/2, good_place, cxp, cyp)) { X326c329 X< fprintf(stderr, "Try bigger maps or fewer sides next time.\n"); X--- X> fprintf(stderr, "Try a bigger map, different map, or fewer sides.\n"); X339c342 X< int u, terr = terrain_at(x, y); X--- X> int u, t = terrain_at(x, y); X341c344,346 X< for_all_unit_types(u) if (terr == favterr[u]) numhexes[u]++; X--- X> for_all_unit_types(u) { X> if (probability(utypes[u].favored[t])) numhexes[u]++; X> } X359c364,365 X< if (first != NOTHING && terrain_at(cx, cy) != favterr[first]) X--- X> if (first != NOTHING && X> !probability(utypes[first].favored[terrain_at(cx, cy)])) X365c371 X< if (utypes[u].incountry > numhexes[u]) return FALSE; X--- X> if (inopen[u] && utypes[u].incountry > numhexes[u]) return FALSE; X392a399 X> set_cover(side, wrap(x), y, 100); X415,416d421 X< /* "favterr" is poorly and unrobustly handled here... */ X< X422c427 X< int u = unit->type, t, tries, x, y, chance, r, favterr = 0; X--- X> int u = unit->type, t, tries, x, y, chance, r; X425,430c430 X< for_all_terrain_types(t) { X< if (could_move(u, t)) X< canmove = TRUE; X< if (utypes[u].favored[t] > utypes[u].favored[favterr]) X< favterr = t; X< } X--- X> for_all_terrain_types(t) if (could_move(u, t)) canmove = TRUE; Xdiff xconq5.0/input.c xconq/input.c X5c5 X< /* RCS $Header: input.c,v 1.1 88/06/21 12:30:17 shebs Exp $ */ X--- X> /* RCS $Header: input.c,v 1.4 88/07/20 15:03:51 shebs Exp $ */ X53c53 X< do_redraw(), do_disband(), do_return(), X--- X> do_redraw(), do_flash(), do_disband(), do_return(), X81a82 X> 'v', do_flash, 1, FALSE, "highlight current position", X171,175c172,178 X< if (side->reqactive && side->reqtype != GARBAGE) { X< if (Debug) printf("Fulfilling %s request with input type %d\n", X< side->name, side->reqtype); X< side->reqactive = FALSE; X< (*(side->reqhandler))(side); X--- X> if (side->reqactive) { X> if (side->reqtype != GARBAGE) { X> if (Debug) printf("Answering %s request with inptype %d\n", X> side->name, side->reqtype); X> side->reqactive = FALSE; X> (*(side->reqhandler))(side); X> } XCommon subdirectories: xconq5.0/lib and xconq/lib Xdiff xconq5.0/map.c xconq/map.c X5c5 X< /* RCS $Header: map.c,v 1.1 88/06/21 12:30:19 shebs Exp $ */ X--- X> /* RCS $Header: map.c,v 1.4 88/07/20 14:29:55 shebs Exp $ */ X60a61,62 X> bool sidecountsread; /* Obscure, fixes numbers of restored units */ X> X141a144 X> sidecountsread = FALSE; X165a169 X> sidecountsread = FALSE; X363a368 X> sidecountsread = TRUE; X879c884 X< sort_units(); X--- X> sort_units(TRUE); X1019,1020c1024,1026 X< /* Dumb use of "limit" means hexes at edge of map may be searched repeatedly */ X< /* A good place to optimize things... */ X--- X> /* Note that points far outside the map may be generated, but the predicate */ X> /* will not be called on them. It may be applied to the same point several */ X> /* times, however. */ X1033,1034c1039,1040 X< x1 = wrap(x0 + dist * dirx[dir]); X< y1 = limit(y0 + dist * diry[dir]); X--- X> x1 = x0 + dist * dirx[dir]; X> y1 = y0 + dist * diry[dir]; X1037,1041c1043,1049 X< x = wrap(x1 + i * dirx[dir2]); X< y = limit(y1 + i * diry[dir2]); X< if ((*pred)(x, y)) { X< *rxp = x; *ryp = y; X< return TRUE; X--- X> x = x1 + i * dirx[dir2]; X> y = y1 + i * diry[dir2]; X> if (between(0, y, world.height-1)) { X> if ((*pred)(wrap(x), y)) { X> *rxp = wrap(x); *ryp = y; X> return TRUE; X> } X1057c1065 X< int x, y, y1 = y0 - dist, y2 = y0 + dist, x1, x2; X--- X> int x, y, x1, y1, x2, y2; X1058a1067,1069 X> dist = min(dist, max(world.width, world.height)); X> y1 = y0 - dist; X> y2 = y0 + dist; Xdiff xconq5.0/move.c xconq/move.c X5c5 X< /* RCS $Header: move.c,v 1.1 88/06/21 12:30:23 shebs Exp $ */ X--- X> /* RCS $Header: move.c,v 1.4 88/07/20 15:06:31 shebs Exp $ */ X128,129c128 X< /* since this causes endless difficulties, despite the apparent improvement */ X< /* in realism. (or allow 0 but round up when possible?) */ X--- X> /* unless it is out of movement supplies. */ X136c135 X< int u = unit->type, moves = 0; X--- X> int u = unit->type, r, moves = 0; X149a149,154 X> for_all_resource_types(r) { X> if (utypes[u].tomove[r] > 0 && unit->supply[r] <= 0) { X> moves = 0; X> break; X> } X> } X295a301,302 X> char *unit_desig(); X> X303,305c310,312 X< if (Debug) printf("%s doing %s with %d moves left\n", X< unit_handle(NULL, unit), order_desig(&(unit->orders)), X< unit->movesleft); X--- X> if (Debug) printf("%d: %s doing %s with %d moves left\n", X> global.time, unit_desig(unit), X> order_desig(&(unit->orders)), unit->movesleft); X732a740 X> /* Only die now if will die during consumption phase. */ X744,745c752,755 X< exhaust_supply(unit); X< return; X--- X> if (utypes[u].consume[r] > 0) { X> exhaust_supply(unit); X> return; X> } XOnly in xconq: mplay.c Xdiff xconq5.0/output.c xconq/output.c X5c5 X< /* RCS $Header: output.c,v 1.1 88/06/21 12:30:32 shebs Exp $ */ X--- X> /* RCS $Header: output.c,v 1.3 88/07/20 16:05:49 shebs Exp $ */ X125c125 X< draw_fg_text(side, side->info, side->margin, 0, tmpbuf); X--- X> draw_info_text(side, 0, 0, 30, tmpbuf); X143a144 X> sprintf(spbuf, ""); X146d146 X< draw_fg_text(side, side->info, side->margin, 1*side->fh, spbuf); X147a148,149 X> draw_info_text(side, 0, 1, 30, spbuf); X> sprintf(spbuf, ""); X158d159 X< draw_fg_text(side, side->info, side->margin, 2*side->fh, spbuf); X160c161,162 X< sprintf(spbuf, "%s %s Moves %d", X--- X> draw_info_text(side, 0, 2, 30, spbuf); X> sprintf(spbuf, "%s %s Moves %d ", X163c165 X< draw_fg_text(side, side->info, side->margin, 3*side->fh, spbuf); X--- X> draw_info_text(side, 0, 3, 30, spbuf); X197c199 X< draw_fg_text(side, side->info, side->margin+30*side->fw, 0, spbuf); X--- X> draw_info_text(side, 30, 0, -1, spbuf); X201,202c203 X< draw_fg_text(side, side->info, X< side->margin+30*side->fw, 1*side->fh, spbuf); X--- X> draw_info_text(side, 30, 1, -1, spbuf); X212,213c213 X< draw_fg_text(side, side->info, X< side->margin+30*side->fw, 3*side->fh, spbuf); X--- X> draw_info_text(side, 30, 3, -1, spbuf); X214a215,233 X> } X> X> /* Display improvement can be achieved by padding out lines with blanks, */ X> /* then the lines need not be cleared before redrawing. */ X> X> draw_info_text(side, x, y, len, buf) X> Side *side; X> int x, y, len; X> char *buf; X> { X> int i; X> char full[BUFSIZE]; X> X> if (len < 0) len = BUFSIZE; X> strcpy(full, buf); X> for (i = strlen(buf); i < len; ++i) full[i] = ' '; X> full[len-1] = '\0'; X> draw_fg_text(side, side->info, X> side->margin + x * side->fw, y * side->fh, full); Xdiff xconq5.0/period.c xconq/period.c X5c5 X< /* RCS $Header: period.c,v 1.1 88/06/21 12:30:35 shebs Exp $ */ X--- X> /* RCS $Header: period.c,v 1.2 88/07/15 14:51:00 shebs Exp $ */ X893c893 X< add_word("spy", P0, 1, OFFSET(Period, spychance)); X--- X> add_word("spy-chance", P0, 1, OFFSET(Period, spychance)); Xdiff xconq5.0/period.ms xconq/period.ms X156c156 X< .IP \fIchar\ name\ color\ \fBrtype\fR 5 X--- X> .IP \fIchar\ name\ color\ \fBttype\fR 5 X282c282 X< Set the type of unit to get a random name during initialization. The X--- X> Set a type of unit to get a random name during initialization. The X285a286,287 X> The value can also be set to \fB2\fP, in which case the unit name X> will be displayed by itself, without side name or unit type name. X385a388 X> If the string is \fB""\fP, then the message will be suppressed entirely. X421c424,426 X< This amount is [should be] amortized over the total construction schedule. X--- X> This amount is amortized over the normal construction schedule, which X> means that extra resources are consumed by startup or research times X> (representing mistakes and experiments). X453a459,460 X> If the unit runs out of a resource that it must consume, X> it dies due to starvation. X512a520,521 X> If the unit is out of any movement resource, it is immobilized X> until it gets more. Xdiff xconq5.0/phases.c xconq/phases.c X5c5 X< /* RCS $Header: phases.c,v 1.1 88/06/21 12:30:38 shebs Exp $ */ X--- X> /* RCS $Header: phases.c,v 1.3 88/07/20 14:35:19 shebs Exp $ */ X21a22,26 X> bool anyrevolt = FALSE; X> bool anysurrender = FALSE; X> bool anyaccident = FALSE; X> bool anyattrition = FALSE; X> X61,65c66,76 X< for_all_units(unit) { X< if (alive(unit)) unit_revolt(unit); X< if (alive(unit)) unit_surrender(unit); X< if (alive(unit)) unit_accident(unit); X< if (alive(unit)) unit_attrition(unit); X--- X> { X> int u, t; X> X> for_all_unit_types(u) { X> if (utypes[u].revolt > 0) anyrevolt = TRUE; X> if (utypes[u].surrender > 0) anysurrender = TRUE; X> for_all_terrain_types(t) { X> if (utypes[u].accident[t] > 0) anyaccident = TRUE; X> if (utypes[u].attrition[t] > 0) anyattrition = TRUE; X> } X> } X66a78,89 X> if (anyrevolt) { X> for_all_units(unit) if (alive(unit)) unit_revolt(unit); X> } X> if (anysurrender) { X> for_all_units(unit) if (alive(unit)) unit_surrender(unit); X> } X> if (anyaccident) { X> for_all_units(unit) if (alive(unit)) unit_accident(unit); X> } X> if (anyattrition) { X> for_all_units(unit) if (alive(unit)) unit_attrition(unit); X> } X76c99 X< int u = unit->type, maxmor, chance; X--- X> int u = unit->type, ux = unit->x, uy = unit->y, maxmor, chance; X79c102 X< if (utypes[u].revolt > 0) { X--- X> if (utypes[unit->type].revolt > 0) { X86,88c109,111 X< see_exact(oldside, unit->x, unit->y); X< draw_hex(oldside, unit->x, unit->y, TRUE); X< all_see_hex(unit->x, unit->y); X--- X> see_exact(oldside, ux, uy); X> draw_hex(oldside, ux, uy, TRUE); X> all_see_hex(ux, uy); X154c177,178 X< notify(us, "%s %s!", unit_handle(us, unit), utypes[u].accidentmsg); X--- X> if (strlen(utypes[u].accidentmsg) > 0) X> notify(us, "%s %s!", unit_handle(us, unit), utypes[u].accidentmsg); X169,173c193,202 X< unit->hp -= utypes[u].attdamage; X< notify(us, "%s %s!%s", X< unit_handle(us, unit), utypes[u].attritionmsg, X< (unit->hp <= 0 ? " The blow is fatal!" : "")); X< if (unit->hp <= 0) kill_unit(unit, DISASTER); X--- X> if (unit->hp <= utypes[u].attdamage) { X> notify(us, "%s dies from attrition!", unit_handle(us, unit)); X> kill_unit(unit, DISASTER); X> } else { X> if (strlen(utypes[u].attritionmsg) > 0) { X> notify(us, "%s %s!", X> unit_handle(us, unit), utypes[u].attritionmsg); X> } X> unit->hp -= utypes[u].attdamage; X> } X221c250 X< for_all_resource_types(r) X--- X> for_all_resource_types(r) { X222a252 X> } X238c268 X< int u = unit->type, r; X--- X> int u = unit->type, r, mk, rmk, use; X241a272 X> mk = utypes[u].make[unit->product]; X243c274,278 X< if (unit->supply[r] < utypes[unit->product].tomake[r]) return; X--- X> if ((rmk = utypes[unit->product].tomake[r]) > 0) { X> use = (rmk / mk) + (unit->schedule < (rmk % mk) ? 1 : 0); X> if (unit->supply[r] < use) return; X> unit->supply[r] -= use; X> } X245,247d279 X< for_all_resource_types(r) { X< unit->supply[r] -= utypes[unit->product].tomake[r]; X< } X302c334 X< kill_unit(newunit, -1); X--- X> kill_unit(newunit, DISASTER); X314c346 X< notify(us, "Idiots! - %s can't build a %s in a %s!\n", X--- X> notify(us, "Idiots! - %s can't build a %s while in a %s!", X342d373 X< flush_dead_units(); X453,457c484 X< for_all_units(unit) { X< if (alive(unit)) { X< unit_consumes(unit); X< } X< } X--- X> for_all_units(unit) if (alive(unit)) unit_consumes(unit); Xdiff xconq5.0/side.c xconq/side.c X5c5 X< /* RCS $Header: side.c,v 1.1 88/06/21 12:30:40 shebs Exp $ */ X--- X> /* RCS $Header: side.c,v 1.2 88/07/18 22:07:28 shebs Exp $ */ X152a153,154 X> extern bool sidecountsread; X> X158c160,161 X< unit->number = (side != NULL ? (side->counts)[unit->type]++ : 0); X--- X> if (!sidecountsread) X> unit->number = (side != NULL ? (side->counts)[unit->type]++ : 0); X447a451 X> draw_hex(side, x, y, TRUE); XOnly in xconq5.0: standard.c Xdiff xconq5.0/unit.c xconq/unit.c X5c5 X< /* RCS $Header: unit.c,v 1.1 88/06/21 12:30:44 shebs Exp $ */ X--- X> /* RCS $Header: unit.c,v 1.5 88/07/20 15:23:42 shebs Exp $ */ X265c265 X< Order *neworders; X--- X> Order *newords; X272,273c272,273 X< neworders = (transport->standing->orders)[unit->type]; X< if (neworders->type != NONE) { X--- X> newords = (transport->standing->orders)[unit->type]; X> if (newords && newords->type != NONE) { X275,276c275,276 X< unit_handle(NULL, unit), order_desig(neworders)); X< copy_orders(&(unit->orders), neworders); X--- X> unit_desig(unit), order_desig(newords)); X> copy_orders(&(unit->orders), newords); X406c406,407 X< int schedule, prod = unit->product; X--- X> if (producing(unit)) unit->schedule = build_time(unit, unit->product); X> } X408,415c409,421 X< if (producing(unit)) { X< schedule = utypes[unit->type].make[prod]; X< if (unit->built == 0) X< schedule += ((schedule * utypes[prod].startup) / 100); X< if (unit->side->counts[prod] <= 1) X< schedule += ((schedule * utypes[prod].research) / 100); X< unit->schedule = schedule; X< } X--- X> /* Basic routine to compute how long a unit will take to build something. */ X> X> build_time(unit, prod) X> Unit *unit; X> int prod; X> { X> int schedule = utypes[unit->type].make[prod]; X> X> if (unit->built == 0) X> schedule += ((schedule * utypes[prod].startup) / 100); X> if (unit->side->counts[prod] <= 1) X> schedule += ((schedule * utypes[prod].research) / 100); X> return schedule; X504c510,511 X< sort_units() X--- X> sort_units(doall) X> bool doall; X510c517 X< while (flips && passes < numunits / 10) { X--- X> while (flips && (doall || passes < numunits / 10)) { X583a591 X> Order *ords; X588c596,597 X< if (unit->standing->orders[u]->type != NONE) { X--- X> ords = unit->standing->orders[u]; X> if (ords && ords->type != NONE) { X590,591c599 X< utypes[u].name, X< order_desig(unit->standing->orders[u])); X--- X> utypes[u].name, order_desig(ords)); X611a620 X> if (utypes[unit->type].named == 2 && unit->name) return unit->name; X674c683 X< for_all_units(unit) if (unit->id == n) return unit; X--- X> for_all_units(unit) if (alive(unit) && unit->id == n) return unit; Xdiff xconq5.0/util.c xconq/util.c X5c5 X< /* RCS $Header: util.c,v 1.1 88/06/21 12:30:46 shebs Exp $ */ X--- X> /* RCS $Header: util.c,v 1.2 88/07/15 16:04:31 shebs Exp $ */ X41a42,56 X> #endif UNIX X> } X> X> /* Napping is like sleeping, but maybe shorter. Arg is milliseconds. */ X> X> nap(t) X> long t; X> { X> #ifdef UNIX X> #ifdef BSD X> usleep(t*1000); X> #endif BSD X> #ifndef BSD X> if (t >= 1000) sleep(t/1000); X> #endif BSD Xdiff xconq5.0/version.h xconq/version.h X1c1 X< #define VERSION "5.0 (6/28/88)" X--- X> #define VERSION "5.1 (7/20/88)" Xdiff xconq5.0/xconq.6 xconq/xconq.6 X164a165,168 X> .PP X> Typically the left button should be used to place the window at startup; X> other buttons can cause it to end up somewhere off the screen. X> .PP Xdiff xconq5.0/xconq.c xconq/xconq.c X5c5 X< /* RCS $Header: xconq.c,v 1.2 88/06/28 10:38:57 shebs Exp $ */ X--- X> /* RCS $Header: xconq.c,v 1.4 88/07/17 17:11:08 shebs Exp $ */ X215a216 X> flush_dead_units(); X217c218 X< sort_units(); X--- X> sort_units(FALSE); X512,513c513 X< sprintf(tmpbuf, "%s(%s)", X< side->name, (side->host ? side->host : "")); X--- X> sprintf(tmpbuf, "%s", side->name); X514a515,518 X> if (side->host) { X> sprintf(tmpbuf, "(%s)", side->host); X> strcat(spbuf, tmpbuf); X> } Xdiff xconq5.0/xconq2.ms xconq/xconq2.ms X104,105c104,105 X< Commands to give units orders typically default to a repetition of 100 turns. X< In some cases, this is meaningless (as in moving to a place). X--- X> Commands to give units orders typically default to a repetition of 100 turns X> (In some cases, this is meaningless, as in moving to a place): X337a338,340 X> .IP v 6 X> View current unit; display a flash that should be bright enough to X> catch the eye and make it easier to see where the current unit is. END_OF_xconq.patch1 if test 33991 -ne `wc -c <xconq.patch1`; then echo shar: \"xconq.patch1\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 2 \(of 2\). cp /dev/null ark2isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0