[comp.sources.games.bugs] xconq5.3 speedups & fixes... -> xconq5.3A

ddickey@cray.com (Dan A. Dickey) (09/25/90)

[I didn't see this come across other machines the first time I posted this,
 so I'll do it again.  Are people out there getting this?  -dan]

Here is a patch to the xconq5.3.tar.Z file found on scam.berkeley.edu
to add my speedup changes to it.  I call it xconq5.3A for no particular
reason.  Not all of these changes are due to speedup changes.
I'm not exactly sure what they all are (one is the fuel "transfer" feature
fix recently posted), but only a few give it some speed.  Other things
are trivial changes...CC & CCFLAGS in the Makefile, to name one.

I wanted to get this out to the net because I haven't worked with
xconq for a long time, but I thought the speedup changes I added were
important; so I'd like to get them out to the world.  I'm not positive,
but I think you can find all the changes dealing with speed improvements
by looking for "vptr".

Also recently talked about were problems with saving/restoring games/maps.
I found this bug and fixed it, so consider one of these changes as
fixing it.  I don't remember which though, that was quite a while ago.

Anyways, here you go....I'd appreciate knowing if any of this works
for someone.
	-Dan A. Dickey	ddickey@cray.com

P.S. - Being new to sending out patches...this patch file worked for
me by cd'ing to my xtrek5.3 directory (the stuff from scam), and
doing:	patch -l -p1 < ../xconq5.3-5.3A.diff

-----cut here----save as xcqon5.3-5.3A.diff------------
diff -c xconq5.3/lib/future.per xconq5.3.A/lib/future.per
*** xconq5.3/lib/future.per	Mon Aug  7 23:01:59 1989
--- xconq5.3.A/lib/future.per	Mon Jun 11 15:09:22 1990
***************
*** 28,33 ****
--- 28,35 ----
  "_" "ice" "white" ttype
  ":" "vacuum" "black" ttype
  
+ sea default-terrain	; for campatibility with other maps
+ 
  true [ swamp vacuum ] dark
  
  t* t* nuked  ; most terrain won't actually change
diff -c xconq5.3/lib/standard.bdf xconq5.3.A/lib/standard.bdf
*** xconq5.3/lib/standard.bdf	Mon Aug  7 23:02:32 1989
--- xconq5.3.A/lib/standard.bdf	Mon Jun  4 11:30:35 1990
***************
*** 1,6 ****
  STARTFONT 2.1
  COMMENT The X10 name for this font was "/mit/games/lib/xconq5/standard.onx"
! FONT /mit/games/lib/xconq5/standard.onx.bdf
  SIZE 11 75 75
  FONTBOUNDINGBOX 16 16 0 0
  STARTPROPERTIES 2
--- 1,6 ----
  STARTFONT 2.1
  COMMENT The X10 name for this font was "/mit/games/lib/xconq5/standard.onx"
! FONT standard
  SIZE 11 75 75
  FONTBOUNDINGBOX 16 16 0 0
  STARTPROPERTIES 2
diff -c xconq5.3/lib/xconq.bdf xconq5.3.A/lib/xconq.bdf
*** xconq5.3/lib/xconq.bdf	Mon Aug  7 23:02:34 1989
--- xconq5.3.A/lib/xconq.bdf	Mon Jun  4 11:30:37 1990
***************
*** 1,6 ****
  STARTFONT 2.1
  COMMENT The X10 name for this font was "/site/Chris/Xconq/lib/xconq.onx"
! FONT /site/Chris/Xconq/lib/xconq.onx.bdf
  SIZE 11 75 75
  FONTBOUNDINGBOX 20 22 0 0
  STARTPROPERTIES 2
--- 1,6 ----
  STARTFONT 2.1
  COMMENT The X10 name for this font was "/site/Chris/Xconq/lib/xconq.onx"
! FONT xconq
  SIZE 11 75 75
  FONTBOUNDINGBOX 20 22 0 0
  STARTPROPERTIES 2
diff -c xconq5.3/Makefile xconq5.3.A/Makefile
*** xconq5.3/Makefile	Mon Aug  7 23:02:53 1989
--- xconq5.3.A/Makefile	Fri Sep  7 13:46:59 1990
***************
*** 2,12 ****
  
  #CC = gcc
  #CFLAGS = -g -O -DXCONQLIB=\"$(LIBDIR)\" -traditional
-fwritable-strings -Wall
! CFLAGS = -g
  
  # Where xconq itself lives.
  
! DESTDIR = /usr/games
  
  # Set this for wherever the library directory should be.
  
--- 2,12 ----
  
  #CC = gcc
  #CFLAGS = -g -O -DXCONQLIB=\"$(LIBDIR)\" -traditional
-fwritable-strings -Wall
! CFLAGS = -g -pg
  
  # Where xconq itself lives.
  
! DESTDIR = /home/aspen1/ddickey/games
  
  # Set this for wherever the library directory should be.
  
diff -c xconq5.3/X11.c xconq5.3.A/X11.c
*** xconq5.3/X11.c	Mon Aug  7 23:03:11 1989
--- xconq5.3.A/X11.c	Mon Jun 11 14:36:49 1990
***************
*** 333,338 ****
--- 333,341 ----
      make_pathname(xconqlib, name, "b11", spbuf);
      a = XReadBitmapFile(sdd(), side->main, spbuf, &w, &h, &rslt,
&junk, &junk);
      if (a == BitmapSuccess) return rslt;
+     make_pathname(NULL, name, "b", spbuf);
+     a = XReadBitmapFile(sdd(), side->main, spbuf, &w, &h, &rslt,
&junk, &junk);
+     if (a == BitmapSuccess) return rslt;
      make_pathname(xconqlib, name, "b", spbuf);
      a = XReadBitmapFile(sdd(), side->main, spbuf, &w, &h, &rslt,
&junk, &junk);
      if (a == BitmapSuccess) return rslt;
diff -c xconq5.3/config.h xconq5.3.A/config.h
*** xconq5.3/config.h	Mon Aug  7 23:02:56 1989
--- xconq5.3.A/config.h	Mon Jun 11 14:23:06 1990
***************
*** 52,58 ****
  /* This is where predefined maps/scenarios/periods/fonts can be found.
*/
  
  #ifndef XCONQLIB
! #define XCONQLIB "/usr/games/lib/xconq"
  #endif  XCONQLIB
  
  /* The newsfile always lives in the lib directory. */
--- 52,58 ----
  /* This is where predefined maps/scenarios/periods/fonts can be found.
*/
  
  #ifndef XCONQLIB
! #define XCONQLIB "/usr/lib/X11/xconq"
  #endif  XCONQLIB
  
  /* The newsfile always lives in the lib directory. */
diff -c xconq5.3/draw.c xconq5.3.A/draw.c
*** xconq5.3/draw.c	Mon Aug  7 23:03:03 1989
--- xconq5.3.A/draw.c	Mon Jun  4 11:30:53 1990
***************
*** 165,174 ****
  
  static int
  world_color(side, x, y)
! Side *side;
! int x, y;
  {
!     int view = side_view(side, x, y);
  
      if (side->monochrome) {
  	return ((view == UNSEEN || view == EMPTY) ? side->bgcolor :
--- 165,174 ----
  
  static int
  world_color(side, x, y)
! register Side *side;
! register int x, y;
  {
!     register int view = side_view(side, x, y);
  
      if (side->monochrome) {
  	return ((view == UNSEEN || view == EMPTY) ? side->bgcolor :
diff -c xconq5.3/map.c xconq5.3.A/map.c
*** xconq5.3/map.c	Mon Aug  7 23:03:08 1989
--- xconq5.3.A/map.c	Mon Jun 11 15:06:51 1990
***************
*** 80,91 ****
      }
      if (loaded) {
  	fprintf(stderr, "\"%s\" is already loaded.\n", name);
-     } else if ((fp = fopen(spbuf, "r")) != NULL) {
- 	if (Debug) printf("Reading \"%s\" ...\n", spbuf);
- 	mapfilenames[nummaps++] = copy_string(spbuf);
      } else if ((fp = fopen(name, "r")) != NULL) {
  	if (Debug) printf("Reading \"%s\" ...\n", name);
  	mapfilenames[nummaps++] = copy_string(name);
      } else {
  	fprintf(stderr, "Neither \"%s\" or \"%s\" could be opened!\n",
  		spbuf, name);
--- 80,91 ----
      }
      if (loaded) {
  	fprintf(stderr, "\"%s\" is already loaded.\n", name);
      } else if ((fp = fopen(name, "r")) != NULL) {
  	if (Debug) printf("Reading \"%s\" ...\n", name);
  	mapfilenames[nummaps++] = copy_string(name);
+     } else if ((fp = fopen(spbuf, "r")) != NULL) {
+ 	if (Debug) printf("Reading \"%s\" ...\n", spbuf);
+ 	mapfilenames[nummaps++] = copy_string(spbuf);
      } else {
  	fprintf(stderr, "Neither \"%s\" or \"%s\" could be opened!\n",
  		spbuf, name);
***************
*** 787,804 ****
  Side *side;
  FILE *fp;
  {
!     int x, y, view;
  
      for (y = 0; y < world.height; ++y) {
! 	for (x = 0; x < world.width; ++x) {
! 	    view = side_view(side, x, y);
! 	    if (view == UNSEEN) {
  		putc('?', fp);
! 	    } else if (view == EMPTY) {
  		putc('.', fp);
  	    } else {
! 		putc(utypes[vtype(view)].uchar, fp);
! 		putc('0' + vside(view), fp);
  	    }
  	}
  	fprintf(fp, "\n");
--- 787,805 ----
  Side *side;
  FILE *fp;
  {
!     register unchar	*vptr;
!     register int	x, y;
  
+     vptr = (unchar *) side->view;
      for (y = 0; y < world.height; ++y) {
! 	for (x = 0; x < world.width; ++x, vptr++) {
! 	    if (*vptr == UNSEEN) {
  		putc('?', fp);
! 	    } else if (*vptr == EMPTY) {
  		putc('.', fp);
  	    } else {
! 		putc(utypes[vtype(*vptr)].uchar, fp);
! 		putc('0' + vside(*vptr), fp);
  	    }
  	}
  	fprintf(fp, "\n");
diff -c xconq5.3/misc.c xconq5.3.A/misc.c
*** xconq5.3/misc.c	Mon Aug  7 23:03:05 1989
--- xconq5.3.A/misc.c	Mon Jun  4 11:30:54 1990
***************
*** 139,147 ****
  
  static int
  dist (x1, y1, x2, y2)
! int x1, y1, x2, y2;
  {
!     int dx = x2 - x1, dy = y2 - y1;
  
      if (dx >= 0) {
  	if (dy >= 0) {
--- 139,147 ----
  
  static int
  dist (x1, y1, x2, y2)
! register int x1, y1, x2, y2;
  {
!     register int dx = x2 - x1, dy = y2 - y1;
  
      if (dx >= 0) {
  	if (dy >= 0) {
***************
*** 163,171 ****
  }
  
  distance (x1, y1, x2, y2)
! int x1, y1, x2, y2;
  {
!     int d1, d2;
  
      d1 = dist(x1, y1, x2, y2);
      if (x1 <= x2) {
--- 163,171 ----
  }
  
  distance (x1, y1, x2, y2)
! register int x1, y1, x2, y2;
  {
!     register int d1, d2;
  
      d1 = dist(x1, y1, x2, y2);
      if (x1 <= x2) {
diff -c xconq5.3/mplay.c xconq5.3.A/mplay.c
*** xconq5.3/mplay.c	Mon Aug  7 23:03:13 1989
--- xconq5.3.A/mplay.c	Mon Jun  4 11:31:02 1990
***************
*** 52,57 ****
--- 52,58 ----
      short area;                 /* radius of relevance of group
activity */
      short member[MAXUTYPES];    /* number of each type in group */
      short need[MAXUTYPES];      /* what group wants but doesn't have
*/
+     Unit *uhead;	/* first unit in group */
  } Group;
  
  /* This structure is where machine sides keep all the plans and
planning */
***************
*** 154,159 ****
--- 155,161 ----
  	for (g = 0; g < MAXGROUPS; ++g) {
  	    side_plan(side)->group[g].goal = NOGROUP;
  	    side_plan(side)->group[g].priority = 0;
+ 	    side_plan(side)->group[g].uhead = NULL;
  	}
  	side_plan(side)->lastreplan = -100;
      }
***************
*** 213,218 ****
--- 215,289 ----
  make_strategy(side)
  Side *side;
  {
+     register unchar	*vptr;
+     register int	x, y;
+     int u, i, g, etype, x0, x1, x2, y1, y2, choice;
+     int pri, sumx = 0, sumy = 0, n = 0;
+     Plan *plan = side_plan(side);
+     Side *side2, *eside;
+ 
+     for_all_sides(side2) {
+ 	for_all_unit_types(u) {
+ 	    plan->estimate[side_number(side2)][u] = 0;
+ 	}
+     }
+     vptr = (unchar *) side->view;
+     for (y = 0; y < world.height; ++y) {
+ 	for (x = 0; x < world.width; ++x, vptr++) {
+ 	    if (*vptr != EMPTY && *vptr != UNSEEN) {
+ 		if (side == side_n(vside(*vptr))) {
+ 		    sumx += x;  sumy += y;  n++;
+ 		}
+ 	    }
+ 	}
+     }
+     if (n > 0) {
+ 	plan->cx = sumx / n;  plan->cy = sumy / n;
+     }
+     vptr = (unchar *) side->view;
+     for (y = 0; y < world.height; ++y) {
+ 	for (x = 0; x < world.width; ++x, vptr++) {
+ 	    if (*vptr != EMPTY && *vptr != UNSEEN) {
+ 		eside = side_n(vside(*vptr));
+ 		etype = vtype(*vptr);
+ 		if (!allied_side(side, eside)) {
+ 		    choice = attack_type(etype);
+ 		    if (eside == NULL && choice == HITTARGET) {
+ 			/* uncapturable neutrals are basically dull */
+ 		    } else if (!find_group(side, choice, x, y)) {
+ 			pri = 100 - (100 * distance(x, y, plan->cx, plan->cy))
+ 			             / world.width;
+ 			form_group(side, choice, pri+1, x, y, 0, etype);
+ 		    }
+ 		} else {
+ 		    if (!mobile(etype) && !defended(side, x, y)) {
+ 			form_group(side, DEFEND, 1, x, y, 3, NOTHING);
+ 		    }
+ 		}
+ 		if (eside) plan->estimate[side_number(eside)][etype]++;
+ 	    }
+ 	}
+     }
+     if (!world.known) {
+ 	if (!find_group(side, EXPLORE, -1, -1)) {
+ 	    x0 = 0 + random(world.width/3);
+ 	    x1 = world.width/3 + random(world.width/3);
+ 	    x2 = (2*world.width)/3 + random(world.width/3);
+ 	    y1 = 0 + random(world.height/3);
+ 	    y2 = (2*world.height)/3 + random(world.height/3);
+ 	    form_group(side, EXPLORE, 1, x0, y1, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x1, y1, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x2, y1, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x0, y2, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x1, y2, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x2, y2, 3, NOTHING);
+ 	}
+     }
+     /* should form a hex occupation group if hex mentioned in win/lose
*/
+ }
+ omake_strategy(side)
+ Side *side;
+ {
      int u, i, g, x, y, view, etype, x0, x1, x2, y1, y2, choice;
      int pri, sumx = 0, sumy = 0, n = 0;
      Plan *plan = side_plan(side);
***************
*** 303,327 ****
  review_groups (side)
  Side *side;
  {
      int g, u, u2, e, view, ideal;
      Plan *plan = side_plan(side);
-     Group *group;
      Unit *unit;
  
      for_all_unit_types(u) {
  	plan->demand[u] = 0;
      }
!     for (g = 1; g < MAXGROUPS; ++g) {
  	for_all_unit_types(u) {
! 	    plan->group[g].member[u] = 0;
! 	    plan->group[g].need[u] = 0;
  	}
      }
      for_all_units(unit) {
  	if (unit->side == side)
plan->group[unit->group].member[unit->type]++;
      }
!     for (g = 1; g < MAXGROUPS; ++g) {
! 	group = &(plan->group[g]);
  	switch (group->goal) {
  	case NOGROUP:
  	    /* a non-existent group */
--- 374,399 ----
  review_groups (side)
  Side *side;
  {
+     register Group *group;
      int g, u, u2, e, view, ideal;
      Plan *plan = side_plan(side);
      Unit *unit;
  
      for_all_unit_types(u) {
  	plan->demand[u] = 0;
      }
!     group = &(plan->group[1]);
!     for (g = 1; g < MAXGROUPS; ++g, group++) {
  	for_all_unit_types(u) {
! 	    group->member[u] = 0;
! 	    group->need[u] = 0;
  	}
      }
      for_all_units(unit) {
  	if (unit->side == side)
plan->group[unit->group].member[unit->type]++;
      }
!     group = &(plan->group[1]);
!     for (g = 1; g < MAXGROUPS; ++g, ++group) {
  	switch (group->goal) {
  	case NOGROUP:
  	    /* a non-existent group */
***************
*** 404,410 ****
  	    break;
  	}
      }
!     for (g = 1; g < MAXGROUPS; ++g) {
  	for_all_unit_types(u) {
  	    plan->demand[u] = group->priority * group->need[u];
  	}
--- 476,486 ----
  	    break;
  	}
      }
!     /* BUG??? original code looked like: */
! /*    group = &(plan->group[MAXGROUPS-1]);*/
! /*    for (g = 1; g < MAXGROUPS; ++g) {*/
!     group = &(plan->group[1]);
!     for (g = 1; g < MAXGROUPS; ++g, group++) {
  	for_all_unit_types(u) {
  	    plan->demand[u] = group->priority * group->need[u];
  	}
***************
*** 466,471 ****
--- 542,588 ----
  
  form_group(side, goal, priority, x, y, area, etype)
  Side *side;
+ register int priority;
+ int goal, x, y, area, etype;
+ {
+     register Group	*gptr;
+     register int	g, u;
+     Plan *plan = side_plan(side);
+ 
+     gptr = &plan->group[1];
+     for (g = 1; g < MAXGROUPS; ++g, gptr++) {
+ 	if (gptr->goal == NOGROUP) break;
+     }
+     if (g == MAXGROUPS) {
+ 	gptr = &plan->group[1];
+ 	for (g = 1; g < MAXGROUPS; ++g, gptr++) {
+ 	    if (priority > gptr->priority) {
+ 		disband_group(side, g);
+ 		break;
+ 	    }
+ 	}
+     }
+     if (g < MAXGROUPS) {
+ 	gptr->goal = goal;
+ 	gptr->priority = priority;
+ 	gptr->x = x;
+ 	gptr->y = y;
+ 	gptr->area = area;
+ 	gptr->etype = etype;
+ 	gptr->uhead = NULL;	/* No units in group yet. */
+ 	for_all_unit_types(u) {
+ 	    gptr->member[u] = 0;
+ 	    gptr->need[u] = 0;
+ 	}
+ 	if (Debug) printf("%d: s%d form %s\n", global.time,
+ 			  side_number(side), group_desig(plan, g));
+ 	return g;
+     } else {
+ 	return 0;
+     }
+ }
+ oform_group(side, goal, priority, x, y, area, etype)
+ Side *side;
  int goal, priority, x, y, area, etype;
  {
      int g, u;
***************
*** 503,508 ****
--- 620,626 ----
  
  /* When group's goal accomplished, release the units for other
activities. */
  /* Not very efficient to scan all units, but simpler and safer than
links. */
+ /* BLAH!  Written with links. */
  /* (All units are known to be alive here.) */
  
  disband_group(side, g)
***************
*** 509,514 ****
--- 627,657 ----
  Side *side;
  int g;
  {
+     register Unit *unit, *up;
+     register Plan *plan = side_plan(side);
+ 
+     if (Debug) printf("%d: s%d disband %s\n", global.time,
+ 		      side_number(side), group_desig(plan, g));
+     plan->group[g].goal = NOGROUP;
+     plan->group[g].priority = 0;
+     up = (Unit *) NULL;
+     for (unit = plan->group[g].uhead; unit; unit = unit->ngrp) {
+ 	    if (up)
+ 		up->ngrp = (Unit *) NULL;
+ 	    unit->group = NOGROUP;
+ 	    unit->goal = NOGOAL;
+ 	    up = unit;
+ 	    if (Debug) printf("%d: %s released from group %d\n",
+ 			      global.time, unit_desig(unit), g);
+     }
+     if (up)
+ 	up->ngrp = (Unit *) NULL;
+     plan->group[g].uhead = NULL;
+ }
+ odisband_group(side, g)
+ Side *side;
+ int g;
+ {
      Unit *unit;
      Plan *plan = side_plan(side);
  
***************
*** 531,536 ****
--- 674,695 ----
  
  find_group(side, goal, x, y)
  Side *side;
+ register int goal, x, y;
+ {
+     register Group	*gptr;
+     register int	g;
+ 
+     gptr = &((side_plan(side))->group[1]);
+     for (g = 1; g < MAXGROUPS; ++g) {
+ 	if ((gptr->goal == goal) &&
+ 	    (x == -1 || gptr->x == x) &&
+ 	    (y == -1 || gptr->y == y))
+ 	    return g;
+     }
+     return 0;
+ }
+ ofind_group(side, goal, x, y)
+ Side *side;
  int goal, x, y;
  {
      int g;
***************
*** 680,685 ****
--- 839,846 ----
  	}
      }
      unit->group = bestgroup;
+     unit->ngrp = plan->group[bestgroup].uhead;
+     plan->group[bestgroup].uhead = unit;
      unit->goal = NOGOAL;
      plan->group[bestgroup].member[unit->type]++;
      if (Debug) printf("%d: %s assigned to %s\n", global.time,
diff -c xconq5.3/phases.c xconq5.3.A/phases.c
*** xconq5.3/phases.c	Mon Aug  7 23:03:20 1989
--- xconq5.3.A/phases.c	Tue Sep  4 13:22:02 1990
***************
*** 435,454 ****
  
  /* This estimates what can be spared.  Note that total transfer of
requested */
  /* amount is not a good idea, since the supplies might be essential to
the */
! /* unit that has them first.  If we're more than half full, or the
request */
! /* is less than 1/4 of our supply, then we can spare it. */
  
  can_satisfy_need(unit, r, need)
  Unit *unit;
  int r, need;
  {
!     if (mobile(unit->type)) {
! 	return (2*(unit->supply[r] - need) > utypes[unit->type].storage[r])
||
! 	       (need < unit->supply[r] / 4);
!     } else {
! 	return (2*unit->supply[r] > utypes[unit->type].storage[r]) ||
! 	       (need < unit->supply[r] / 4);
!     }
  }
  
  /* Move supply from one unit to another.  Don't move more than is
possible; */
--- 435,450 ----
  
  /* This estimates what can be spared.  Note that total transfer of
requested */
  /* amount is not a good idea, since the supplies might be essential to
the */
! /* unit that has them first.  If the request leaves us with at least
half */
! /* of maximum capacity or the request is less than 1/5 of our supply,
then */
! /* we can spare it. */
  
  can_satisfy_need(unit, r, need)
  Unit *unit;
  int r, need;
  {
!     return (((unit->supply[r] - need) >=
(utypes[unit->type].storage[r] / 2)) ||
! 	    (need < unit->supply[r] / 5));
  }
  
  /* Move supply from one unit to another.  Don't move more than is
possible; */
diff -c xconq5.3/side.c xconq5.3.A/side.c
*** xconq5.3/side.c	Mon Aug  7 23:03:21 1989
--- xconq5.3.A/side.c	Mon Jun  4 11:31:07 1990
***************
*** 109,122 ****
  init_view(side)
  Side *side;
  {
!     int x, y, cov, seen;
  
      cov = (period.allseen ? 100 : 0);
      seen = ((period.allseen || world.known) ? EMPTY : UNSEEN);
!     for (x = 0; x < world.width; ++x) {
! 	for (y = 0; y < world.height; ++y) {
  	    set_cover(side, x, y, cov);
! 	    set_side_view(side, x, y, seen);
  	}
      }
  }
--- 109,126 ----
  init_view(side)
  Side *side;
  {
!     register unchar	*vptr;
!     register int	x, y;
!     int cov, seen;
  
      cov = (period.allseen ? 100 : 0);
      seen = ((period.allseen || world.known) ? EMPTY : UNSEEN);
!     vptr = (unchar *) side->view;
!     for (y = 0; y < world.height; ++y) {
! 	for (x = 0; x < world.width; ++x, vptr++) {
  	    set_cover(side, x, y, cov);
! 	    *vptr = seen;
! /*	    set_side_view(side, x, y, seen);*/
  	}
      }
  }
***************
*** 125,131 ****
  /* Neutrals are -1, for lack of any better ideas. */
  
  side_number (side)
! Side *side;
  {
      return (side == NULL ? -1 : (side - sides));
  }
--- 129,135 ----
  /* Neutrals are -1, for lack of any better ideas. */
  
  side_number (side)
! register Side *side;
  {
      return (side == NULL ? -1 : (side - sides));
  }
***************
*** 135,141 ****
  
  Side *
  side_n (n)
! int n;
  {
      return ((n >= 0 && n < numsides) ? &sides[n] : NULL);
  }
--- 139,145 ----
  
  Side *
  side_n (n)
! register int n;
  {
      return ((n >= 0 && n < numsides) ? &sides[n] : NULL);
  }
***************
*** 146,153 ****
  extern bool sidecountsread;
  
  assign_unit_to_side(unit, side)
! Unit *unit;
! Side *side;
  {
      unit->side = side;
      if (!sidecountsread)
--- 150,157 ----
  extern bool sidecountsread;
  
  assign_unit_to_side(unit, side)
! register Unit *unit;
! register Side *side;
  {
      unit->side = side;
      if (!sidecountsread)
***************
*** 157,163 ****
  /* Being at war requires only ones of the sides to consider itself so.
*/
  
  enemy_side(s1, s2)
! Side *s1, *s2;
  {
      if (s1 == s2) return FALSE;
      return (s1 != NULL && s2 != NULL &&
--- 161,167 ----
  /* Being at war requires only ones of the sides to consider itself so.
*/
  
  enemy_side(s1, s2)
! register Side *s1, *s2;
  {
      if (s1 == s2) return FALSE;
      return (s1 != NULL && s2 != NULL &&
***************
*** 168,174 ****
  /* A formal alliance requires the agreement of both sides. */
  
  allied_side(s1, s2)
! Side *s1, *s2;
  {
      if (s1 == s2) return TRUE;
      return (s1 != NULL && s2 != NULL &&
--- 172,178 ----
  /* A formal alliance requires the agreement of both sides. */
  
  allied_side(s1, s2)
! register Side *s1, *s2;
  {
      if (s1 == s2) return TRUE;
      return (s1 != NULL && s2 != NULL &&
***************
*** 179,185 ****
  /* Neutralness is basically anything else. */
  
  neutral_side(s1, s2)
! Side *s1, *s2;
  {
      return (!enemy_side(s1, s2) && !allied_side(s1, s2));
  }
--- 183,189 ----
  /* Neutralness is basically anything else. */
  
  neutral_side(s1, s2)
! register Side *s1, *s2;
  {
      return (!enemy_side(s1, s2) && !allied_side(s1, s2));
  }
***************
*** 188,194 ****
  /* dragging allies in. */
  
  declare_war (side1, side2)
! Side *side1, *side2;
  {
      Side *side3;
  
--- 192,198 ----
  /* dragging allies in. */
  
  declare_war (side1, side2)
! register Side *side1, *side2;
  {
      Side *side3;
  
***************
*** 430,436 ****
  
  /* Utility to clean up images of units from a side. */
  
! remove_images (side, other)
  Side *side, *other;
  {
      int n;
--- 434,440 ----
  
  /* Utility to clean up images of units from a side. */
  
! oremove_images (side, other)
  Side *side, *other;
  {
      int n;
***************
*** 441,446 ****
--- 445,469 ----
  	for (y = 0; y < world.height; ++y) {
  	    view = side_view(side, x, y);
  	    if (view != EMPTY && view != UNSEEN && vside(view) == n) {
+ 		see_exact(side, x, y);
+ 		draw_hex(side, x, y, FALSE);
+ 	    }
+ 	}
+     }
+     if (active_display(side)) flush_output(side);
+ }
+ remove_images (side, other)
+ Side *side, *other;
+ {
+     register unchar	*vptr;
+     register int	x, y;
+     register int	n;
+ 
+     n = side_number(other);
+     vptr = (unchar *) side->view;
+     for (y = 0; y < world.height; ++y) {
+ 	for (x = 0; x < world.width; ++x, vptr++) {
+ 	    if (*vptr != EMPTY && *vptr != UNSEEN && vside(*vptr) == n) {
  		see_exact(side, x, y);
  		draw_hex(side, x, y, FALSE);
  	    }
diff -c xconq5.3/unit.c xconq5.3.A/unit.c
*** xconq5.3/unit.c	Mon Aug  7 23:03:27 1989
--- xconq5.3.A/unit.c	Mon Jun  4 11:31:11 1990
***************
*** 110,115 ****
--- 110,116 ----
      newunit->standing = NULL;
      newunit->occupant = NULL;
      newunit->nexthere = NULL;
+     newunit->ngrp = NULL;
      newunit->lastdir = -1;
      insert_unit_before(unithead, newunit);
      wake_unit(newunit, FALSE);
***************
*** 386,391 ****
--- 387,393 ----
      Unit *occ;
      
      unit->hp = 0;
+     unit->movesleft = 0;
      occdeath[u]++;
      if (unit->side != NULL && reason >= 0) {
  	unit->side->balance[u][reason]++;
diff -c xconq5.3/unit.h xconq5.3.A/unit.h
*** xconq5.3/unit.h	Mon Aug  7 23:03:26 1989
--- xconq5.3.A/unit.h	Mon Jun  4 11:31:10 1990
***************
*** 130,135 ****
--- 130,136 ----
      struct _unit *nexthere;	/* pointer to fellow occupant */
      struct _unit *prev;	/* previous unit in list of all units */
      struct _unit *next;	/* next unit in list of all units */
+     struct _unit *ngrp; /* Next unit in Group */
  } Unit;
  
  /* Some convenient macros. */

---------
Dan A. Dickey      ddickey@aspen.cray.com

ddickey@aspen04.cray.com (Dan A. Dickey) (10/17/90)

[I didn't see this come across other machines after I posted it,
 so I'll do it again.  Are people out there getting this?  -dan]

Here is a patch to the xconq5.3.tar.Z file found on scam.berkeley.edu
to add my speedup changes to it.  I call it xconq5.3A for no particular
reason.  Not all of these changes are due to speedup changes.
I'm not exactly sure what they all are (one is the fuel "transfer" feature
fix recently posted), but only a few give it some speed.  Other things
are trivial changes...CC & CCFLAGS in the Makefile, to name one.

I wanted to get this out to the net because I haven't worked with
xconq for a long time, but I thought the speedup changes I added were
important; so I'd like to get them out to the world.  I'm not positive,
but I think you can find all the changes dealing with speed improvements
by looking for "vptr".

Also recently talked about were problems with saving/restoring games/maps.
I found this bug and fixed it, so consider one of these changes as
fixing it.  I don't remember which though, that was quite a while ago.

Anyways, here you go....I'd appreciate knowing if any of this works
for someone.
	-Dan A. Dickey	ddickey@cray.com

P.S. - Being new to sending out patches...this patch file worked for
me by cd'ing to my xtrek5.3 directory (the stuff from scam), and
doing:	patch -l -p1 < ../xconq5.3-5.3A.diff

-----cut here----save as xcqon5.3-5.3A.diff------------
diff -c xconq5.3/lib/future.per xconq5.3.A/lib/future.per
*** xconq5.3/lib/future.per	Mon Aug  7 23:01:59 1989
--- xconq5.3.A/lib/future.per	Mon Jun 11 15:09:22 1990
***************
*** 28,33 ****
--- 28,35 ----
  "_" "ice" "white" ttype
  ":" "vacuum" "black" ttype
  
+ sea default-terrain	; for campatibility with other maps
+ 
  true [ swamp vacuum ] dark
  
  t* t* nuked  ; most terrain won't actually change
diff -c xconq5.3/lib/standard.bdf xconq5.3.A/lib/standard.bdf
*** xconq5.3/lib/standard.bdf	Mon Aug  7 23:02:32 1989
--- xconq5.3.A/lib/standard.bdf	Mon Jun  4 11:30:35 1990
***************
*** 1,6 ****
  STARTFONT 2.1
  COMMENT The X10 name for this font was "/mit/games/lib/xconq5/standard.onx"
! FONT /mit/games/lib/xconq5/standard.onx.bdf
  SIZE 11 75 75
  FONTBOUNDINGBOX 16 16 0 0
  STARTPROPERTIES 2
--- 1,6 ----
  STARTFONT 2.1
  COMMENT The X10 name for this font was "/mit/games/lib/xconq5/standard.onx"
! FONT standard
  SIZE 11 75 75
  FONTBOUNDINGBOX 16 16 0 0
  STARTPROPERTIES 2
diff -c xconq5.3/lib/xconq.bdf xconq5.3.A/lib/xconq.bdf
*** xconq5.3/lib/xconq.bdf	Mon Aug  7 23:02:34 1989
--- xconq5.3.A/lib/xconq.bdf	Mon Jun  4 11:30:37 1990
***************
*** 1,6 ****
  STARTFONT 2.1
  COMMENT The X10 name for this font was "/site/Chris/Xconq/lib/xconq.onx"
! FONT /site/Chris/Xconq/lib/xconq.onx.bdf
  SIZE 11 75 75
  FONTBOUNDINGBOX 20 22 0 0
  STARTPROPERTIES 2
--- 1,6 ----
  STARTFONT 2.1
  COMMENT The X10 name for this font was "/site/Chris/Xconq/lib/xconq.onx"
! FONT xconq
  SIZE 11 75 75
  FONTBOUNDINGBOX 20 22 0 0
  STARTPROPERTIES 2
diff -c xconq5.3/Makefile xconq5.3.A/Makefile
*** xconq5.3/Makefile	Mon Aug  7 23:02:53 1989
--- xconq5.3.A/Makefile	Fri Sep  7 13:46:59 1990
***************
*** 2,12 ****
  
  #CC = gcc
  #CFLAGS = -g -O -DXCONQLIB=\"$(LIBDIR)\" -traditional -fwritable-strings -Wall
! CFLAGS = -g
  
  # Where xconq itself lives.
  
! DESTDIR = /usr/games
  
  # Set this for wherever the library directory should be.
  
--- 2,12 ----
  
  #CC = gcc
  #CFLAGS = -g -O -DXCONQLIB=\"$(LIBDIR)\" -traditional -fwritable-strings -Wall
! CFLAGS = -g -pg
  
  # Where xconq itself lives.
  
! DESTDIR = /home/aspen1/ddickey/games
  
  # Set this for wherever the library directory should be.
  
diff -c xconq5.3/X11.c xconq5.3.A/X11.c
*** xconq5.3/X11.c	Mon Aug  7 23:03:11 1989
--- xconq5.3.A/X11.c	Mon Jun 11 14:36:49 1990
***************
*** 333,338 ****
--- 333,341 ----
      make_pathname(xconqlib, name, "b11", spbuf);
      a = XReadBitmapFile(sdd(), side->main, spbuf, &w, &h, &rslt, &junk, &junk);
      if (a == BitmapSuccess) return rslt;
+     make_pathname(NULL, name, "b", spbuf);
+     a = XReadBitmapFile(sdd(), side->main, spbuf, &w, &h, &rslt, &junk, &junk);
+     if (a == BitmapSuccess) return rslt;
      make_pathname(xconqlib, name, "b", spbuf);
      a = XReadBitmapFile(sdd(), side->main, spbuf, &w, &h, &rslt, &junk, &junk);
      if (a == BitmapSuccess) return rslt;
diff -c xconq5.3/config.h xconq5.3.A/config.h
*** xconq5.3/config.h	Mon Aug  7 23:02:56 1989
--- xconq5.3.A/config.h	Mon Jun 11 14:23:06 1990
***************
*** 52,58 ****
  /* This is where predefined maps/scenarios/periods/fonts can be found. */
  
  #ifndef XCONQLIB
! #define XCONQLIB "/usr/games/lib/xconq"
  #endif  XCONQLIB
  
  /* The newsfile always lives in the lib directory. */
--- 52,58 ----
  /* This is where predefined maps/scenarios/periods/fonts can be found. */
  
  #ifndef XCONQLIB
! #define XCONQLIB "/usr/lib/X11/xconq"
  #endif  XCONQLIB
  
  /* The newsfile always lives in the lib directory. */
diff -c xconq5.3/draw.c xconq5.3.A/draw.c
*** xconq5.3/draw.c	Mon Aug  7 23:03:03 1989
--- xconq5.3.A/draw.c	Mon Jun  4 11:30:53 1990
***************
*** 165,174 ****
  
  static int
  world_color(side, x, y)
! Side *side;
! int x, y;
  {
!     int view = side_view(side, x, y);
  
      if (side->monochrome) {
  	return ((view == UNSEEN || view == EMPTY) ? side->bgcolor :
--- 165,174 ----
  
  static int
  world_color(side, x, y)
! register Side *side;
! register int x, y;
  {
!     register int view = side_view(side, x, y);
  
      if (side->monochrome) {
  	return ((view == UNSEEN || view == EMPTY) ? side->bgcolor :
diff -c xconq5.3/map.c xconq5.3.A/map.c
*** xconq5.3/map.c	Mon Aug  7 23:03:08 1989
--- xconq5.3.A/map.c	Mon Jun 11 15:06:51 1990
***************
*** 80,91 ****
      }
      if (loaded) {
  	fprintf(stderr, "\"%s\" is already loaded.\n", name);
-     } else if ((fp = fopen(spbuf, "r")) != NULL) {
- 	if (Debug) printf("Reading \"%s\" ...\n", spbuf);
- 	mapfilenames[nummaps++] = copy_string(spbuf);
      } else if ((fp = fopen(name, "r")) != NULL) {
  	if (Debug) printf("Reading \"%s\" ...\n", name);
  	mapfilenames[nummaps++] = copy_string(name);
      } else {
  	fprintf(stderr, "Neither \"%s\" or \"%s\" could be opened!\n",
  		spbuf, name);
--- 80,91 ----
      }
      if (loaded) {
  	fprintf(stderr, "\"%s\" is already loaded.\n", name);
      } else if ((fp = fopen(name, "r")) != NULL) {
  	if (Debug) printf("Reading \"%s\" ...\n", name);
  	mapfilenames[nummaps++] = copy_string(name);
+     } else if ((fp = fopen(spbuf, "r")) != NULL) {
+ 	if (Debug) printf("Reading \"%s\" ...\n", spbuf);
+ 	mapfilenames[nummaps++] = copy_string(spbuf);
      } else {
  	fprintf(stderr, "Neither \"%s\" or \"%s\" could be opened!\n",
  		spbuf, name);
***************
*** 787,804 ****
  Side *side;
  FILE *fp;
  {
!     int x, y, view;
  
      for (y = 0; y < world.height; ++y) {
! 	for (x = 0; x < world.width; ++x) {
! 	    view = side_view(side, x, y);
! 	    if (view == UNSEEN) {
  		putc('?', fp);
! 	    } else if (view == EMPTY) {
  		putc('.', fp);
  	    } else {
! 		putc(utypes[vtype(view)].uchar, fp);
! 		putc('0' + vside(view), fp);
  	    }
  	}
  	fprintf(fp, "\n");
--- 787,805 ----
  Side *side;
  FILE *fp;
  {
!     register unchar	*vptr;
!     register int	x, y;
  
+     vptr = (unchar *) side->view;
      for (y = 0; y < world.height; ++y) {
! 	for (x = 0; x < world.width; ++x, vptr++) {
! 	    if (*vptr == UNSEEN) {
  		putc('?', fp);
! 	    } else if (*vptr == EMPTY) {
  		putc('.', fp);
  	    } else {
! 		putc(utypes[vtype(*vptr)].uchar, fp);
! 		putc('0' + vside(*vptr), fp);
  	    }
  	}
  	fprintf(fp, "\n");
diff -c xconq5.3/misc.c xconq5.3.A/misc.c
*** xconq5.3/misc.c	Mon Aug  7 23:03:05 1989
--- xconq5.3.A/misc.c	Mon Jun  4 11:30:54 1990
***************
*** 139,147 ****
  
  static int
  dist (x1, y1, x2, y2)
! int x1, y1, x2, y2;
  {
!     int dx = x2 - x1, dy = y2 - y1;
  
      if (dx >= 0) {
  	if (dy >= 0) {
--- 139,147 ----
  
  static int
  dist (x1, y1, x2, y2)
! register int x1, y1, x2, y2;
  {
!     register int dx = x2 - x1, dy = y2 - y1;
  
      if (dx >= 0) {
  	if (dy >= 0) {
***************
*** 163,171 ****
  }
  
  distance (x1, y1, x2, y2)
! int x1, y1, x2, y2;
  {
!     int d1, d2;
  
      d1 = dist(x1, y1, x2, y2);
      if (x1 <= x2) {
--- 163,171 ----
  }
  
  distance (x1, y1, x2, y2)
! register int x1, y1, x2, y2;
  {
!     register int d1, d2;
  
      d1 = dist(x1, y1, x2, y2);
      if (x1 <= x2) {
diff -c xconq5.3/mplay.c xconq5.3.A/mplay.c
*** xconq5.3/mplay.c	Mon Aug  7 23:03:13 1989
--- xconq5.3.A/mplay.c	Mon Jun  4 11:31:02 1990
***************
*** 52,57 ****
--- 52,58 ----
      short area;                 /* radius of relevance of group activity */
      short member[MAXUTYPES];    /* number of each type in group */
      short need[MAXUTYPES];      /* what group wants but doesn't have */
+     Unit *uhead;	/* first unit in group */
  } Group;
  
  /* This structure is where machine sides keep all the plans and planning */
***************
*** 154,159 ****
--- 155,161 ----
  	for (g = 0; g < MAXGROUPS; ++g) {
  	    side_plan(side)->group[g].goal = NOGROUP;
  	    side_plan(side)->group[g].priority = 0;
+ 	    side_plan(side)->group[g].uhead = NULL;
  	}
  	side_plan(side)->lastreplan = -100;
      }
***************
*** 213,218 ****
--- 215,289 ----
  make_strategy(side)
  Side *side;
  {
+     register unchar	*vptr;
+     register int	x, y;
+     int u, i, g, etype, x0, x1, x2, y1, y2, choice;
+     int pri, sumx = 0, sumy = 0, n = 0;
+     Plan *plan = side_plan(side);
+     Side *side2, *eside;
+ 
+     for_all_sides(side2) {
+ 	for_all_unit_types(u) {
+ 	    plan->estimate[side_number(side2)][u] = 0;
+ 	}
+     }
+     vptr = (unchar *) side->view;
+     for (y = 0; y < world.height; ++y) {
+ 	for (x = 0; x < world.width; ++x, vptr++) {
+ 	    if (*vptr != EMPTY && *vptr != UNSEEN) {
+ 		if (side == side_n(vside(*vptr))) {
+ 		    sumx += x;  sumy += y;  n++;
+ 		}
+ 	    }
+ 	}
+     }
+     if (n > 0) {
+ 	plan->cx = sumx / n;  plan->cy = sumy / n;
+     }
+     vptr = (unchar *) side->view;
+     for (y = 0; y < world.height; ++y) {
+ 	for (x = 0; x < world.width; ++x, vptr++) {
+ 	    if (*vptr != EMPTY && *vptr != UNSEEN) {
+ 		eside = side_n(vside(*vptr));
+ 		etype = vtype(*vptr);
+ 		if (!allied_side(side, eside)) {
+ 		    choice = attack_type(etype);
+ 		    if (eside == NULL && choice == HITTARGET) {
+ 			/* uncapturable neutrals are basically dull */
+ 		    } else if (!find_group(side, choice, x, y)) {
+ 			pri = 100 - (100 * distance(x, y, plan->cx, plan->cy))
+ 			             / world.width;
+ 			form_group(side, choice, pri+1, x, y, 0, etype);
+ 		    }
+ 		} else {
+ 		    if (!mobile(etype) && !defended(side, x, y)) {
+ 			form_group(side, DEFEND, 1, x, y, 3, NOTHING);
+ 		    }
+ 		}
+ 		if (eside) plan->estimate[side_number(eside)][etype]++;
+ 	    }
+ 	}
+     }
+     if (!world.known) {
+ 	if (!find_group(side, EXPLORE, -1, -1)) {
+ 	    x0 = 0 + random(world.width/3);
+ 	    x1 = world.width/3 + random(world.width/3);
+ 	    x2 = (2*world.width)/3 + random(world.width/3);
+ 	    y1 = 0 + random(world.height/3);
+ 	    y2 = (2*world.height)/3 + random(world.height/3);
+ 	    form_group(side, EXPLORE, 1, x0, y1, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x1, y1, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x2, y1, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x0, y2, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x1, y2, 3, NOTHING);
+ 	    form_group(side, EXPLORE, 1, x2, y2, 3, NOTHING);
+ 	}
+     }
+     /* should form a hex occupation group if hex mentioned in win/lose */
+ }
+ omake_strategy(side)
+ Side *side;
+ {
      int u, i, g, x, y, view, etype, x0, x1, x2, y1, y2, choice;
      int pri, sumx = 0, sumy = 0, n = 0;
      Plan *plan = side_plan(side);
***************
*** 303,327 ****
  review_groups (side)
  Side *side;
  {
      int g, u, u2, e, view, ideal;
      Plan *plan = side_plan(side);
-     Group *group;
      Unit *unit;
  
      for_all_unit_types(u) {
  	plan->demand[u] = 0;
      }
!     for (g = 1; g < MAXGROUPS; ++g) {
  	for_all_unit_types(u) {
! 	    plan->group[g].member[u] = 0;
! 	    plan->group[g].need[u] = 0;
  	}
      }
      for_all_units(unit) {
  	if (unit->side == side) plan->group[unit->group].member[unit->type]++;
      }
!     for (g = 1; g < MAXGROUPS; ++g) {
! 	group = &(plan->group[g]);
  	switch (group->goal) {
  	case NOGROUP:
  	    /* a non-existent group */
--- 374,399 ----
  review_groups (side)
  Side *side;
  {
+     register Group *group;
      int g, u, u2, e, view, ideal;
      Plan *plan = side_plan(side);
      Unit *unit;
  
      for_all_unit_types(u) {
  	plan->demand[u] = 0;
      }
!     group = &(plan->group[1]);
!     for (g = 1; g < MAXGROUPS; ++g, group++) {
  	for_all_unit_types(u) {
! 	    group->member[u] = 0;
! 	    group->need[u] = 0;
  	}
      }
      for_all_units(unit) {
  	if (unit->side == side) plan->group[unit->group].member[unit->type]++;
      }
!     group = &(plan->group[1]);
!     for (g = 1; g < MAXGROUPS; ++g, ++group) {
  	switch (group->goal) {
  	case NOGROUP:
  	    /* a non-existent group */
***************
*** 404,410 ****
  	    break;
  	}
      }
!     for (g = 1; g < MAXGROUPS; ++g) {
  	for_all_unit_types(u) {
  	    plan->demand[u] = group->priority * group->need[u];
  	}
--- 476,486 ----
  	    break;
  	}
      }
!     /* BUG??? original code looked like: */
! /*    group = &(plan->group[MAXGROUPS-1]);*/
! /*    for (g = 1; g < MAXGROUPS; ++g) {*/
!     group = &(plan->group[1]);
!     for (g = 1; g < MAXGROUPS; ++g, group++) {
  	for_all_unit_types(u) {
  	    plan->demand[u] = group->priority * group->need[u];
  	}
***************
*** 466,471 ****
--- 542,588 ----
  
  form_group(side, goal, priority, x, y, area, etype)
  Side *side;
+ register int priority;
+ int goal, x, y, area, etype;
+ {
+     register Group	*gptr;
+     register int	g, u;
+     Plan *plan = side_plan(side);
+ 
+     gptr = &plan->group[1];
+     for (g = 1; g < MAXGROUPS; ++g, gptr++) {
+ 	if (gptr->goal == NOGROUP) break;
+     }
+     if (g == MAXGROUPS) {
+ 	gptr = &plan->group[1];
+ 	for (g = 1; g < MAXGROUPS; ++g, gptr++) {
+ 	    if (priority > gptr->priority) {
+ 		disband_group(side, g);
+ 		break;
+ 	    }
+ 	}
+     }
+     if (g < MAXGROUPS) {
+ 	gptr->goal = goal;
+ 	gptr->priority = priority;
+ 	gptr->x = x;
+ 	gptr->y = y;
+ 	gptr->area = area;
+ 	gptr->etype = etype;
+ 	gptr->uhead = NULL;	/* No units in group yet. */
+ 	for_all_unit_types(u) {
+ 	    gptr->member[u] = 0;
+ 	    gptr->need[u] = 0;
+ 	}
+ 	if (Debug) printf("%d: s%d form %s\n", global.time,
+ 			  side_number(side), group_desig(plan, g));
+ 	return g;
+     } else {
+ 	return 0;
+     }
+ }
+ oform_group(side, goal, priority, x, y, area, etype)
+ Side *side;
  int goal, priority, x, y, area, etype;
  {
      int g, u;
***************
*** 503,508 ****
--- 620,626 ----
  
  /* When group's goal accomplished, release the units for other activities. */
  /* Not very efficient to scan all units, but simpler and safer than links. */
+ /* BLAH!  Written with links. */
  /* (All units are known to be alive here.) */
  
  disband_group(side, g)
***************
*** 509,514 ****
--- 627,657 ----
  Side *side;
  int g;
  {
+     register Unit *unit, *up;
+     register Plan *plan = side_plan(side);
+ 
+     if (Debug) printf("%d: s%d disband %s\n", global.time,
+ 		      side_number(side), group_desig(plan, g));
+     plan->group[g].goal = NOGROUP;
+     plan->group[g].priority = 0;
+     up = (Unit *) NULL;
+     for (unit = plan->group[g].uhead; unit; unit = unit->ngrp) {
+ 	    if (up)
+ 		up->ngrp = (Unit *) NULL;
+ 	    unit->group = NOGROUP;
+ 	    unit->goal = NOGOAL;
+ 	    up = unit;
+ 	    if (Debug) printf("%d: %s released from group %d\n",
+ 			      global.time, unit_desig(unit), g);
+     }
+     if (up)
+ 	up->ngrp = (Unit *) NULL;
+     plan->group[g].uhead = NULL;
+ }
+ odisband_group(side, g)
+ Side *side;
+ int g;
+ {
      Unit *unit;
      Plan *plan = side_plan(side);
  
***************
*** 531,536 ****
--- 674,695 ----
  
  find_group(side, goal, x, y)
  Side *side;
+ register int goal, x, y;
+ {
+     register Group	*gptr;
+     register int	g;
+ 
+     gptr = &((side_plan(side))->group[1]);
+     for (g = 1; g < MAXGROUPS; ++g) {
+ 	if ((gptr->goal == goal) &&
+ 	    (x == -1 || gptr->x == x) &&
+ 	    (y == -1 || gptr->y == y))
+ 	    return g;
+     }
+     return 0;
+ }
+ ofind_group(side, goal, x, y)
+ Side *side;
  int goal, x, y;
  {
      int g;
***************
*** 680,685 ****
--- 839,846 ----
  	}
      }
      unit->group = bestgroup;
+     unit->ngrp = plan->group[bestgroup].uhead;
+     plan->group[bestgroup].uhead = unit;
      unit->goal = NOGOAL;
      plan->group[bestgroup].member[unit->type]++;
      if (Debug) printf("%d: %s assigned to %s\n", global.time,
diff -c xconq5.3/phases.c xconq5.3.A/phases.c
*** xconq5.3/phases.c	Mon Aug  7 23:03:20 1989
--- xconq5.3.A/phases.c	Tue Sep  4 13:22:02 1990
***************
*** 435,454 ****
  
  /* This estimates what can be spared.  Note that total transfer of requested */
  /* amount is not a good idea, since the supplies might be essential to the */
! /* unit that has them first.  If we're more than half full, or the request */
! /* is less than 1/4 of our supply, then we can spare it. */
  
  can_satisfy_need(unit, r, need)
  Unit *unit;
  int r, need;
  {
!     if (mobile(unit->type)) {
! 	return (2*(unit->supply[r] - need) > utypes[unit->type].storage[r]) ||
! 	       (need < unit->supply[r] / 4);
!     } else {
! 	return (2*unit->supply[r] > utypes[unit->type].storage[r]) ||
! 	       (need < unit->supply[r] / 4);
!     }
  }
  
  /* Move supply from one unit to another.  Don't move more than is possible; */
--- 435,450 ----
  
  /* This estimates what can be spared.  Note that total transfer of requested */
  /* amount is not a good idea, since the supplies might be essential to the */
! /* unit that has them first.  If the request leaves us with at least half */
! /* of maximum capacity or the request is less than 1/5 of our supply, then */
! /* we can spare it. */
  
  can_satisfy_need(unit, r, need)
  Unit *unit;
  int r, need;
  {
!     return (((unit->supply[r] - need) >= (utypes[unit->type].storage[r] / 2)) ||
! 	    (need < unit->supply[r] / 5));
  }
  
  /* Move supply from one unit to another.  Don't move more than is possible; */
diff -c xconq5.3/side.c xconq5.3.A/side.c
*** xconq5.3/side.c	Mon Aug  7 23:03:21 1989
--- xconq5.3.A/side.c	Mon Jun  4 11:31:07 1990
***************
*** 109,122 ****
  init_view(side)
  Side *side;
  {
!     int x, y, cov, seen;
  
      cov = (period.allseen ? 100 : 0);
      seen = ((period.allseen || world.known) ? EMPTY : UNSEEN);
!     for (x = 0; x < world.width; ++x) {
! 	for (y = 0; y < world.height; ++y) {
  	    set_cover(side, x, y, cov);
! 	    set_side_view(side, x, y, seen);
  	}
      }
  }
--- 109,126 ----
  init_view(side)
  Side *side;
  {
!     register unchar	*vptr;
!     register int	x, y;
!     int cov, seen;
  
      cov = (period.allseen ? 100 : 0);
      seen = ((period.allseen || world.known) ? EMPTY : UNSEEN);
!     vptr = (unchar *) side->view;
!     for (y = 0; y < world.height; ++y) {
! 	for (x = 0; x < world.width; ++x, vptr++) {
  	    set_cover(side, x, y, cov);
! 	    *vptr = seen;
! /*	    set_side_view(side, x, y, seen);*/
  	}
      }
  }
***************
*** 125,131 ****
  /* Neutrals are -1, for lack of any better ideas. */
  
  side_number (side)
! Side *side;
  {
      return (side == NULL ? -1 : (side - sides));
  }
--- 129,135 ----
  /* Neutrals are -1, for lack of any better ideas. */
  
  side_number (side)
! register Side *side;
  {
      return (side == NULL ? -1 : (side - sides));
  }
***************
*** 135,141 ****
  
  Side *
  side_n (n)
! int n;
  {
      return ((n >= 0 && n < numsides) ? &sides[n] : NULL);
  }
--- 139,145 ----
  
  Side *
  side_n (n)
! register int n;
  {
      return ((n >= 0 && n < numsides) ? &sides[n] : NULL);
  }
***************
*** 146,153 ****
  extern bool sidecountsread;
  
  assign_unit_to_side(unit, side)
! Unit *unit;
! Side *side;
  {
      unit->side = side;
      if (!sidecountsread)
--- 150,157 ----
  extern bool sidecountsread;
  
  assign_unit_to_side(unit, side)
! register Unit *unit;
! register Side *side;
  {
      unit->side = side;
      if (!sidecountsread)
***************
*** 157,163 ****
  /* Being at war requires only ones of the sides to consider itself so. */
  
  enemy_side(s1, s2)
! Side *s1, *s2;
  {
      if (s1 == s2) return FALSE;
      return (s1 != NULL && s2 != NULL &&
--- 161,167 ----
  /* Being at war requires only ones of the sides to consider itself so. */
  
  enemy_side(s1, s2)
! register Side *s1, *s2;
  {
      if (s1 == s2) return FALSE;
      return (s1 != NULL && s2 != NULL &&
***************
*** 168,174 ****
  /* A formal alliance requires the agreement of both sides. */
  
  allied_side(s1, s2)
! Side *s1, *s2;
  {
      if (s1 == s2) return TRUE;
      return (s1 != NULL && s2 != NULL &&
--- 172,178 ----
  /* A formal alliance requires the agreement of both sides. */
  
  allied_side(s1, s2)
! register Side *s1, *s2;
  {
      if (s1 == s2) return TRUE;
      return (s1 != NULL && s2 != NULL &&
***************
*** 179,185 ****
  /* Neutralness is basically anything else. */
  
  neutral_side(s1, s2)
! Side *s1, *s2;
  {
      return (!enemy_side(s1, s2) && !allied_side(s1, s2));
  }
--- 183,189 ----
  /* Neutralness is basically anything else. */
  
  neutral_side(s1, s2)
! register Side *s1, *s2;
  {
      return (!enemy_side(s1, s2) && !allied_side(s1, s2));
  }
***************
*** 188,194 ****
  /* dragging allies in. */
  
  declare_war (side1, side2)
! Side *side1, *side2;
  {
      Side *side3;
  
--- 192,198 ----
  /* dragging allies in. */
  
  declare_war (side1, side2)
! register Side *side1, *side2;
  {
      Side *side3;
  
***************
*** 430,436 ****
  
  /* Utility to clean up images of units from a side. */
  
! remove_images (side, other)
  Side *side, *other;
  {
      int n;
--- 434,440 ----
  
  /* Utility to clean up images of units from a side. */
  
! oremove_images (side, other)
  Side *side, *other;
  {
      int n;
***************
*** 441,446 ****
--- 445,469 ----
  	for (y = 0; y < world.height; ++y) {
  	    view = side_view(side, x, y);
  	    if (view != EMPTY && view != UNSEEN && vside(view) == n) {
+ 		see_exact(side, x, y);
+ 		draw_hex(side, x, y, FALSE);
+ 	    }
+ 	}
+     }
+     if (active_display(side)) flush_output(side);
+ }
+ remove_images (side, other)
+ Side *side, *other;
+ {
+     register unchar	*vptr;
+     register int	x, y;
+     register int	n;
+ 
+     n = side_number(other);
+     vptr = (unchar *) side->view;
+     for (y = 0; y < world.height; ++y) {
+ 	for (x = 0; x < world.width; ++x, vptr++) {
+ 	    if (*vptr != EMPTY && *vptr != UNSEEN && vside(*vptr) == n) {
  		see_exact(side, x, y);
  		draw_hex(side, x, y, FALSE);
  	    }
diff -c xconq5.3/unit.c xconq5.3.A/unit.c
*** xconq5.3/unit.c	Mon Aug  7 23:03:27 1989
--- xconq5.3.A/unit.c	Mon Jun  4 11:31:11 1990
***************
*** 110,115 ****
--- 110,116 ----
      newunit->standing = NULL;
      newunit->occupant = NULL;
      newunit->nexthere = NULL;
+     newunit->ngrp = NULL;
      newunit->lastdir = -1;
      insert_unit_before(unithead, newunit);
      wake_unit(newunit, FALSE);
***************
*** 386,391 ****
--- 387,393 ----
      Unit *occ;
      
      unit->hp = 0;
+     unit->movesleft = 0;
      occdeath[u]++;
      if (unit->side != NULL && reason >= 0) {
  	unit->side->balance[u][reason]++;
diff -c xconq5.3/unit.h xconq5.3.A/unit.h
*** xconq5.3/unit.h	Mon Aug  7 23:03:26 1989
--- xconq5.3.A/unit.h	Mon Jun  4 11:31:10 1990
***************
*** 130,135 ****
--- 130,136 ----
      struct _unit *nexthere;	/* pointer to fellow occupant */
      struct _unit *prev;	/* previous unit in list of all units */
      struct _unit *next;	/* next unit in list of all units */
+     struct _unit *ngrp; /* Next unit in Group */
  } Unit;
  
  /* Some convenient macros. */
-- 
Dan A. Dickey	ddickey@aspen.cray.com

-- 
---------
Dan A. Dickey      ddickey@aspen.cray.com