DELTA 14656 0 536
SVN  VV$ B S G _o I 3So ? = generator scripting

bin_PROGRAMS = civserver
lib_LTLIBRARIES = libfreeciv-srv.lfreeciv_srv_la_SOURCES = \
		aiiface.c	\
		aiiface.h	edithand.h	\
		voting.c	\
		voting# FIXME: Server library is calling AI functions.
#        We should get rid of this dependency.
libfreeciv_srv_la_DEPENDENCIES = \
 $(top_builddir)/ai/libcivai.la

libfreeciv_srv_la_LIBADD = \
 $(top_builddir)/ai/libcivai.la

civserver_DEPENDENCIES = \
 $(top_builddir)/common/libfreeciv.la \
 ./libfreeciv-srv.la \
 ./scripting/libscripting.la \
 $(LUA_AS_DEPENDENCY) $(TOLUA_AS_DEPENDENCY) \
 ./generator/libgenerator.la
civserver_LDFLAGS = $(GGZDMOD_LDFLAGS)
civserver_LDADD = \
 $(top_builddir)/common/libfreeciv.la \
 ./libfreeciv-srv.la \
 $(top_builddir)/common/libfreeciv.la \
 ./libfreeciv-srv.la \
 $(top_builddir)/common/libfreeciv.la \
 ./generator/libgenerator.la \
 ./scripting/libscripting.la $(INTLLIBS) \
 $(LUA_LIBS) $(TOLUA_LIBS) \
ENDREP
DELTA 15744 0 2076
SVN  D% W  ,V {} f H *t/* server */
#include "aiiface.h"if (pplayer2->ai_funcs.incident_war) {
      pplayer2->ai_funcs.incident_war(pplayer, pplayer2);
    }ENDREP
DELTA 15729 62 1169
SVN         xHq 9 q Z
    if (pplayer->ai_funcs.building_advisor_init) {
      pplayer->ai_funcs.building_advisor_init(pplayer);
    }ENDREP
DELTA 15744 2955 659
SVN  SH    E4A Oif (pplayer->ai_funcs.building_advisor_init) {
        pplayer->ai_funcs.building_advisor_init(pplayer); /* building advisor */
      } && pplayer->ai_funcs.before_auto_settlers) {
      pplayer->ai_funcs.before_auto_settlers(pplayer);
    }
    if (pplayer->ai_funcs.auto_settlers) {
      pplayer->ai_funcs.auto_settlers(pplayer);
    }
    if (pplayer->ai.control && pplayer->ai_funcs.last_activities) {
      pplayer->ai_funcs.last_activities(pplayer);ENDREP
DELTA 2 225233 6195
SVN   a 8  N < @@( Q 8 @@; U@3 @@b P r @@ P , @@| P E @@r G % @@( Q  @@/ Q  @@R Q ^ @@ Q i @@N Q l @@7 Q Z @@ P  @@/ Q@ @@? Q  @@/ Q 3 @@z ! 2 ! + S~ @@  D?H @@h Q ] @@? D?6 @@Z Q : @@w N y @@# Q@ @@i G s @@U P 8 @@f Q  @@> D? Ox; S~ @@ O  @@9 Q  @@n Q c @@Z U@ @@7 Q 	 @@X U@$ @@q U@^ @@ D?K @@A !  U@O @@  Q m @@f Q d @@\ Q l @@f D?	 @@1 Q  @@2 Q  P ] D?3 @@ U@n @@ Q j @@" P B @@b P B @@n P  @@B P  @@z G  @@{ D?l @@) T@ @@* G K @@ Q  @@i Q L @@ Q / @@X
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "fcintl.h"
#include "log.h"
#include "mem.h"
#include "rand.h"
#include "shared.h"
#include "support.h"

#include "base.h"
#include "city.h"
#include "combat.h"
#include "events.h"
#include "game.h"
#include "government.h"
#include "idex.h"
#include "map.h"
#include "movement.h"
#include "packets.h"
#include "player.h"
#include "unit.h"
#include "unitlist.h"

#include "path_finding.h"
#include "pf_tools.h"

#include "barbarian.h"
#include "citytools.h"
#include "cityturn.h"
#include "diplhand.h"
#include "gamehand.h"
#include "gotohand.h"
#include "maphand.h"
#include "plrhand.h"
#include "script_signal.h"
#include "sernet.h"
#include "settlers.h"
#include "srv_main.h"
#include "techtools.h"
#include "unithand.h"
#include "unittools.h"

#include "advdiplomacy.h"
#include "aiexplorer.h"
#include "aiferry.h"
#include "aitools.h"
#include "aiunit.h"

/* We need this global variable for our sort algorithm */
static struct tile *autoattack_target;

static void unit_restore_hitpoints(struct unit *punit);
static void unit_restore_movepoints(struct player *pplayer, struct unit *punit);
static void update_unit_activity(struct unit *punit);
static void wakeup_neighbor_sentries(struct unit *punit);
static void do_upgrade_effects(struct player *pplayer);

static bool maybe_cancel_patrol_due_to_enemy(struct unit *punit);
static int hp_gain_coord(struct unit *punit);

static void put_unit_onto_transporter(struct unit *punit, struct unit *ptrans);
static void pull_unit_from_transporter(struct unit *punit,
				       struct unit *ptrans);  Returns a unit type that matches the role_tech or role roles.

  If role_tech is given, then we look at all units with this role
  whose requirements are met by any player, and return a random one.  This
  can be used to give a unit to barbarians taken from the set of most
  advanced units researched by the 'real' players.

  If role_tech is not give (-1) or if there are no matching unit types,
  then we look at 'role' value and return a random matching unit type.

  It is an error if there are no available units.  This function will
  always return a valid unit.
**********/
struct unit_type *find_a_unit_type(enum unit_role_id role,
				   enum unit_role_id role_tech)
{
  struct unit_type *which[U_LAST];
  int i, num=0;

  if (role_tech != -1) {
    for(i=0; i<num_role_units(role_tech); i++) {
      struct unit_type *iunit = get_role_unit(role_tech, i);
      const int minplayers = 2;
      int players = 0;

      /* Note, if there's only one player in the game this check will always
       * fail. */
      players_iterate(pplayer) {
	if (!is_barbarian(pplayer)
	    && can_player_build_unit_direct(pplayer, iunit)) {
	  players++;
	}
      } players_iterate_end;
      if (players > minplayers) {
	which[num++] = iunit;
      }
    }
  }
  if(num==0) {
    for(i=0; i<num_role_units(role); i++) {
      which[num++] = get_role_unit(role, i);
    }
  }
  if(num==0) {
    /* Ruleset code should ensure there is at least one unit for each
     * possibly-required role, or check before calling this function.
     */
    die("No unit types in find_a_unit_type(%d,%d)!", role, role_tech);
  }
  return which[myrand(num)]  After a battle, after diplomatic aggression and after surviving trireme
  loss chance, this routine is called to decide whether or not the unit
  should become more experienced.

  There is a specified chance for it to happen, (+50% if player got SUNTZU)
  the chances are specified in the units.ruleset file.
**********/
bool maybe_make_veteran(struct unit *punit)
{
  if (punit->veteran + 1 >= MAX_VET_LEVELS
      || unit_type(punit)->veteran[punit->veteran].name[0] == '\0'
      || unit_has_type_flag(punit, F_NO_VETERAN)) {
    return FALSE;
  } else {
    int mod = 100 + get_unittype_bonus(unit_owner(punit), punit->tile,
				       unit_type(punit), EFT_VETERAN_COMBAT);

    /* The modification is tacked on as a multiplier to the base chance.
     * For example with a base chance of 50% for green units and a modifier
     * of +50% the end chance is 75%. */
    if (myrand(100) < game.veteran_chance[punit->veteran] * mod / 100) {
      punit->veteran++;
      return TRUE;
    }
    return FALSE  This is the basic unit versus unit combat routine.
  1) ALOT of modifiers bonuses etc is added to the 2 units rates.
  2) If the attack is a bombardment, do rate attacks and don't kill the
     defender, then return.
  3) the combat loop, which continues until one of the units are dead
  4) the aftermath, the loser (and potentially the stack which is below it)
     is wiped, and the winner gets a chance of gaining veteran status
**********/
void unit_versus_unit(struct unit *attacker, struct unit *defender,
		      bool bombard)
{
  int attackpower = get_total_attack_power(attacker,defender);
  int defensepower = get_total_defense_power(attacker,defender);

  int attack_firepower, defense_firepower;
  get_modified_firepower(attacker, defender,
			 &attack_firepower, &defense_firepower);

  freelog(LOG_VERBOSE, "attack:%d, defense:%d, attack firepower:%d, defense firepower:%d",
	  attackpower, defensepower, attack_firepower, defense_firepower);

  if (bombard) {
    int i;
    int rate = unit_type(attacker)->bombard_rate;

    for (i = 0; i < rate; i++) {
      if (myrand(attackpower+defensepower) >= defensepower) {
	defender->hp -= attack_firepower;
      }
    }

    /* Don't kill the target. */
    if (defender->hp <= 0) {
      defender->hp = 1;
    }
    return;
  }

  if (attackpower == 0) {
      attacker->hp=0; 
  } else if (defensepower == 0) {
      defender->hp=0;
  }
  while (attacker->hp>0 && defender->hp>0) {
    if (myrand(attackpower+defensepower) >= defensepower) {
      defender->hp -= attack_firepower;
    } else {
      attacker->hp -= defense_firepower;
    }
  }
  if (attacker->hp<0) attacker->hp = 0;
  if (defender->hp<0) defender->hp = 0;

  if (attacker->hp > 0)
    maybe_make_veteran(attacker); 
  else if (defender->hp > 0)
    maybe_make_veteran(defender)*
  Do unit auto-upgrades to players with the EFT_UNIT_UPGRADE effect
  (traditionally from Leonardo's Workshop).
************/
static void do_upgrade_effects(struct player *pplayer)
{
  int upgrades = get_player_bonus(pplayer, EFT_UPGRADE_UNIT);
  struct unit_list *candidates;

  if (upgrades <= 0) {
    return;
  }
  candidates = unit_list_new();

  unit_list_iterate(pplayer->units, punit) {
    /* We have to be careful not to strand units at sea, for example by
     * upgrading a frigate to an ironclad while it was carrying a unit. */
    if (test_unit_upgrade(punit, TRUE) == UR_OK) {
      unit_list_prepend(candidates, punit);	/* Potential candidate :) */
    }
  } unit_list_iterate_end;

  while (upgrades > 0 && unit_list_size(candidates) > 0) {
    /* Upgrade one unit.  The unit is chosen at random from the list of
     * available candidates. */
    int candidate_to_upgrade = myrand(unit_list_size(candidates));
    struct unit *punit = unit_list_get(candidates, candidate_to_upgrade);
    struct unit_type *upgrade_type
      = can_upgrade_unittype(pplayer, unit_type(punit));

    notify_player(pplayer, punit->tile, E_UNIT_UPGRADED,
		  _("%s was upgraded for free to %s."),
		  unit_name_translation(punit),
		  utype_name_translation(upgrade_type));
    upgrade_unit(punit, upgrade_type, TRUE);
    unit_list_unlink(candidates, punit);
    upgrades--;
  }

  unit_list_free(candidates)*
  1. Do Leonardo's Workshop upgrade if applicable.

  2. Restore/decrease unit hitpoints.

  3. Kill dead units.

  4. Rescue airplanes by returning them to base automatically.

  5. Decrease fuel of planes in the air.

  6. Refuel planes that are in bases.

  7. Kill planes that are out of fuel.
************/
void player_restore_units(struct player *pplayer)
{
  /* 1) get Leonardo out of the way first: */
  do_upgrade_effects(pplayer);

  unit_list_iterate_safe(pplayer->units, punit) {

    /* 2) Modify unit hitpoints. Helicopters can even lose them. */
    unit_restore_hitpoints(punit);

    /* 3) Check that unit has hitpoints */
    if (punit->hp<=0) {
      /* This should usually only happen for heli units,
	 but if any other units get 0 hp somehow, catch
	 them too.  --dwp  */
      notify_player(pplayer, punit->tile, E_UNIT_LOST_MISC, 
          _("Your %s has run out of hit points."), 
          unit_name_translation(punit));
      wipe_unit(punit);
      continue; /* Continue iterating... */
    }

    /* 4) Rescue planes if needed */
    if (utype_fuel(unit_type(punit))) {
      /* Shall we emergency return home on the last vapors? */

      /* I think this is strongly against the spirit of client goto.
       * The problem is (again) that here we know too much. -- Zamar */

      if (punit->fuel <= 1
          && !is_unit_being_refueled(punit)) {
        struct unit *carrier;

        carrier = find_transport_from_tile(punit, punit->tile);
        if (carrier) {
          put_unit_onto_transporter(punit, carrier);
        } else {
          bool alive = true;

          struct pf_map *map;
          struct pf_parameter parameter;

          pft_fill_unit_parameter(&parameter, punit);
          map = pf_create_map(&parameter);

          pf_iterator(map, pos) {
            if (pos.total_MC > punit->moves_left) {
              /* Too far */
              break;
            }

            if (is_airunit_refuel_point(pos.tile, pplayer, unit_type(punit), FALSE)) {

              struct pf_path *path;
              int id = punit->id;

              /* Client orders may be running for this unit - if so
               * we free them before engaging goto. */
              free_unit_orders(punit);

              path = pf_get_path(map, pos.tile);

	      alive = ai_follow_path(punit, path, pos.tile);

	      if (!alive) {
                freelog(LOG_ERROR, "rescue plane: unit %d died enroute!", id);
              } else if (!same_pos(punit->tile, pos.tile)) {
                  /* Enemy units probably blocked our route
                   * FIXME: We should try find alternative route around
                   * the enemy unit instead of just giving up and crashing. */
                  freelog(LOG_DEBUG,
                          "rescue plane: unit %d could not move to refuel point!",
                          punit->id);
              }

              if (alive) {
                /* Clear activity. Unit info will be sent in the end of
	         * the function. */
                unit_activity_handling(punit, ACTIVITY_IDLE);
                punit->goto_tile = NULL;

                if (!is_unit_being_refueled(punit)) {
                  carrier = find_transport_from_tile(punit, punit->tile);
                  if (carrier) {
                    put_unit_onto_transporter(punit, carrier);
                  }
                }

                notify_player(pplayer, punit->tile, E_UNIT_ORDERS, 
                              _("Your %s has returned to refuel."),
                              unit_name_translation(punit));
	      }
              pf_destroy_path(path);
              break;
            }
          } pf_iterator_end;
          pf_destroy_map(map);

          if (!alive) {
            /* Unit died trying to move to refuel point. */
            return;
	  }
        }
      }

      /* 5) Update fuel */
      punit->fuel--;

      /* 6) Automatically refuel air units in cities, airbases, and
       *    transporters (carriers). */
      if (is_unit_being_refueled(punit)) {
	punit->fuel = utype_fuel(unit_type(punit));
      }
    }
  } unit_list_iterate_safe_end;

  /* 7) Check if there are air units without fuel */
  unit_list_iterate_safe(pplayer->units, punit) {
    if (punit->fuel <= 0 && utype_fuel(unit_type(punit))) {
      notify_player(pplayer, punit->tile, E_UNIT_LOST_MISC, 
		       _("Your %s has run out of fuel."),
		       unit_name_translation(punit));
      wipe_unit(punit);
    } 
  } unit_list_iterate_safe_end;

  /* Send all updates. */
  unit_list_iterate(pplayer->units, punit) {
    send_unit_info(NULL, punit);
  } unit_list_iterate_end**
  add hitpoints to the unit, hp_gain_coord returns the amount to add
  united nations will speed up the process by 2 hp's / turn, means helicopters
  will actually not loose hp's every turn if player have that wonder.
  Units which have moved don't gain hp, except the United Nations and
  helicopter effects still occur.
*************/
static void unit_restore_hitpoints(struct unit *punit)
{
  bool was_lower;
  struct unit_class *class = unit_class(punit);
  struct city *pcity = tile_city(punit->tile);

  was_lower=(punit->hp < unit_type(punit)->hp);

  if(!punit->moved) {
    punit->hp+=hp_gain_coord(punit);
  }

  /* Bonus recovery HP (traditionally from the United Nations) */
  punit->hp += get_unit_bonus(punit, EFT_UNIT_RECOVER);

  if (!pcity && !tile_has_native_base(punit->tile, unit_type(punit))
      && punit->transported_by == -1) {
    punit->hp -= unit_type(punit)->hp * class->hp_loss_pct / 100;
  }

  if(punit->hp>=unit_type(punit)->hp) {
    punit->hp=unit_type(punit)->hp;
    if(was_lower&&punit->activity==ACTIVITY_SENTRY){
      set_unit_activity(punit,ACTIVITY_IDLE);
    }
  }
  if(punit->hp<0)
    punit->hp=0;

  punit->moved = FALSE;
  punit->paradropped = FALSE;
}
  
*****
  Move points are trivial, only modifiers to the base value is if it's
  sea units and the player has certain wonders/techs. Then add veteran
  bonus, if any.
***********/
static void unit_restore_movepoints(struct player *pplayer, struct unit *punit)
{
  punit->moves_left = unit_move_rate(punit);
  punit->done_moving = FALSE  iterate through all units and update them.
**********/
void update_unit_activities(struct player *pplayer)
{
  unit_list_iterate_safe(pplayer->units, punit)
    update_unit_activity(punit);
  unit_list_iterate_safe_end  returns how many hp's a unit will gain on this square
  depends on whether or not it's inside city or fortress.
  barracks will regen landunits completely
  airports will regen airunits  completely
  ports    will regen navalunits completely
  fortify will add a little extra.
***********/
static int hp_gain_coord(struct unit *punit)
{
  int hp = 0;
  const int base = unit_type(punit)->hp;

  /* Includes barracks (100%), fortress (25%), etc. */
  hp += base * get_unit_bonus(punit, EFT_HP_REGEN) / 100;

  if (tile_city(punit->tile)) {
    hp = MAX(hp, base / 3);
  }

  if (!unit_class(punit)->hp_loss_pct) {
    hp += (base + 9) / 10;
  }

  if (punit->activity == ACTIVITY_FORTIFIED) {
    hp += (base + 9) / 10;
  }

  return MAX(hp, 0)  Calculate the total amount of activity performed by all units on a tile
  for a given task.
**********/
static int total_activity(struct tile *ptile, enum unit_activity act)
{
  int total = 0;

  unit_list_iterate (ptile->units, punit)
    if (punit->activity == act) {
      total += punit->activity_count;
    }
  unit_list_iterate_end;
  return total  Calculate the total amount of activity performed by all units on a tile
  for a given task and target.
**********/
static int total_activity_targeted(struct tile *ptile, enum unit_activity act,
				   enum tile_special_type tgt)
{
  int total = 0;

  unit_list_iterate (ptile->units, punit)
    if ((punit->activity == act) && (punit->activity_target == tgt))
      total += punit->activity_count;
  unit_list_iterate_end;
  return total  Calculate the total amount of base building activity performed by all
  units on a tile for a given base.
**********/
static int total_activity_base(struct tile *ptile, Base_type_id base)
{
  int total = 0;

  unit_list_iterate (ptile->units, punit)
    if (punit->activity == ACTIVITY_BASE
        && punit->activity_base == base) {
      total += punit->activity_count;
    }
  unit_list_iterate_end;
  return total  Check the total amount of activity performed by all units on a tile
  for a given task.
**********/
static bool total_activity_done(struct tile *ptile, enum unit_activity act)
{
  return total_activity(ptile, act) >= tile_activity_time(act, ptile)*
  Maybe settler/worker gains a veteran level?
************/
static bool maybe_settler_become_veteran(struct unit *punit)
{
  if (punit->veteran + 1 >= MAX_VET_LEVELS
      || unit_type(punit)->veteran[punit->veteran].name[0] == '\0'
      || unit_has_type_flag(punit, F_NO_VETERAN)) {
    return FALSE;
  }
  if (unit_has_type_flag(punit, F_SETTLERS)
      && myrand(100) < game.work_veteran_chance[punit->veteran]) {
    punit->veteran++;
    return TRUE;
  }
  return FALSE;   Common notification for all experience levels.
**********/
void notify_unit_experience(struct unit *punit)
{
  if (!punit) {
    return;
  }

  notify_player(unit_owner(punit), unit_tile(punit), E_UNIT_BECAME_VET,
                /* TRANS: Your <unit> became ... */
                _("Your %s became more experienced!"),
                unit_name_translation(punit))  Pillages base from tile
**********/
static void unit_pillage_base(struct tile *ptile, struct base_type *pbase)
{
  if (territory_claiming_base(pbase)) {
    /* Clearing borders will take care of the vision providing
     * bases as well. */
    map_clear_border(ptile);
  } else if (pbase->vision_sq >= 0) {
    /* Base provides vision, but no borders. */
    struct player *owner = tile_owner(ptile);
    if (owner) {
      map_refog_circle(owner, ptile, pbase->vision_sq, -1,
                       game.info.vision_reveal_tiles, V_MAIN);
    }
  }
  tile_remove_base(ptile, pbase)  progress settlers in their current tasks, 
  and units that is pillaging.
  also move units that is on a goto.
  restore unit move points (information needed for settler tasks)
**********/
static void update_unit_activity(struct unit *punit)
{
  struct player *pplayer = unit_owner(punit);
  int id = punit->id;
  bool unit_activity_done = FALSE;
  enum unit_activity activity = punit->activity;
  struct tile *ptile = punit->tile;
  bool check_adjacent_units = FALSE;
  
  switch (activity) {
  case ACTIVITY_IDLE:
  case ACTIVITY_EXPLORE:
  case ACTIVITY_FORTIFIED:
  case ACTIVITY_GOTO:
  case ACTIVITY_PATROL_UNUSED:
  case ACTIVITY_UNKNOWN:
  case ACTIVITY_LAST:
    /*  We don't need the activity_count for the above */
    break;

  case ACTIVITY_FORTIFYING:
  case ACTIVITY_SENTRY:
    punit->activity_count += get_activity_rate_this_turn(punit);
    break;

  case ACTIVITY_POLLUTION:
  case ACTIVITY_ROAD:
  case ACTIVITY_MINE:
  case ACTIVITY_IRRIGATE:
  case ACTIVITY_FORTRESS:
  case ACTIVITY_RAILROAD:
  case ACTIVITY_PILLAGE:
  case ACTIVITY_TRANSFORM:
  case ACTIVITY_AIRBASE:
  case ACTIVITY_FALLOUT:
  case ACTIVITY_BASE:
    punit->activity_count += get_activity_rate_this_turn(punit);

    /* settler may become veteran when doing something useful */
    if (maybe_settler_become_veteran(punit)) {
      notify_unit_experience(punit);
    }
    break;
  };

  unit_restore_movepoints(pplayer, punit);

  switch (activity) {
  case ACTIVITY_IDLE:
  case ACTIVITY_FORTIFIED:
  case ACTIVITY_FORTRESS:
  case ACTIVITY_SENTRY:
  case ACTIVITY_GOTO:
  case ACTIVITY_UNKNOWN:
  case ACTIVITY_AIRBASE:
  case ACTIVITY_FORTIFYING:
  case ACTIVITY_PATROL_UNUSED:
  case ACTIVITY_LAST:
    /* no default, ensure all handled */
    break;

  case ACTIVITY_EXPLORE:
    do_explore(punit);
    return;

  case ACTIVITY_PILLAGE:
    if (punit->activity_target == S_LAST) { /* case for old save files */
      if (punit->activity_count >= 1) {
        struct base_type *first_base = NULL;
        enum tile_special_type what;

        base_type_iterate(pbase) {
          if (tile_has_base(ptile, pbase)) {
            if (pbase->pillageable) {
              first_base = pbase;
              break;
            }
          }
        } base_type_iterate_end;

        what = get_preferred_pillage(get_tile_infrastructure_set(ptile, NULL),
                                     first_base);

	if (what != S_LAST) {
          if (what == S_PILLAGE_BASE) {
            unit_pillage_base(ptile, first_base);
          } else {
            tile_clear_special(ptile, what);
          }
	  update_tile_knowledge(ptile);
	  set_unit_activity(punit, ACTIVITY_IDLE);
	  check_adjacent_units = TRUE;
	}

	/* Change vision if effects have changed. */
	unit_list_refresh_vision(ptile->units);
      }
    }
    else if (total_activity_targeted(ptile, ACTIVITY_PILLAGE, 
                                     punit->activity_target) >= 1) {
      enum tile_special_type what_pillaged = punit->activity_target;
      struct player *victim;

      if (what_pillaged == S_PILLAGE_BASE) {
        base_type_iterate(pbase) {
          if (tile_has_base(ptile, pbase)) {
            if (pbase->pillageable) {
              /* Remove first pillageable base */
              unit_pillage_base(ptile, pbase);
              break; /* but only first */
            }
          }
        } base_type_iterate_end;
      } else {
        tile_clear_special(ptile, what_pillaged);
      }
      unit_list_iterate (ptile->units, punit2) {
        if ((punit2->activity == ACTIVITY_PILLAGE) &&
	    (punit2->activity_target == what_pillaged)) {
	  set_unit_activity(punit2, ACTIVITY_IDLE);
	  send_unit_info(NULL, punit2);
	}
      } unit_list_iterate_end;
      update_tile_knowledge(ptile);

      victim = tile_owner(ptile);
      if (victim->ai_funcs.incident_pillage) {
        victim->ai_funcs.incident_pillage(unit_owner(punit), victim);
      }

      /* Change vision if effects have changed. */
      unit_list_refresh_vision(ptile->units);
    }
    break;

  case ACTIVITY_POLLUTION:
    if (total_activity_done(ptile, ACTIVITY_POLLUTION)) {
      tile_clear_special(ptile, S_POLLUTION);
      unit_activity_done = TRUE;
    }
    break;

  case ACTIVITY_FALLOUT:
    if (total_activity_done(ptile, ACTIVITY_FALLOUT)) {
      tile_clear_special(ptile, S_FALLOUT);
      unit_activity_done = TRUE;
    }
    break;

  case ACTIVITY_BASE:
    if (total_activity_base(ptile, punit->activity_base)
        >= tile_activity_base_time(ptile, punit->activity_base)) {
      struct base_type *new_base = base_by_number(punit->activity_base);

      base_type_iterate(old_base) {
        if (tile_has_base(ptile, old_base)
            && !can_bases_coexist(old_base, new_base)) {
          if (territory_claiming_base(old_base)) {
            map_clear_border(ptile);
            map_claim_ownership(ptile, NULL, NULL);
          } else if (old_base->vision_sq >= 0) {
              /* Base provides vision, but no borders. */
              struct player *owner = tile_owner(ptile);
              if (owner) {
                map_refog_circle(owner, ptile, old_base->vision_sq, -1,
                                 game.info.vision_reveal_tiles, V_MAIN);
              }
          }
          tile_remove_base(ptile, old_base);
        }
      } base_type_iterate_end;

      tile_add_base(ptile, new_base);

      /* Watchtower might become effective
       * FIXME: Reqs on other specials will not be updated immediately. */
      unit_list_refresh_vision(ptile->units);

      /* Claim base if it has "ClaimTerritory" flag */
      if (territory_claiming_base(new_base)) {
        map_claim_ownership(ptile, unit_owner(punit), ptile);
        map_claim_border(ptile, unit_owner(punit));
        city_thaw_workers_queue();
        city_refresh_queue_processing();
      } else if (new_base->vision_sq > 0) {
        struct player *owner = tile_owner(ptile);
        if (owner) {
          map_refog_circle(owner, ptile, -1, new_base->vision_sq,
                           game.info.vision_reveal_tiles, V_MAIN);
        }
      }

      unit_activity_done = TRUE;
    }
    break;

  case ACTIVITY_IRRIGATE:
    if (total_activity_done(ptile, ACTIVITY_IRRIGATE)) {
      struct terrain *old = tile_terrain(ptile);

      tile_apply_activity(ptile, ACTIVITY_IRRIGATE);
      check_terrain_change(ptile, old);
      unit_activity_done = TRUE;
    }
    break;

  case ACTIVITY_MINE:
  case ACTIVITY_TRANSFORM:
    if (total_activity_done(ptile, activity)) {
      struct terrain *old = tile_terrain(ptile);

      tile_apply_activity(ptile, activity);
      check_terrain_change(ptile, old);
      unit_activity_done = TRUE;
      check_adjacent_units = TRUE;
    }
    break;

  case ACTIVITY_ROAD:
    if (total_activity (ptile, ACTIVITY_ROAD)
	+ total_activity (ptile, ACTIVITY_RAILROAD)
        >= tile_activity_time(ACTIVITY_ROAD, ptile)) {
      tile_set_special(ptile, S_ROAD);
      unit_activity_done = TRUE;
    }
    break;

  case ACTIVITY_RAILROAD:
    if (total_activity_done(ptile, ACTIVITY_RAILROAD)) {
      tile_set_special(ptile, S_RAILROAD);
      unit_activity_done = TRUE;
    }
    break;
  };

  if (unit_activity_done) {
    update_tile_knowledge(ptile);
    unit_list_iterate (ptile->units, punit2) {
      if (punit2->activity == activity) {
	set_unit_activity(punit2, ACTIVITY_IDLE);
	send_unit_info(NULL, punit2);
      }
    } unit_list_iterate_end;
  }

  /* Some units nearby can not continue irrigating */
  if (check_adjacent_units) {
    adjc_iterate(ptile, ptile2) {
      unit_list_iterate(ptile2->units, punit2) {
        if (!can_unit_continue_current_activity(punit2)) {
          unit_activity_handling(punit2, ACTIVITY_IDLE);
        }
      } unit_list_iterate_end;
    } adjc_iterate_end;
  }

  if (activity == ACTIVITY_FORTIFYING) {
    if (punit->activity_count >= 1) {
      set_unit_activity(punit,ACTIVITY_FORTIFIED);
    }
  }

  if (game_find_unit_by_number(id) && unit_has_orders(punit)) {
    if (!execute_orders(punit)) {
      /* Unit died. */
      return;
    }
  }

  if (game_find_unit_by_number(id)) {
    send_unit_info(NULL, punit);
  }

  unit_list_iterate(ptile->units, punit2) {
    if (!can_unit_continue_current_activity(punit2))
    {
      unit_activity_handling(punit2, ACTIVITY_IDLE);
    }
  } unit_list_iterate_endenum goto_move_restriction get_activity_move_restriction(enum unit_activity activity)
{
  enum goto_move_restriction restr;

  switch (activity) {
  case ACTIVITY_IRRIGATE:
    restr = GOTO_MOVE_CARDINAL_ONLY;
    break;
  case ACTIVITY_POLLUTION:
  case ACTIVITY_ROAD:
  case ACTIVITY_MINE:
  case ACTIVITY_FORTRESS:
  case ACTIVITY_RAILROAD:
  case ACTIVITY_PILLAGE:
  case ACTIVITY_TRANSFORM:
  case ACTIVITY_AIRBASE:
  case ACTIVITY_FALLOUT:
    restr = GOTO_MOVE_STRAIGHTEST;
    break;
  default:
    restr = GOTO_MOVE_ANY;
    break;
  }

  return (restr)static bool find_a_good_partisan_spot(struct city *pcity,
				      struct unit_type *u_type,
				      struct tile **dst_tile)
{
  struct tile *pcenter = city_tile(pcity);
  struct player *powner = city_owner(pcity);
  int bestvalue = 0;

  /* coords of best tile in arg pointers */
  city_tile_iterate(pcenter, ptile) {
    int value;

    if (is_ocean_tile(ptile)) {
      continue;
    }

    if (NULL != tile_city(ptile)) {
      continue;
    }

    if (0 < unit_list_size(ptile->units)) {
      continue;
    }

    /* City has not changed hands yet; see place_partisans(). */
    value = get_virtual_defense_power(NULL, u_type, powner,
				      ptile, FALSE, 0);
    value *= 10;

    if (tile_continent(ptile) != tile_continent(pcenter)) {
      value /= 2;
    }

    value -= myrand(value/3);

    if (value > bestvalue) {
      *dst_tile = ptile;
      bestvalue = value;
    }
  } city_tile_iterate_end;

  return bestvalue >  finds a spot around pcity and place a partisan.
**********/
static void place_partisans(struct city *pcity, int count)
{
  struct tile *ptile = NULL;
  struct unit_type *u_type = get_role_unit(L_PARTISAN, 0);

  while ((count--) > 0 && find_a_good_partisan_spot(pcity, u_type, &ptile)) {
    struct unit *punit;

    punit = create_unit(city_owner(pcity), ptile, u_type, 0, 0, -1);
    if (can_unit_do_activity(punit, ACTIVITY_FORTIFYING)) {
      punit->activity = ACTIVITY_FORTIFIED; /* yes; directly fortified */
      send_unit_info(NULL, punit);
    }
  }***********
  if requirements to make partisans when a city is conquered is fullfilled
  this routine makes a lot of partisans based on the city's size.
  To be candidate for partisans the following things must be satisfied:
  1) Guerilla warfare must be known by atleast 1 player
  2) The owner of the city is the original player.
  3) The player must know about communism and gunpowder
  4) the player must run either a democracy or a communist society.
**********/
void make_partisans(struct city *pcity)
{
  int partisans;

  if (num_role_units(L_PARTISAN) <= 0
      || pcity->original != city_owner(pcity)
      || get_city_bonus(pcity, EFT_INSPIRE_PARTISANS) <= 0) {
    return;
  }
  
  partisans = myrand(1 + pcity->size/2) + 1;
  if (partisans > 8) 
    partisans = 8;
  
  place_partisans(pcity,partisans)Are there dangerous enemies at or adjacent to (x, y)?

N.B. This function should only be used by (cheating) AI, as it iterates 
through all units stacked on the tiles, an info not normally available 
to the human player.
**********/
bool enemies_at(struct unit *punit, struct tile *ptile)
{
  int a = 0, d, db;
  struct player *pplayer = unit_owner(punit);
  struct city *pcity = tile_city(ptile);

  if (pcity && pplayers_allied(city_owner(pcity), unit_owner(punit))
      && !is_non_allied_unit_tile(ptile, pplayer)) {
    /* We will be safe in a friendly city */
    return FALSE;
  }

  /* Calculate how well we can defend at (x,y) */
  db = 10 + tile_terrain(ptile)->defense_bonus / 10;
  if (tile_has_special(ptile, S_RIVER))
    db += (db * terrain_control.river_defense_bonus) / 100;
  d = unit_def_rating_basic_sq(punit) * db;

  adjc_iterate(ptile, ptile1) {
    if (ai_handicap(pplayer, H_FOG)
	&& !map_is_known_and_seen(ptile1, unit_owner(punit), V_MAIN)) {
      /* We cannot see danger at (ptile1) => assume there is none */
      continue;
    }
    unit_list_iterate(ptile1->units, enemy) {
      if (pplayers_at_war(unit_owner(enemy), unit_owner(punit)) 
          && can_unit_attack_unit_at_tile(enemy, punit, ptile)
          && can_unit_attack_all_at_tile(enemy, ptile)) {
	a += unit_att_rating(enemy);
	if ((a * a * 10) >= d) {
          /* The enemies combined strength is too big! */
          return TRUE;
        }
      }
    } unit_list_iterate_end;
  } adjc_iterate_end;

  return FALSE; /* as good a quick'n'dirty should be -- Syela */***********
Teleport punit to city at cost specified.  Returns success.
(If specified cost is -1, then teleportation costs all movement.)
                         - Kris Bubendorfer
**********/
bool teleport_unit_to_city(struct unit *punit, struct city *pcity,
			  int move_cost, bool verbose)
{
  struct tile *src_tile = punit->tile, *dst_tile = pcity->tile;

  if (city_owner(pcity) == unit_owner(punit)){
    freelog(LOG_VERBOSE, "Teleported %s %s from (%d,%d) to %s",
	    nation_rule_name(nation_of_unit(punit)),
	    unit_rule_name(punit),
	    TILE_XY(src_tile),
	    city_name(pcity));
    if (verbose) {
      notify_player(unit_owner(punit), pcity->tile, E_UNIT_RELOCATED,
		       _("Teleported your %s to %s."),
		       unit_name_translation(punit),
		       city_name(pcity));
    }

    /* Silently free orders since they won't be applicable anymore. */
    free_unit_orders(punit);

    if (move_cost == -1)
      move_cost = punit->moves_left;
    move_unit(punit, dst_tile, move_cost);
    return TRUE;
  }
  return FALSE  Move or remove a unit due to stack conflicts. This function will try to
  find a random safe tile within a two tile distance of the unit's current
  tile and move the unit there. If no tiles are found, the unit is
  disbanded. If 'verbose' is TRUE, a message is sent to the unit owner
  regarding what happened.
**********/
void bounce_unit(struct unit *punit, bool verbose)
{
  struct player *pplayer;
  struct tile *punit_tile;
  int count = 0;

  /* I assume that there are no topologies that have more than
   * (2d + 1)^2 tiles in the "square" of "radius" d. */
  const int DIST = 2;
  struct tile *tiles[(2 * DIST + 1) * (2 * DIST + 1)];

  if (!punit) {
    return;
  }

  pplayer = unit_owner(punit);
  punit_tile = unit_tile(punit);

  square_iterate(punit_tile, DIST, ptile) {
    if (count >= ARRAY_SIZE(tiles)) {
      break;
    }
    if (can_unit_survive_at_tile(punit, ptile)
        && !is_non_allied_city_tile(ptile, pplayer)
        && !is_non_allied_unit_tile(ptile, pplayer)) {
      tiles[count++] = ptile;
    }
  } square_iterate_end;

  if (count > 0) {
    struct tile *ptile = tiles[myrand(count)];

    if (verbose) {
      /* TRANS: A unit is moved to resolve stack conflicts. */
      notify_player(pplayer, ptile, E_UNIT_RELOCATED, _("Moved your %s."),
                    unit_name_translation(punit));
    }
    move_unit(punit, ptile, 0);
    return;
  }

  /* Didn't find a place to bounce the unit, just disband it. */
  if (verbose) {
    /* TRANS: A unit is disbanded to resolve stack conflicts. */
    notify_player(pplayer, punit_tile, E_UNIT_LOST_MISC,
                  _("Disbanded your %s."),
                  unit_name_translation(punit));
  }
  wipe_unit(punit);
}
  Throw pplayer's units from non allied cities

  If verbose is true, pplayer gets messages about where each units goes.
**********/
static void throw_units_from_illegal_cities(struct player *pplayer,
                                           bool verbose)
{
  unit_list_iterate_safe(pplayer->units, punit) {
    struct tile *ptile = punit->tile;
    struct city *pcity = tile_city(ptile);

    if (NULL != pcity && !pplayers_allied(city_owner(pcity), pplayer)) {
      bounce_unit(punit, verbose);
    }
  } unit_list_iterate_safe_end;     For each pplayer's unit, check if we stack illegally, if so,
  bounce both players' units. If on ocean tile, bounce everyone but ships
  to avoid drowning. This function assumes that cities are clean.

  If verbose is true, the unit owner gets messages about where each
  units goes.
**********/
static void resolve_stack_conflicts(struct player *pplayer,
                                    struct player *aplayer, bool verbose)
{
  unit_list_iterate_safe(pplayer->units, punit) {
    struct tile *ptile = punit->tile;

    if (is_non_allied_unit_tile(ptile, pplayer)) {
      unit_list_iterate_safe(ptile->units, aunit) {
        if (unit_owner(aunit) == pplayer
            || unit_owner(aunit) == aplayer
            || !can_unit_survive_at_tile(aunit, ptile)) {
          bounce_unit(aunit, verbose);
        }
      } unit_list_iterate_safe_end;
    }    
  } unit_list_iterate_safe_end;
}
				
****
  When in civil war or an alliance breaks there will potentially be units 
  from both sides coexisting on the same squares.  This routine resolves 
  this by first bouncing off non-allied units from their cities, then by 
  bouncing both players' units in now illegal multiowner stacks.  To avoid
  drowning due to removal of transports, we bounce everyone (including
  third parties' units) from ocean tiles.

  If verbose is true, the unit owner gets messages about where each
  units goes.
**********/
void resolve_unit_stacks(struct player *pplayer, struct player *aplayer,
                         bool verbose)
{
  throw_units_from_illegal_cities(pplayer, verbose);
  throw_units_from_illegal_cities(aplayer, verbose);
  
  resolve_stack_conflicts(pplayer, aplayer, verbose);
  resolve_stack_conflicts(aplayer, pplayer, verbose)**
  When two players cancel an alliance, a lot of units that were visible may
  no longer be visible (this includes units in transporters and cities).
  Call this function to inform the clients that these units are no longer
  visible.  Note that this function should be called _after_
  resolve_unit_stacks().
************/
void remove_allied_visibility(struct player* pplayer, struct player* aplayer)
{
  unit_list_iterate(aplayer->units, punit) {
    /* We don't know exactly which units have been hidden.  But only a unit
     * whose tile is visible but who aren't visible themselves are
     * candidates.  This solution just tells the client to drop all such
     * units.  If any of these are unknown to the client the client will
     * just ignore them. */
    if (map_is_known_and_seen(punit->tile, pplayer, V_MAIN) &&
        !can_player_see_unit(pplayer, punit)) {
      unit_goes_out_of_sight(pplayer, punit);
    }
  } unit_list_iterate_end;

  city_list_iterate(aplayer->cities, pcity) {
    /* The player used to know what units were in these cities.  Now that he
     * doesn't, he needs to get a new short city packet updating the
     * occupied status. */
    if (map_is_known_and_seen(pcity->tile, pplayer, V_MAIN)) {
      send_city_info(pplayer, pcity);
    }
  } city_list_iterate_end Is unit being refueled in its current position
**********/
bool is_unit_being_refueled(const struct unit *punit)
{
  return (punit->transported_by != -1                   /* Carrier */
          || tile_city(punit->tile)                 /* City    */
          || tile_has_native_base(punit->tile,
                                  unit_type(punit))); /* Airbase */***********/
bool is_airunit_refuel_point(struct tile *ptile, struct player *pplayer,
			     const struct unit_type *type,
			     bool unit_is_on_carrier)
{
  int cap;
  struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);

  if (!is_non_allied_unit_tile(ptile, pplayer)) {
    if (is_allied_city_tile(ptile, pplayer)) {
      return TRUE;
    }

    base_type_iterate(pbase) {
      if (BV_ISSET(plrtile->bases, base_index(pbase))
          && is_native_base_to_utype(pbase, type)) {
        return TRUE;
      }
    } base_type_iterate_end;
  }

  cap = unit_class_transporter_capacity(ptile, pplayer, utype_class(type));

  if (unit_is_on_carrier) {
    cap++;
  }

  return cap >  Really upgrades a single unit.

  Before calling this function you should use unit_upgrade to test if
  this is possible.

  is_free: Leonardo upgrade for free, in all other cases the unit
  owner has to pay

  Note that this function is strongly tied to unit.c:test_unit_upgrade().
**********/
void upgrade_unit(struct unit *punit, struct unit_type *to_unit,
		  bool is_free)
{
  struct player *pplayer = unit_owner(punit);
  int old_mr = unit_move_rate(punit), old_hp = unit_type(punit)->hp;

  assert(test_unit_upgrade(punit, is_free) == UR_OK);

  if (!is_free) {
    pplayer->economic.gold -=
	unit_upgrade_price(pplayer, unit_type(punit), to_unit);
  }

  punit->utype = to_unit;

  /* Scale HP and MP, rounding down.  Be careful with integer arithmetic,
   * and don't kill the unit.  unit_move_rate is used to take into account
   * global effects like Magellan's Expedition. */
  punit->hp = MAX(punit->hp * unit_type(punit)->hp / old_hp, 1);
  punit->moves_left = punit->moves_left * unit_move_rate(punit) / old_mr;

  if (utype_has_flag(to_unit, F_NO_VETERAN)) {
    punit->veteran = 0;
  } else if (is_free) {
    punit->veteran = MAX(punit->veteran
                         - game.info.autoupgrade_veteran_loss, 0);
  } else {
    punit->veteran = MAX(punit->veteran
                         - game.info.upgrade_veteran_loss, 0);
  }

  /* update unit upkeep */
  city_units_upkeep(game_find_city_by_number(punit->homecity));

  conn_list_do_buffer(pplayer->connections);

  unit_refresh_vision(punit);

  send_unit_info(NULL, punit);
  conn_list_do_unbuffer(pplayer->connections) 
  Wrapper of the below
*********/
struct unit *create_unit(struct player *pplayer, struct tile *ptile, 
			 struct unit_type *type, int veteran_level, 
                         int homecity_id, int moves_left)
{
  return create_unit_full(pplayer, ptile, type, veteran_level, homecity_id, 
                          moves_left, -1, NULL)  Creates a unit, and set it's initial values, and put it into the right 
  lists.
  If moves_left is less than zero, unit will get max moves.
**********/
struct unit *create_unit_full(struct player *pplayer, struct tile *ptile,
			      struct unit_type *type, int veteran_level, 
                              int homecity_id, int moves_left, int hp_left,
			      struct unit *ptrans)
{
  struct unit *punit = create_unit_virtual(pplayer, NULL, type, veteran_level);
  struct city *pcity;

  /* Register unit */
  punit->id = identity_number();
  idex_register_unit(punit);

  assert(ptile != NULL);
  punit->tile = ptile;

  pcity = game_find_city_by_number(homecity_id);
  if (utype_has_flag(type, F_NOHOME)) {
    punit->homecity = 0; /* none */
  } else {
    punit->homecity = homecity_id;
  }

  if (hp_left >= 0) {
    /* Override default full HP */
    punit->hp = hp_left;
  }

  if (moves_left >= 0) {
    /* Override default full MP */
    punit->moves_left = MIN(moves_left, unit_move_rate(punit));
  }

  if (ptrans) {
    /* Set transporter for unit. */
    punit->transported_by = ptrans->id;
  } else {
    assert(!ptile || can_unit_exist_at_tile(punit, ptile));
  }

  /* Assume that if moves_left < 0 then the unit is "fresh",
   * and not moved; else the unit has had something happen
   * to it (eg, bribed) which we treat as equivalent to moved.
   * (Otherwise could pass moved arg too...)  --dwp */
  punit->moved = (moves_left >= 0);

  unit_list_prepend(pplayer->units, punit);
  unit_list_prepend(ptile->units, punit);
  if (pcity && !utype_has_flag(type, F_NOHOME)) {
    assert(city_owner(pcity) == pplayer);
    unit_list_prepend(pcity->units_supported, punit);
    /* Refresh the unit's homecity. */
    city_refresh(pcity);
    send_city_info(pplayer, pcity);
  }

  punit->server.vision = vision_new(pplayer, ptile);
  unit_refresh_vision(punit);

  send_unit_info(NULL, punit);
  maybe_make_contact(ptile, unit_owner(punit));
  wakeup_neighbor_sentries(punit);

  /* update unit upkeep */
  city_units_upkeep(game_find_city_by_number(homecity_id));

  /* The unit may have changed the available tiles in nearby cities. */
  city_map_update_tile_now(ptile);
  sync_cities();

  /* Initialize aiferry stuff for new unit */
  aiferry_init_ferry(punit);

  return punitWe remove the unit and see if it's disappearance has affected the homecity
and the city it was in.
**********/
static void server_remove_unit(struct unit *punit)
{
  struct tile *ptile = punit->tile;
  struct city *pcity = tile_city(ptile);
  struct city *phomecity = game_find_city_by_number(punit->homecity);

#ifndef NDEBUG
  unit_list_iterate(ptile->units, pcargo) {
    assert(pcargo->transported_by != punit->id);
  } unit_list_iterate_end;
#endif

  /* Since settlers plot in new cities in the minimap before they
     are built, so that no two settlers head towards the same city
     spot, we need to ensure this reservation is cleared should
     the settler disappear on the way. */
  if (punit->ai.ai_role != AIUNIT_NONE) {
    ai_unit_new_role(punit, AIUNIT_NONE, NULL);
  }

  conn_list_iterate(game.est_connections, pconn) {
    if ((NULL == pconn->playing && pconn->observer)
	|| (NULL != pconn->playing
            && map_is_known_and_seen(ptile, pconn->playing, V_MAIN))) {
      /* FIXME: this sends the remove packet to all players, even those who
       * can't see the unit.  This potentially allows some limited cheating.
       * However fixing it requires changes elsewhere since sometimes the
       * client is informed about unit disappearance only after the unit
       * disappears.  For instance when building a city the settler unit
       * is wiped only after the city is built...at which point the settler
       * is already "hidden" inside the city and can_player_see_unit would
       * return FALSE.  One possible solution is to have a bv_player for
       * each unit to record which players (clients) currently know about
       * the unit; then we could just use a BV_TEST here and not have to
       * worry about any synchronization problems. */
      dsend_packet_unit_remove(pconn, punit->id);
    }
  } conn_list_iterate_end;

  vision_clear_sight(punit->server.vision);
  vision_free(punit->server.vision);
  punit->server.vision = NULL;

  /* check if this unit had F_GAMELOSS flag */
  if (unit_has_type_flag(punit, F_GAMELOSS) && unit_owner(punit)->is_alive) {
    notify_conn(game.est_connections, ptile, E_UNIT_LOST_MISC,
                   _("Unable to defend %s, %s has lost the game."),
                   unit_name_translation(punit),
                   player_name(unit_owner(punit)));
    notify_player(unit_owner(punit), ptile, E_GAME_END,
		  _("Losing %s meant losing the game! "
                  "Be more careful next time!"),
                  unit_name_translation(punit));
    unit_owner(punit)->is_dying = TRUE;
  }

  game_remove_unit(punit);
  punit = NULL;

  /* This unit may have blocked tiles of adjacent cities. Update them. */
  city_map_update_tile_now(ptile);
  sync_cities();

  if (phomecity) {
    city_refresh(phomecity);
    send_city_info(city_owner(phomecity), phomecity);
  }

  if (pcity && pcity != phomecity) {
    city_refresh(pcity);
    send_city_info(city_owner(pcity), pcity);
  }

  if (pcity && unit_list_size(ptile->units) == 0) {
    /* The last unit in the city was killed: update the occupied flag. */
    send_city_info(NULL, pcity)  Handle units destroyed when their transport is destroyed
**********/
static void unit_lost_with_transport(const struct player *pplayer,
                                     struct unit *pcargo,
                                     struct unit_type *ptransport)
{
  notify_player(pplayer, pcargo->tile, E_UNIT_LOST_MISC,
                _("%s lost when %s was lost."),
                unit_name_translation(pcargo),
                utype_name_translation(ptransport));
  server_remove_unit(pcargo)  Remove the unit, and passengers if it is a carrying any. Remove the 
  _minimum_ number, eg there could be another boat on the square.
**********/
void wipe_unit(struct unit *punit)
{
  struct tile *ptile = punit->tile;
  struct player *pplayer = unit_owner(punit);
  struct unit_type *putype_save = unit_type(punit); /* for notify messages */
  int drowning = 0;
  int saved_id = punit->id;
  int homecity_id = punit->homecity;

  /* First pull all units off of the transporter. */
  if (get_transporter_capacity(punit) > 0) {
    unit_list_iterate(ptile->units, pcargo) {
      if (pcargo->transported_by == punit->id) {
	/* Could use unload_unit_from_transporter here, but that would
	 * call send_unit_info for the transporter unnecessarily. */
	pull_unit_from_transporter(pcargo, punit);
        if (!can_unit_exist_at_tile(pcargo, ptile)) {
          drowning++;
        }
	if (pcargo->activity == ACTIVITY_SENTRY) {
	  /* Activate sentried units - like planes on a disbanded carrier.
	   * Note this will activate ground units even if they just change
	   * transporter. */
	  set_unit_activity(pcargo, ACTIVITY_IDLE);
	}
        if (!can_unit_exist_at_tile(pcargo, ptile)) {
          drowning++;
          /* No need for send_unit_info() here. Unit info will be sent
           * when it is assigned to a new transport or it will be removed. */
        } else {
          send_unit_info(NULL, pcargo);
        }
      }
    } unit_list_iterate_end;
  }

  script_signal_emit("unit_lost", 2,
                     API_TYPE_UNIT, punit,
                     API_TYPE_PLAYER, pplayer);

  if (unit_alive(saved_id)) {
    /* Now remove the unit. */
    server_remove_unit(punit);
  }

  /* update unit upkeep */
  city_units_upkeep(game_find_city_by_number(homecity_id));

  /* Finally reassign, bounce, or destroy all units that cannot exist at this
   * location without transport. */
  if (drowning) {
    struct city *pcity = NULL;

    /* First save undisbandable and gameloss units */
    unit_list_iterate_safe(ptile->units, pcargo) {
      if (pcargo->transported_by == -1
          && !can_unit_exist_at_tile(pcargo, ptile)
          && (unit_has_type_flag(pcargo, F_UNDISBANDABLE)
           || unit_has_type_flag(pcargo, F_GAMELOSS))) {
        struct unit *ptransport = find_transport_from_tile(pcargo, ptile);
        if (ptransport != NULL) {
          put_unit_onto_transporter(pcargo, ptransport);
          send_unit_info(NULL, pcargo);
        } else {
	  if (unit_has_type_flag(pcargo, F_UNDISBANDABLE)) {
	    pcity = find_closest_owned_city(unit_owner(pcargo),
					    pcargo->tile, TRUE, NULL);
	    if (pcity && teleport_unit_to_city(pcargo, pcity, 0, FALSE)) {
	      notify_player(pplayer, ptile, E_UNIT_RELOCATED,
                            _("%s escaped the destruction of %s, and "
                              "fled to %s."),
                            unit_name_translation(pcargo),
                            utype_name_translation(putype_save),
                            city_name(pcity));
	    }
          }
          if (!unit_has_type_flag(pcargo, F_UNDISBANDABLE) || !pcity) {
            unit_lost_with_transport(pplayer, pcargo, putype_save);
          }
        }

        drowning--;
        if (!drowning) {
          break;
        }
      }
    } unit_list_iterate_safe_end;
  }

  /* Then other units */
  if (drowning) {
    unit_list_iterate_safe(ptile->units, pcargo) {
      if (pcargo->transported_by == -1
          && !can_unit_exist_at_tile(pcargo, ptile)) {
        struct unit *ptransport = find_transport_from_tile(pcargo, ptile);

        if (ptransport != NULL) {
          put_unit_onto_transporter(pcargo, ptransport);
          send_unit_info(NULL, pcargo);
        } else {
          unit_lost_with_transport(pplayer, pcargo, putype_save);
        }

        drowning--;
        if (!drowning) {
          break;
        }
      }
    } unit_list_iterate_safe_end  Called when one unit kills another in combat (this function is only
  called in one place).  It handles all side effects including
  notifications and killstack.
**********/
void kill_unit(struct unit *pkiller, struct unit *punit, bool vet)
{
  struct player *pvictim = unit_owner(punit);
  struct player *pvictor = unit_owner(pkiller);
  int ransom, unitcount = 0;

  /* barbarian leader ransom hack */
  if( is_barbarian(pvictim) && unit_has_type_role(punit, L_BARBARIAN_LEADER)
      && (unit_list_size(punit->tile->units) == 1)
      && uclass_has_flag(unit_class(pkiller), UCF_COLLECT_RANSOM)) {
    /* Occupying units can collect ransom if leader is alone in the tile */
    ransom = (pvictim->economic.gold >= game.info.ransom_gold) 
             ? game.info.ransom_gold : pvictim->economic.gold;
    notify_player(pvictor, pkiller->tile, E_UNIT_WIN_ATT,
		     _("Barbarian leader captured, %d gold ransom paid."),
                     ransom);
    pvictor->economic.gold += ransom;
    pvictim->economic.gold -= ransom;
    send_player_info(pvictor, NULL);   /* let me see my new gold :-) */
    unitcount = 1;
  }

  if (unitcount == 0) {
    unit_list_iterate(punit->tile->units, vunit)
      if (pplayers_at_war(pvictor, unit_owner(vunit)))
	unitcount++;
    unit_list_iterate_end;
  }

  if (!is_stack_vulnerable(punit->tile) || unitcount == 1) {
    notify_player(pvictor, pkiller->tile, E_UNIT_WIN_ATT,
		  /* TRANS: "... Cannon ... the Polish Destroyer." */
		  _("Your attacking %s succeeded against the %s %s!"),
		  unit_name_translation(pkiller),
		  nation_adjective_for_player(pvictim),
		  unit_name_translation(punit));
    if (vet) {
      notify_unit_experience(pkiller);
    }
    notify_player(pvictim, punit->tile, E_UNIT_LOST_DEF,
		  /* TRANS: "Cannon ... the Polish Destroyer." */
		  _("%s lost to an attack by the %s %s."),
		  unit_name_translation(punit),
		  nation_adjective_for_player(pvictor),
		  unit_name_translation(pkiller));

    wipe_unit(punit);
  } else { /* unitcount > 1 */
    int i;
    int num_killed[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
    struct unit *other_killed[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];

    assert(unitcount > 1);

    /* initialize */
    for (i = 0; i<MAX_NUM_PLAYERS+MAX_NUM_BARBARIANS; i++) {
      num_killed[i] = 0;
      other_killed[i] = NULL;
    }

    /* count killed units */
    unit_list_iterate(punit->tile->units, vunit) {
      struct player *vplayer = unit_owner(vunit);
      if (pplayers_at_war(pvictor, vplayer)) {
	num_killed[player_index(vplayer)]++;
	if (vunit != punit) {
	  other_killed[player_index(vplayer)] = vunit;
	  other_killed[player_index(pvictor)] = vunit;
	}
      }
    } unit_list_iterate_end;

    /* Inform the destroyer: lots of different cases here! */
    notify_player(pvictor, pkiller->tile, E_UNIT_WIN_ATT,
		  /* TRANS: "... Cannon ... the Polish Destroyer ...." */
		  PL_("Your attacking %s succeeded against the %s %s "
		      "(and %d other unit)!",
		      "Your attacking %s succeeded against the %s %s "
		      "(and %d other units)!", unitcount - 1),
		  unit_name_translation(pkiller),
		  nation_adjective_for_player(pvictim),
		  unit_name_translation(punit),
		  unitcount - 1);
    if (vet) {
      notify_unit_experience(pkiller);
    }

    /* inform the owners: this only tells about owned units that were killed.
     * there may have been 20 units who died but if only 2 belonged to the
     * particular player they'll only learn about those.
     *
     * Also if a large number of units die you don't find out what type
     * they all are. */
    for (i = 0; i<MAX_NUM_PLAYERS+MAX_NUM_BARBARIANS; i++) {
      if (num_killed[i] == 1) {
	if (i == player_index(pvictim)) {
	  assert(other_killed[i] == NULL);
	  notify_player(player_by_number(i), punit->tile, E_UNIT_LOST_DEF,
			/* TRANS: "Cannon ... the Polish Destroyer." */
			_("%s lost to an attack by the %s %s."),
			unit_name_translation(punit),
			nation_adjective_for_player(pvictor),
			unit_name_translation(pkiller));
	} else {
	  assert(other_killed[i] != punit);
	  notify_player(player_by_number(i), punit->tile, E_UNIT_LOST_DEF,
			/* TRANS: "Cannon lost when the Polish Destroyer
			 * attacked the German Musketeers." */
			_("%s lost when the %s %s attacked the %s %s."),
			unit_name_translation(other_killed[i]),
			nation_adjective_for_player(pvictor),
			unit_name_translation(pkiller),
			nation_adjective_for_player(pvictim),
			unit_name_translation(punit));
	}
      } else if (num_killed[i] > 1) {
	if (i == player_index(pvictim)) {
	  int others = num_killed[i] - 1;

	  if (others == 1) {
	    notify_player(player_by_number(i), punit->tile, E_UNIT_LOST_DEF,
			  /* TRANS: "Musketeers (and Cannon) lost to an
			   * attack from the Polish Destroyer." */
			  _("%s (and %s) lost to an attack from the %s %s."),
			  unit_name_translation(punit),
			  unit_name_translation(other_killed[i]),
			  nation_adjective_for_player(pvictor),
			  unit_name_translation(pkiller));
	  } else {
	    notify_player(player_by_number(i), punit->tile, E_UNIT_LOST_DEF,
			  /* TRANS: "Musketeers and 3 other units lost to
			   * an attack from the Polish Destroyer."
			   * (only happens with at least 2 other units) */
			  PL_("%s and %d other unit lost to an attack "
			      "from the %s %s.",
			      "%s and %d other units lost to an attack "
			      "from the %s %s.", others),
			  unit_name_translation(punit),
			  others,
			  nation_adjective_for_player(pvictor),
			  unit_name_translation(pkiller));
	  }
	} else {
	  notify_player(player_by_number(i), punit->tile, E_UNIT_LOST_DEF,
			/* TRANS: "2 units lost when the Polish Destroyer
			 * attacked the German Musketeers."
			 * (only happens with at least 2 other units) */
			PL_("%d unit lost when the %s %s attacked the %s %s.",
			    "%d units lost when the %s %s attacked the %s %s.",
			    num_killed[i]),
			num_killed[i],
			nation_adjective_for_player(pvictor),
			unit_name_translation(pkiller),
			nation_adjective_for_player(pvictim),
			unit_name_translation(punit));
	}
      }
    }

    /* remove the units */
    unit_list_iterate_safe(punit->tile->units, punit2) {
      if (pplayers_at_war(pvictor, unit_owner(punit2))) {
	wipe_unit(punit2);
      }
    } unit_list_iterate_safe_end  Package a unit_info packet.  This packet contains basically all
  information about a unit.
**********/
void package_unit(struct unit *punit, struct packet_unit_info *packet)
{
  packet->id = punit->id;
  packet->owner = player_number(unit_owner(punit));
  packet->x = punit->tile->x;
  packet->y = punit->tile->y;
  packet->homecity = punit->homecity;
  output_type_iterate(o) {
    packet->upkeep[o] = punit->upkeep[o];
  } output_type_iterate_end;
  packet->veteran = punit->veteran;
  packet->type = utype_number(unit_type(punit));
  packet->movesleft = punit->moves_left;
  packet->hp = punit->hp;
  packet->activity = punit->activity;
  packet->activity_base = punit->activity_base;
  packet->activity_count = punit->activity_count;
  packet->ai = punit->ai.control;
  packet->fuel = punit->fuel;
  if (punit->goto_tile) {
    packet->goto_dest_x = punit->goto_tile->x;
    packet->goto_dest_y = punit->goto_tile->y;
  } else {
    packet->goto_dest_x = 255;
    packet->goto_dest_y = 255;
    assert(!is_normal_map_pos(255, 255));
  }
  packet->activity_target = punit->activity_target;
  packet->activity_base = punit->activity_base;
  packet->paradropped = punit->paradropped;
  packet->done_moving = punit->done_moving;
  if (punit->transported_by == -1) {
    packet->transported = FALSE;
    packet->transported_by = 0;
  } else {
    packet->transported = TRUE;
    packet->transported_by = punit->transported_by;
  }
  packet->occupy = get_transporter_occupancy(punit);
  packet->battlegroup = punit->battlegroup;
  packet->has_orders = punit->has_orders;
  if (punit->has_orders) {
    int i;

    packet->orders_length = punit->orders.length;
    packet->orders_index = punit->orders.index;
    packet->orders_repeat = punit->orders.repeat;
    packet->orders_vigilant = punit->orders.vigilant;
    for (i = 0; i < punit->orders.length; i++) {
      packet->orders[i] = punit->orders.list[i].order;
      packet->orders_dirs[i] = punit->orders.list[i].dir;
      packet->orders_activities[i] = punit->orders.list[i].activity;
      packet->orders_bases[i] = punit->orders.list[i].base;
    }
  } else {
    packet->orders_length = packet->orders_index = 0;
    packet->orders_repeat = packet->orders_vigilant = FALSE;
    /* No need to initialize array. */
  }***********
  Package a short_unit_info packet.  This contains a limited amount of
  information about the unit, and is sent to players who shouldn't know
  everything (like the unit's owner's enemies).
**********/
void package_short_unit(struct unit *punit,
			struct packet_unit_short_info *packet,
			enum unit_info_use packet_use,
			int info_city_id, bool new_serial_num)
{
  static unsigned int serial_num = 0;

  /* a 16-bit unsigned number, never zero */
  if (new_serial_num) {
    serial_num = (serial_num + 1) & 0xFFFF;
    if (serial_num == 0) {
      serial_num++;
    }
  }
  packet->serial_num = serial_num;
  packet->packet_use = packet_use;
  packet->info_city_id = info_city_id;

  packet->id = punit->id;
  packet->owner = player_number(unit_owner(punit));
  packet->x = punit->tile->x;
  packet->y = punit->tile->y;
  packet->veteran = punit->veteran;
  packet->type = utype_number(unit_type(punit));
  packet->hp = punit->hp;
  packet->occupied = (get_transporter_occupancy(punit) > 0);
  if (punit->activity == ACTIVITY_EXPLORE
      || punit->activity == ACTIVITY_GOTO) {
    packet->activity = ACTIVITY_IDLE;
    packet->activity_base = -1;
  } else {
    packet->activity = punit->activity;
    packet->activity_base = punit->activity_base;
  }

  /* Transported_by information is sent to the client even for units that
   * aren't fully known.  Note that for non-allied players, any transported
   * unit can't be seen at all.  For allied players we have to know if
   * transporters have room in them so that we can load units properly. */
  if (punit->transported_by == -1) {
    packet->transported = FALSE;
    packet->transported_by = 0;
  } else {
    packet->transported = TRUE;
    packet->transported_by = punit->transported_by;
  }

  packet->goes_out_of_sight = FALSEvoid unit_goes_out_of_sight(struct player *pplayer, struct unit *punit)
{
  if (unit_owner(punit) == pplayer) {
    /* Unit is either about to die, or to change owner (civil war, bribe) */
    struct packet_unit_remove packet;

    packet.unit_id = punit->id;
    lsend_packet_unit_remove(pplayer->connections, &packet);
  } else {
    struct packet_unit_short_info packet;

    memset(&packet, 0, sizeof(packet));
    packet.id = punit->id;
    packet.goes_out_of_sight = TRUE;
    lsend_packet_unit_short_info(pplayer->connections, &packet)  Send the unit into to those connections in dest which can see the units
  at its position, or the specified ptile (if different).
  Eg, use ptile as where the unit came from, so that the info can be
  sent if the other players can see either the target or destination tile.
  dest = NULL means all connections (game.est_connections)
**********/
void send_unit_info_to_onlookers(struct conn_list *dest, struct unit *punit,
				 struct tile *ptile, bool remove_unseen)
{
  struct packet_unit_info info;
  struct packet_unit_short_info sinfo;
  
  if (!dest) {
    dest = game.est_connections;
  }

  CHECK_UNIT(punit);

  package_unit(punit, &info);
  package_short_unit(punit, &sinfo, UNIT_INFO_IDENTITY, FALSE, FALSE);
            
  conn_list_iterate(dest, pconn) {
    struct player *pplayer = pconn->playing;

    /* Be careful to consider all cases where pplayer is NULL... */
    if ((!pplayer && pconn->observer) || pplayer == unit_owner(punit)) {
      send_packet_unit_info(pconn, &info);
    } else if (pplayer) {
      bool see_in_old;
      bool see_in_new = can_player_see_unit_at(pplayer, punit, punit->tile);

      if (punit->tile == ptile) {
	/* This is not about movement */
	see_in_old = see_in_new;
      } else {
	see_in_old = can_player_see_unit_at(pplayer, punit, ptile);
      }

      if (see_in_new || see_in_old) {
	/* First send movement */
	send_packet_unit_short_info(pconn, &sinfo);

	if (!see_in_new) {
	  /* Then remove unit if necessary */
	  unit_goes_out_of_sight(pplayer, punit);
	}
      } else {
	if (remove_unseen) {
	  dsend_packet_unit_remove(pconn, punit->id);
	}
      }
    }
  } conn_list_iterate_end  send the unit to the players who need the info 
  dest = NULL means all connections (game.est_connections)
**********/
void send_unit_info(struct player *dest, struct unit *punit)
{
  struct conn_list *conn_dest = (dest ? dest->connections
				 : game.est_connections);
  send_unit_info_to_onlookers(conn_dest, punit, punit->tile, FALSE)  For each specified connections, send information about all the units
  known to that player/conn.
**********/
void send_all_known_units(struct conn_list *dest)
{
  conn_list_do_buffer(dest);
  conn_list_iterate(dest, pconn) {
    struct player *pplayer = pconn->playing;

    if (NULL == pplayer && !pconn->observer) {
      continue;
    }

    players_iterate(unitowner) {
      unit_list_iterate(unitowner->units, punit) {
	if (!pplayer || can_player_see_unit(pplayer, punit)) {
	  send_unit_info_to_onlookers(pconn->self, punit,
				      punit->tile, FALSE);
	}
      } unit_list_iterate_end;
    } players_iterate_end;
  }
  conn_list_iterate_end;
  conn_list_do_unbuffer(dest);
  flush_packets()  Nuke a square: 1) remove all units on the square, and 2) halve the 
  size of the city on the square.

  If it isn't a city square or an ocean square then with 50% chance add 
  some fallout, then notify the client about the changes.
**********/
static void do_nuke_tile(struct player *pplayer, struct tile *ptile)
{
  struct city *pcity = NULL;

  unit_list_iterate_safe(ptile->units, punit) {
    notify_player(unit_owner(punit), ptile, E_UNIT_LOST_MISC,
		  _("Your %s was nuked by %s."),
		  unit_name_translation(punit),
		  pplayer == unit_owner(punit)
		  ? _("yourself")
		  : nation_plural_for_player(pplayer));
    if (unit_owner(punit) != pplayer) {
      notify_player(pplayer, ptile, E_UNIT_WIN,
		    _("The %s %s was nuked."),
		    nation_adjective_for_player(unit_owner(punit)),
		    unit_name_translation(punit));
    }
    wipe_unit(punit);
  } unit_list_iterate_safe_end;

  pcity = tile_city(ptile);

  if (pcity) {
    notify_player(city_owner(pcity), ptile, E_CITY_NUKED,
		  _("%s was nuked by %s."),
		  city_name(pcity),
		  pplayer == city_owner(pcity)
		  ? _("yourself")
		  : nation_plural_for_player(pplayer));

    if (city_owner(pcity) != pplayer) {
      notify_player(pplayer, ptile, E_CITY_NUKED,
		    _("You nuked %s."),
		    city_name(pcity));
    }

    city_reduce_size(pcity, pcity->size / 2, pplayer);
  }

  if (!is_ocean_tile(ptile) && myrand(2) == 1) {
    if (game.info.nuke_contamination == CONTAMINATION_POLLUTION) {
      if (!tile_has_special(ptile, S_POLLUTION)) {
	tile_set_special(ptile, S_POLLUTION);
	update_tile_knowledge(ptile);
      }
    } else {
      if (!tile_has_special(ptile, S_FALLOUT)) {
	tile_set_special(ptile, S_FALLOUT);
	update_tile_knowledge(ptile);
      }
    }
  }***********
  Nuke all the squares in a 3x3 square around the center of the explosion
  pplayer is the player that caused the explosion.
**********/
void do_nuclear_explosion(struct player *pplayer, struct tile *ptile)
{
  struct player *victim = tile_owner(ptile);

  if (victim && victim->ai_funcs.incident_nuclear) {
    victim->ai_funcs.incident_nuclear(pplayer, victim);
  } else if (pplayer->ai_funcs.incident_nuclear) {
    pplayer->ai_funcs.incident_nuclear(pplayer, NULL);
  }

  square_iterate(ptile, 1, ptile1) {
    do_nuke_tile(pplayer, ptile1);
  } square_iterate_end;

  notify_conn(NULL, ptile, E_NUKE,
	      _("The %s detonated a nuke!"),
	      nation_plural_for_player(pplayer))  go by airline, if both cities have an airport and neither has been used this
  turn the unit will be transported by it and have it's moves set to 0
**********/
bool do_airline(struct unit *punit, struct city *city2)
{
  struct tile *src_tile = punit->tile;
  struct city *city1 = tile_city(src_tile);

  if (!city1)
    return FALSE;
  if (!unit_can_airlift_to(punit, city2))
    return FALSE;
  if (get_transporter_occupancy(punit) > 0) {
    return FALSE;
  }
  city1->airlift--;
  city2->airlift--;

  notify_player(unit_owner(punit), city2->tile, E_UNIT_RELOCATED,
		   _("%s transported successfully."),
		   unit_name_translation(punit));

  move_unit(punit, city2->tile, punit->moves_left);

  /* airlift fields have changed. */
  send_city_info(city_owner(city1), city1);
  send_city_info(city_owner(city2), city2);

  return TRUE  void do_explore(struct unit *punit)
{
  struct player *owner = unit_owner(punit);

  if (owner->ai_funcs.auto_explorer) {
    switch (owner->ai_funcs.auto_explorer(punit)) {
      case MR_DEATH:
        /* don't use punit! */
        return;
      case MR_OK:
        /* FIXME: ai_manage_explorer() isn't supposed to change the activity,
         * but don't count on this.  See PR#39792.
         */
        if (punit->activity == ACTIVITY_EXPLORE) {
          break;
        }
        /* fallthru */
      default:
        unit_activity_handling(punit, ACTIVITY_IDLE);

        /* FIXME: When the ai_manage_explorer() call changes the activity from
         * EXPLORE to IDLE, in unit_activity_handling() ai.control is left
         * alone.  We reset it here.  See PR#12931. */
        punit->ai.control = FALSE;
        break;
    };
  } else {
    unit_activity_handling(punit, ACTIVITY_IDLE);
    punit->ai.control = FALSE;
  }
  send_unit_info(NULL, punit); /* probably duplicate */***********
  Returns whether the drop was made or not. Note that it also returns 1 
  in the case where the drop was succesful, but the unit was killed by
  barbarians in a hut.
**********/
bool do_paradrop(struct unit *punit, struct tile *ptile)
{
  struct player *pplayer = unit_owner(punit);

  if (!unit_has_type_flag(punit, F_PARATROOPERS)) {
    notify_player(pplayer, punit->tile, E_BAD_COMMAND,
                     _("This unit type can not be paradropped."));
    return FALSE;
  }

  if (!can_unit_paradrop(punit)) {
    return FALSE;
  }

  if (get_transporter_occupancy(punit) > 0) {
    notify_player(pplayer, punit->tile, E_BAD_COMMAND,
		     _("You cannot paradrop a unit that is "
		       "transporting other units."));
  }

  if (!map_is_known(ptile, pplayer)) {
    notify_player(pplayer, ptile, E_BAD_COMMAND,
                     _("The destination location is not known."));
    return FALSE;
  }

  /* Safe terrain according to player map? */
  if (!is_native_terrain(unit_type(punit),
                         map_get_player_tile(ptile, pplayer)->terrain,
                         map_get_player_tile(ptile, pplayer)->special,
                         map_get_player_tile(ptile, pplayer)->bases)) {
    notify_player(pplayer, ptile, E_BAD_COMMAND,
                     _("This unit cannot paradrop into %s."),
                     terrain_name_translation(
                        map_get_player_tile(ptile, pplayer)->terrain));
    return FALSE;
  }

  if (map_is_known_and_seen(ptile, pplayer, V_MAIN)
      && ((tile_city(ptile)
	  && pplayers_non_attack(pplayer, tile_owner(ptile)))
      || is_non_attack_unit_tile(ptile, pplayer))) {
    notify_player(pplayer, ptile, E_BAD_COMMAND,
                     _("Cannot attack unless you declare war first."));
    return FALSE;    
  }

  {
    int range = unit_type(punit)->paratroopers_range;
    int distance = real_map_distance(punit->tile, ptile);
    if (distance > range) {
      notify_player(pplayer, ptile, E_BAD_COMMAND,
                       _("The distance to the target (%i) "
                         "is greater than the unit's range (%i)."),
                       distance, range);
      return FALSE;
    }
  }

  /* Safe terrain, really? Not transformed since player last saw it. */
  if (!can_unit_exist_at_tile(punit, ptile)) {
    map_show_circle(pplayer, ptile, unit_type(punit)->vision_radius_sq);
    notify_player(pplayer, ptile, E_UNIT_LOST_MISC,
                     _("Your %s paradropped into the %s "
                       "and was lost."),
                     unit_name_translation(punit),
                     terrain_name_translation(tile_terrain(ptile)));
    server_remove_unit(punit);
    return TRUE;
  }

  if ((tile_city(ptile) && pplayers_non_attack(pplayer, tile_owner(ptile)))
      || is_non_allied_unit_tile(ptile, pplayer)) {
    map_show_circle(pplayer, ptile, unit_type(punit)->vision_radius_sq);
    maybe_make_contact(ptile, pplayer);
    notify_player(pplayer, ptile, E_UNIT_LOST_MISC,
                     _("Your %s was killed by enemy units at the "
                       "paradrop destination."),
                     unit_name_translation(punit));
    server_remove_unit(punit);
    return TRUE;
  }

  /* All ok */
  {
    int move_cost = unit_type(punit)->paratroopers_mr_sub;
    punit->paradropped = TRUE;
    move_unit(punit, ptile, move_cost);
    return TRUE  Give 25 Gold or kill the unit. For H_LIMITEDHUTS
  Return TRUE if unit is alive, and FALSE if it was killed
**********/
static bool hut_get_limited(struct unit *punit)
{
  bool ok = TRUE;
  int hut_chance = myrand(12);
  struct player *pplayer = unit_owner(punit);
  /* 1 in 12 to get barbarians */
  if (hut_chance != 0) {
    int cred = 25;
    notify_player(pplayer, punit->tile, E_HUT_GOLD,
		              _("You found %d gold."), cred);
    pplayer->economic.gold += cred;
  } else if (city_exists_within_city_radius(punit->tile, TRUE)
             || unit_has_type_flag(punit, F_GAMELOSS)) {
    notify_player(pplayer, punit->tile, E_HUT_BARB_CITY_NEAR,
                  _("An abandoned village is here."));
  } else {
    struct unit_type *type = unit_type(punit);
    struct tile *tile = punit->tile;

    wipe_unit(punit);
    ok = FALSE;
    notify_player(pplayer, tile, E_HUT_BARB_KILLED,
                  _("Your %s has been killed by barbarians!"),
                  utype_name_translation(type));
  }
  return ok  Due to the effects in the scripted hut behavior can not be predicted,
  unit_enter_hut returns nothing.
**********/
static void unit_enter_hut(struct unit *punit)
{
  struct player *pplayer = unit_owner(punit);
  enum hut_behavior behavior = unit_class(punit)->hut_behavior;

  /* FIXME: Should we still run "hut_enter" script when
   *        hut_behavior is HUT_NOTHING or HUT_FRIGHTEN? */ 
  if (behavior == HUT_NOTHING) {
    return;
  }

  tile_clear_special(punit->tile, S_HUT);
  update_tile_knowledge(punit->tile);

  if (behavior == HUT_FRIGHTEN) {
    notify_player(pplayer, punit->tile, E_HUT_BARB,
		     _("Your overflight frightens the tribe;"
		       " they scatter in terror."));
    return;
  }
  
  /* AI with H_LIMITEDHUTS only gets 25 gold (or barbs if unlucky) */
  if (pplayer->ai.control && ai_handicap(pplayer, H_LIMITEDHUTS)) {
    (void) hut_get_limited(punit);
    return;
  }

  script_signal_emit("hut_enter", 1, API_TYPE_UNIT, punit);

  send_player_info(pplayer, pplayer);       /* eg, gold */
  return**
  Put the unit onto the transporter.  Don't do any other work.
************/
static void put_unit_onto_transporter(struct unit *punit, struct unit *ptrans)
{
  /* In the future we may updated ptrans->occupancy. */
  assert(punit->transported_by == -1);
  punit->transported_by = ptrans->id**
  Put the unit onto the transporter.  Don't do any other work.
************/
static void pull_unit_from_transporter(struct unit *punit,
				       struct unit *ptrans)
{
  /* In the future we may updated ptrans->occupancy. */
  assert(punit->transported_by == ptrans->id);
  punit->transported_by = -1**
  Put the unit onto the transporter, and tell everyone.
************/
void load_unit_onto_transporter(struct unit *punit, struct unit *ptrans)
{
  put_unit_onto_transporter(punit, ptrans);
  send_unit_info(NULL, punit);
  send_unit_info(NULL, ptrans)**
  Pull the unit off of the transporter, and tell everyone.
************/
void unload_unit_from_transporter(struct unit *punit)
{
  struct unit *ptrans = game_find_unit_by_number(punit->transported_by);

  pull_unit_from_transporter(punit, ptrans);
  send_unit_info(NULL, punit);
  send_unit_info(NULL, ptrans)
  This function is passed to unit_list_sort() to sort a list of
  units according to their win chance against autoattack_x|y.
  If the unit is being transported, then push it to the front of
  the list, since we wish to leave its transport out of combat
  if at all possible.
*/
static int compare_units(const void *p, const void *q)
{
  struct unit * const *p1 = p;
  struct unit * const *q1 = q;
  struct unit *p1def = get_defender(*p1, autoattack_target);
  struct unit *q1def = get_defender(*q1, autoattack_target);
  int p1uwc = unit_win_chance(*p1, p1def);
  int q1uwc = unit_win_chance(*q1, q1def);

  if (p1uwc < q1uwc || (*q1)->transported_by > 0) {
    return -1; /* q is better */
  } else if (p1uwc == q1uwc) {
    return 0;
  } else {
    return 1; /* p is better */
  }**
  Check if unit survives enemy autoattacks. We assume that any
  unit that is adjacent to us can see us.
*/
static bool unit_survive_autoattack(struct unit *punit)
{
  struct unit_list *autoattack = unit_list_new();
  int moves = punit->moves_left;
  int sanity1 = punit->id;

  /* Kludge to prevent attack power from dropping to zero during calc */
  punit->moves_left = MAX(punit->moves_left, 1);

  adjc_iterate(punit->tile, ptile) {
    /* First add all eligible units to a unit list */
    unit_list_iterate(ptile->units, penemy) {
      struct player *enemyplayer = unit_owner(penemy);
      enum diplstate_type ds = 
            pplayer_get_diplstate(unit_owner(punit), enemyplayer)->type;

      if (game.info.autoattack
          && penemy->moves_left > 0
          && ds == DS_WAR
          && can_unit_attack_unit_at_tile(penemy, punit, punit->tile)) {
        unit_list_prepend(autoattack, penemy);
      }
    } unit_list_iterate_end;
  } adjc_iterate_end;

  /* The unit list is now sorted according to win chance against punit */
  autoattack_target = punit->tile; /* global variable */
  if (unit_list_size(autoattack) >= 2) {
    unit_list_sort(autoattack, &compare_units);
  }

  unit_list_iterate_safe(autoattack, penemy) {
    int sanity2 = penemy->id;
    struct unit *enemy_defender = get_defender(punit, penemy->tile);
    struct unit *punit_defender = get_defender(penemy, punit->tile);
    double punitwin = unit_win_chance(punit, enemy_defender);
    double penemywin = unit_win_chance(penemy, punit_defender);
    double threshold = 0.25;
    struct tile *ptile = penemy->tile;

    if (tile_city(ptile) && unit_list_size(ptile->units) == 1) {
      /* Don't leave city defenseless */
      threshold = 0.90;
    }

    if ((penemywin > 1.0 - punitwin
         || unit_has_type_flag(punit, F_DIPLOMAT)
         || get_transporter_capacity(punit) > 0)
        && penemywin > threshold) {
#ifdef REALLY_DEBUG_THIS
      freelog(LOG_TEST, "AA %s -> %s (%d,%d) %.2f > %.2f && > %.2f",
              unit_rule_name(penemy),
              unit_rule_name(punit), 
              TILE_XY(punit->tile),
              penemywin,
              1.0 - punitwin, 
              threshold);
#endif

      unit_activity_handling(penemy, ACTIVITY_IDLE);
      (void) unit_move_handling(penemy, punit->tile, FALSE, FALSE);
    }
#ifdef REALLY_DEBUG_THIS
      else {
      freelog(LOG_TEST, "!AA %s -> %s (%d,%d) %.2f > %.2f && > %.2f",
              unit_rule_name(penemy),
              unit_rule_name(punit), 
              TILE_XY(punit->tile),
              penemywin,
              1.0 - punitwin, 
              threshold);
      continue;
    }
#endif

    if (game_find_unit_by_number(sanity2)) {
      send_unit_info(NULL, penemy);
    }
    if (game_find_unit_by_number(sanity1)) {
      send_unit_info(NULL, punit);
    } else {
      unit_list_free(autoattack);
      return FALSE; /* moving unit dead */
    }
  } unit_list_iterate_safe_end;

  unit_list_free(autoattack);
  if (game_find_unit_by_number(sanity1)) {
    /* We could have lost movement in combat */
    punit->moves_left = MIN(punit->moves_left, moves);
    send_unit_info(NULL, punit);
    return TRUE;
  } else {
    return FALSE**
  Cancel orders for the unit.
************/
static void cancel_orders(struct unit *punit, char *dbg_msg)
{
  free_unit_orders(punit);
  send_unit_info(NULL, punit);
  freelog(LOG_DEBUG, "%s", dbg_msg)
  Will wake up any neighboring enemy sentry units or patrolling 
  units.
*/
static void wakeup_neighbor_sentries(struct unit *punit)
{
  /* There may be sentried units with a sightrange>3, but we don't
     wake them up if the punit is farther away than 3. */
  square_iterate(punit->tile, 3, ptile) {
    unit_list_iterate(ptile->units, penemy) {
      int radius_sq = get_unit_vision_at(penemy, penemy->tile, V_MAIN);

      if (!pplayers_allied(unit_owner(punit), unit_owner(penemy))
	  && penemy->activity == ACTIVITY_SENTRY
	  && radius_sq >= sq_map_distance(punit->tile, ptile)
	  && can_player_see_unit(unit_owner(penemy), punit)
	  /* on board transport; don't awaken */
	  && can_unit_exist_at_tile(penemy, penemy->tile)) {
	set_unit_activity(penemy, ACTIVITY_IDLE);
	send_unit_info(NULL, penemy);
      }
    } unit_list_iterate_end;
  } square_iterate_end;

  /* Wakeup patrolling units we bump into.
     We do not wakeup units further away than 3 squares... */
  square_iterate(punit->tile, 3, ptile) {
    unit_list_iterate(ptile->units, ppatrol) {
      if (punit != ppatrol
	  && unit_has_orders(ppatrol)
	  && ppatrol->orders.vigilant) {
	if (maybe_cancel_patrol_due_to_enemy(ppatrol)) {
	  cancel_orders(ppatrol, "  stopping because of nearby enemy");
	  notify_player(unit_owner(ppatrol), ppatrol->tile, E_UNIT_ORDERS,
			_("Orders for %s aborted after enemy movement was "
			  "spotted."),
			unit_name_translation(ppatrol));
	}
      }
    } unit_list_iterate_end;
  } square_iterate_endDoes: 1) updates the unit's homecity and the city it enters/leaves (the
         city's happiness varies). This also takes into account when the
	 unit enters/leaves a fortress.
      2) process any huts at the unit's destination.
      3) updates adjacent cities' unavailable tiles.

FIXME: Sometimes it is not necessary to send cities because the goverment
       doesn't care whether a unit is away or not.
**********/
static void unit_move_consequences(struct unit *punit,
                                   struct tile *src_tile,
                                   struct tile *dst_tile,
                                   bool passenger)
{
  struct city *fromcity = tile_city(src_tile);
  struct city *tocity = tile_city(dst_tile);
  struct city *homecity_start_pos = NULL;
  struct city *homecity_end_pos = NULL;
  int homecity_id_start_pos = punit->homecity;
  int homecity_id_end_pos = punit->homecity;
  struct player *pplayer_start_pos = unit_owner(punit);
  struct player *pplayer_end_pos = pplayer_start_pos;
  struct unit_type *type_start_pos = unit_type(punit);
  struct unit_type *type_end_pos = type_start_pos;
  bool refresh_homecity_start_pos = FALSE;
  bool refresh_homecity_end_pos = FALSE;
  int saved_id = punit->id;
  bool unit_died = FALSE;

  if (tocity) {
    unit_enter_city(punit, tocity, passenger);

    if(!unit_alive(saved_id)) {
      /* Unit died inside unit_enter_city().
       * This means that some cleanup has already taken place when it was
       * removed from game. */
      unit_died = TRUE;
    } else {
      /* In case script has changed something about unit */
      pplayer_end_pos = unit_owner(punit);
      type_end_pos = unit_type(punit);
      homecity_id_end_pos = punit->homecity;
    }
  }

  if (homecity_id_start_pos != 0) {
    homecity_start_pos = game_find_city_by_number(homecity_id_start_pos);
  }
  if (homecity_id_start_pos != homecity_id_end_pos) {
    homecity_end_pos = game_find_city_by_number(homecity_id_end_pos);
  } else {
    homecity_end_pos = homecity_start_pos;
  }

  /* We only do refreshes for non-AI players to now make sure the AI turns
     doesn't take too long. Perhaps we should make a special refresh_city
     functions that only refreshed happines. */

  /* might have changed owners or may be destroyed */
  tocity = tile_city(dst_tile);

  if (tocity) { /* entering a city */
    if (tocity->owner == pplayer_end_pos) {
      if (tocity != homecity_end_pos && !pplayer_end_pos->ai.control) {
        city_refresh(tocity);
        send_city_info(pplayer_end_pos, tocity);
      }
    }
    if (homecity_start_pos) {
      refresh_homecity_start_pos = TRUE;
    }
  }

  if (fromcity) { /* leaving a city */
    if (homecity_start_pos) {
      refresh_homecity_start_pos = TRUE;
    }
    if (fromcity != homecity_start_pos
        && fromcity->owner == pplayer_start_pos
        && !pplayer_start_pos->ai.control) {
      city_refresh(fromcity);
      send_city_info(pplayer_start_pos, fromcity);
    }
  }

  /* entering/leaving a fortress or friendly territory */
  if (homecity_start_pos || homecity_end_pos) {
    if ((game.info.happyborders > 0 && tile_owner(src_tile) != tile_owner(dst_tile))
        || (tile_has_base_flag_for_unit(dst_tile,
                                        type_end_pos,
                                        BF_NOT_AGGRESSIVE)
            && is_friendly_city_near(pplayer_end_pos, dst_tile))
        || (tile_has_base_flag_for_unit(src_tile,
                                        type_start_pos,
                                        BF_NOT_AGGRESSIVE)
            && is_friendly_city_near(pplayer_start_pos, src_tile))) {
      refresh_homecity_start_pos = TRUE;
      refresh_homecity_end_pos = TRUE;
    }
  }

  if (refresh_homecity_start_pos && !pplayer_start_pos->ai.control) {
    city_refresh(homecity_start_pos);
    send_city_info(pplayer_start_pos, homecity_start_pos);
  }
  if (refresh_homecity_end_pos
      && (!refresh_homecity_start_pos
          || homecity_start_pos != homecity_end_pos)
      && !pplayer_end_pos->ai.control) {
    city_refresh(homecity_end_pos);
    send_city_info(pplayer_end_pos, homecity_end_pos);
  }

  city_map_update_tile_now(dst_tile);
  sync_cities()Check if the units activity is legal for a move , and reset it if it isn't.
**********/
static void check_unit_activity(struct unit *punit)
{
  switch (punit->activity) {
  case ACTIVITY_IDLE:
  case ACTIVITY_SENTRY:
  case ACTIVITY_EXPLORE:
  case ACTIVITY_GOTO:
    break;
  case ACTIVITY_POLLUTION:
  case ACTIVITY_ROAD:
  case ACTIVITY_MINE:
  case ACTIVITY_IRRIGATE:
  case ACTIVITY_FORTIFIED:
  case ACTIVITY_FORTRESS:
  case ACTIVITY_RAILROAD:
  case ACTIVITY_PILLAGE:
  case ACTIVITY_TRANSFORM:
  case ACTIVITY_UNKNOWN:
  case ACTIVITY_AIRBASE:
  case ACTIVITY_FORTIFYING:
  case ACTIVITY_FALLOUT:
  case ACTIVITY_PATROL_UNUSED:
  case ACTIVITY_BASE:
  case ACTIVITY_LAST:
    set_unit_activity(punit, ACTIVITY_IDLE);
    break;
  }  Moves a unit. No checks whatsoever! This is meant as a practical 
  function for other functions, like do_airline, which do the checking 
  themselves.

  If you move a unit you should always use this function, as it also sets 
  the transported_by unit field correctly. take_from_land is only relevant 
  if you have set transport_units. Note that the src and dest need not be 
  adjacent.

  Returns TRUE iff unit still alive.
**********/
bool move_unit(struct unit *punit, struct tile *pdesttile, int move_cost)
{
  struct player *pplayer = unit_owner(punit);
  struct tile *psrctile = punit->tile;
  struct city *pcity;
  struct unit *ptransporter = NULL;
  struct vision *old_vision = punit->server.vision;
  struct vision *new_vision;
  int saved_id = punit->id;
  bool unit_lives;
    
  conn_list_do_buffer(pplayer->connections);

  /* Transporting units. We first make a list of the units to be moved and
     then insert them again. The way this is done makes sure that the
     units stay in the same order. */
  if (get_transporter_capacity(punit) > 0) {
    struct unit_list *cargo_units = unit_list_new();

    /* First make a list of the units to be moved. */
    unit_list_iterate(psrctile->units, pcargo) {
      if (pcargo->transported_by == punit->id) {
	unit_list_unlink(psrctile->units, pcargo);
	unit_list_prepend(cargo_units, pcargo);
      }
    } unit_list_iterate_end;

    /* Insert them again. */
    unit_list_iterate(cargo_units, pcargo) {
      /* FIXME: Some script may have killed unit while it has been
       *        in cargo_units list, but it has not been unlinked
       *        from this list. pcargo may be invalid pointer. */
      struct vision *old_vision = pcargo->server.vision;
      struct vision *new_vision = vision_new(unit_owner(pcargo), pdesttile);

      pcargo->server.vision = new_vision;
      vision_layer_iterate(v) {
	vision_change_sight(new_vision, v,
			    get_unit_vision_at(pcargo, pdesttile, v));
      } vision_layer_iterate_end;

      ASSERT_VISION(new_vision);

      /* Silently free orders since they won't be applicable anymore. */
      free_unit_orders(pcargo);

      pcargo->tile = pdesttile;

      unit_list_prepend(pdesttile->units, pcargo);
      check_unit_activity(pcargo);
      send_unit_info_to_onlookers(NULL, pcargo, psrctile, FALSE);

      vision_clear_sight(old_vision);
      vision_free(old_vision);

      unit_move_consequences(pcargo, psrctile, pdesttile, TRUE);
    } unit_list_iterate_end;
    unit_list_free(cargo_units);
  }

  unit_lives = unit_alive(saved_id);

  /* We first unfog the destination, then move the unit and send the
     move, and then fog the old territory. This means that the player
     gets a chance to see the newly explored territory while the
     client moves the unit, and both areas are visible during the
     move */

  /* Enhance vision if unit steps into a fortress */
  if (unit_lives) {
    new_vision = vision_new(unit_owner(punit), pdesttile);
    punit->server.vision = new_vision;
    vision_layer_iterate(v) {
      vision_change_sight(new_vision, v,
                          get_unit_vision_at(punit, pdesttile, v));
    } vision_layer_iterate_end;

    ASSERT_VISION(new_vision);

    /* Claim ownership of fortress? */
    if (tile_has_claimable_base(pdesttile, unit_type(punit))
        && (!tile_owner(pdesttile)
            || pplayers_at_war(tile_owner(pdesttile), pplayer))) {
      map_claim_ownership(pdesttile, pplayer, pdesttile);
      map_claim_border(pdesttile, pplayer);
      city_thaw_workers_queue();
      city_refresh_queue_processing();
    }

    unit_list_unlink(psrctile->units, punit);
    punit->tile = pdesttile;
    punit->moved = TRUE;
    if (punit->transported_by != -1) {
      ptransporter = game_find_unit_by_number(punit->transported_by);
      pull_unit_from_transporter(punit, ptransporter);
    }
    punit->moves_left = MAX(0, punit->moves_left - move_cost);
    if (punit->moves_left == 0) {
      punit->done_moving = TRUE;
    }
    unit_list_prepend(pdesttile->units, punit);
    check_unit_activity(punit);
  }

  /*
   * Transporter info should be send first becouse this allow us get right
   * update_menu effect in client side.
   */
  
  /*
   * Send updated information to anyone watching that transporter was unload
   * cargo.
   */
  if (ptransporter) {
    send_unit_info(NULL, ptransporter);
  }

  /* Send updated information to anyone watching.  If the unit moves
   * in or out of a city we update the 'occupied' field.  Note there may
   * be cities at both src and dest under some rulesets.
   *   If unit is about to take over enemy city, unit is seen by
   * those players seeing inside cities of old city owner. After city
   * has been transferred, updated info is sent by unit_enter_city() */
  if (unit_lives) {
    send_unit_info_to_onlookers(NULL, punit, psrctile, FALSE);
    
    /* Special checks for ground units in the ocean. */
    if (!can_unit_survive_at_tile(punit, pdesttile)) {
      ptransporter = find_transporter_for_unit(punit);
      if (ptransporter) {
        put_unit_onto_transporter(punit, ptransporter);
      }

      /* Set activity to sentry if boarding a ship. */
      if (ptransporter && !pplayer->ai.control && !unit_has_orders(punit)
          && !can_unit_exist_at_tile(punit, pdesttile)) {
        set_unit_activity(punit, ACTIVITY_SENTRY);
      }

      /*
       * Transporter info should be send first because this allow us get right
       * update_menu effect in client side.
       */
    
      /*
       * Send updated information to anyone watching that transporter has cargo.
       */
      if (ptransporter) {
        send_unit_info(NULL, ptransporter);
      }

      /*
       * Send updated information to anyone watching that unit is on transport.
       * All players without shared vison with owner player get
       * REMOVE_UNIT package.
       */
      send_unit_info_to_onlookers(NULL, punit, punit->tile, TRUE);
    }
  }

  if ((pcity = tile_city(psrctile))) {
    refresh_dumb_city(pcity);
  }
  if ((pcity = tile_city(pdesttile))) {
    refresh_dumb_city(pcity);
  }

  vision_clear_sight(old_vision);
  vision_free(old_vision);

  /* Remove hidden units (like submarines) which aren't seen anymore. */
  square_iterate(psrctile, 1, tile1) {
    players_iterate(pplayer) {
      /* We're only concerned with known, unfogged tiles which may contain
       * hidden units that are no longer visible.  These units will not
       * have been handled by the fog code, above. */
      if (TILE_KNOWN_SEEN == tile_get_known(tile1, pplayer)) {
        unit_list_iterate(tile1->units, punit2) {
          if (punit2 != punit && !can_player_see_unit(pplayer, punit2)) {
	    unit_goes_out_of_sight(pplayer, punit2);
	  }
        } unit_list_iterate_end;
      }
    } players_iterate_end;
  } square_iterate_end;

  if (unit_lives) {
    unit_move_consequences(punit, psrctile, pdesttile, FALSE);

    /* FIXME: Should signal emit be after sentried units have been
     *        waken up in case script causes unit death? */
    script_signal_emit("unit_moved", 3,
                       API_TYPE_UNIT, punit,
                       API_TYPE_TILE, psrctile,
                       API_TYPE_TILE, pdesttile);
    unit_lives = unit_alive(saved_id);

    if (!unit_lives) {
      /* Script caused unit to die */
      return FALSE;
    }
  }

  if (unit_lives) {
    wakeup_neighbor_sentries(punit);
    unit_lives = unit_survive_autoattack(punit);
  }

  if (unit_lives) {
    maybe_make_contact(pdesttile, unit_owner(punit));
  }

  conn_list_do_unbuffer(pplayer->connections);

  if (!unit_lives) {
    return FALSE;
  }

  if (game.info.timeout != 0 && game.timeoutaddenemymove > 0) {
    bool new_information_for_enemy = FALSE;

    phase_players_iterate(penemy) {
      /* Increase the timeout if an enemy unit moves and the
       * timeoutaddenemymove setting is in use. */
      if (penemy->is_connected
	  && pplayer != penemy
	  && pplayers_at_war(penemy, pplayer)
	  && can_player_see_unit(penemy, pu DK\E3E2E2Y	DF3DCF1D9D[D&E DDDDlD`DmE`FEZDHFEDCDFE
D[DaDTEFD!HYE!EGZDzHE,E7G9F%@InDDOD2FF@JnD
DdFADLFFFEGeGhDTDTDxG9F DTE5F?G+NHD0_Z@dhSSD[GhE>EVDIGM@fpF`ZF:EDGAD1D~F DG*HFaE,GhFGGRfEZHNF+HlIAF5GwNhH_HGH1GhGVD2D0DMFGE3WDaGoD*IJF^GFoG:GGNJGVGlE;DDFXIuJ*F%FK,E3O-IVG9FA@PhE6E?F%DeGF5E+IEED\DD3DoFD^E}I]HZD#E7DVG9EGPF%DFF3DTD.FwDWG9EKDQG?DLDnD,I1D)FHDSE}DhDD+DXDUJD<DWD^P\DpEoEXDLE@E;DoF$GMG8D.G5DDuD.D	DqDXDuDtEERDAD5DODeD;EYE;FgHZDBDWFSDmDPDkD&E7FKEODUH5EeGu@LD9EDNYM(FYDEDDkF"H9D@Pn}F;E{D3D_G?D=HWD3EDEZE@DYGGrEZDaGIWHZF/GfIqEdE2DWDEHD GDD%DuLM]GVF#EmF6D3D`E@G;EyIG8FdO2FAF)F`EDFHHD0D%SZFFgKZGF;DJzFYEuEWHtIVHD<DuGDhDYFyG,Q4GVM#KJzgFEZD;mLGMDeamHrKFGK6E%D@EqG`DmKGOLZ F^JLGJKL>EaMiD&JDD@FfDHmE@DE E5JbPL;IGMNDD7HCFhDG/M8EDrDTJL_GTDGN\XDMJ;GZJaNF0E2DfMYGZH#OSIFYDaJaM0D5I4D=DjG\D}DlH|JF\FGnF~G&DF
JDJxF0D%F}D}DZFFJEOG-FDoFJF9E)OF MMaD*E	KVDCE1K+D@DzG/I	D(DDWE.D\D*G(F0GvGQEDODVDGFHE>D=DgEvOPEYHD(E=EFDaG`GgF3GRPLPIF&M>EdHU+GE[J8FH.E`DDEvDD0FDyE,GaDE3G`IrDUEOLDEmETD8F]F3EH[VDyFGKBcQFMK`HrFF FJFsD1FmEEAFMSHJWVE|DuD0JLEzFLHSK@FsI'D}E|GWwHGFG8DEE|Iqu9ZtH@IiFEqH8F/Dk_<QVD&EyL-F:F6DhE@G9I4J<K`H<HrIWG%L`EDDaH*FyJzJ!K:E-D|E@IVDBHDBK|D#U0DuO|XzHHWFXwO\L-GmHW@UGJfEXEEJCI~t	b)KTY4J0DOGOYlI1H=YURP8cQVHHrDQFoHDzHKF@D"N<F&_FPE$E[EDH>E5@yMH~NLJaD`PRVGHKyI*@QOLJf@EVG#HvDLHKJJ}HE[EPGmKdMwlVF7DKEzF#EbD*H`E9FHF"E~F?VlKTDrD.DBI+O<GBDD\JOGmDDFyDAVGhF(F@F]QbCGwR.FBM"Gm\@DE^EPIx@[JfGmEy@IYGH@UgDD/F-E!DEPmaOK.DcE8E:DzW	DU'J<LLE/D?FJJLFK;E`DRE!DyK>E FSE%HnD5G,ED6DJGhE`J4G,J E1FGETD\DM`FfI.KI#P'FSF&EFQGHI2QI}ZYDFLE$THFD\|VHHr\SDmJLLpGZQOYKsK`Ld^<EfDuRrETFPLpFfHnQE.RFQ5XwMm{J$GfHnHnOx{WVHI^<E~EtDBD-TfIDEYp [yK@D|K[IM.@JvI=elF^fgIiDV&G{FR@dKFR@O:FwGc@xHrXwGgEPH>Ey@I/EqD#Mm@O.T9GSnG2_JR%K;G|tIG6`	NAMKI'DUEZaP0K%Y(J H@TOF:DFVJ2JG`DXE.GSEBFVD>EVDeDDD'E7J4G~DGD&EQKFtFDaI@PBDvSMThR(K1EMGVFFE;DkHAF)DqG)GVIAG2IEqF)LlGSGeKEF^FWHEG_EE`FtFrG9HOG M+DBE'G G@I,EjGE'G9@UNDG4GQG9JD#DoD EZDD~DGED5G/GWECEvFfE HlF>GzD0@PBEF~FtGU`%G~G~ID.FVE+LRI4KIEDrEAE!RMEaI`KGVG+D!GEgMFWU;IVHtHE@Q2QnG~DiNLEFOb@Z	D[bE+GsDFeJ'M5DHdGT^JfR`FVnit)) {
	new_information_for_enemy = TRUE;
	break;
 }} phase_players_iterate_end;
if (incretimeout_because_unit_moved()}/* Note, an individual call to  may leave things inunstable* state (e.g., negatiransporter capacity)moran one isbeingd at a bounc) and they are not dinright order.  This is probablya bug. */tile_has_special(pdest, S_HUTt saved_id = p->ienter_hut()returit_alive(}

/*
  Maybe cancel gototherean  way
/
ic boolbe___due_to(struct*,  *p)
(is_non_allied(,owner) 
	  || )patrol asnear.If you modifykeup rangeshould chn
 _neighbor_sentries() too.= FALSEradius_sq = getvisa,V_MAIN *p=circle, sitd = map_(&&e(, ))
	|| (&& !s&& ->occupied Executes a'ss stored put on idifac fail""setencouedvalue will bes, owise.  (
  funuseda_result enumion, declahand.h.
  But was nevhecked berjustonfu.  Arealeedsknowd or
  died; y elslternwi e_)repeatlooprts oae beginnoitmpleteo avoifinsrailroad wep for
  whebackted,nit hs leftAattunderonlyts finaldsrlast_made = 0ctivBypebaseassert(!= ACTIVITY_IDLE/* Umiddle o waititshfreelog(LOG_DEBUG, "%s %d",rule_nam));   Anyega messagewh( == 0/* FIXME: won't wors take 0 MPoppnr points"we'revigilant"ParearbynotifyE_UNIT_ORDERS,
	   _("Oabd"
			 "by."_llengtho,'tce perwe a round  sen(NULL++ = (!index + 1ist[]Cleabefwe engaovThat any* syieldibeaa nlimant:a caravapopupdialoasdvsteward* updaliaoincludnewex. tto someaf sperlydswitch (case _FULL_MP:!/*doesfull MPs unti
	 * next Weu('sat)			BUILD_CITYbuilsuggesfiby_iB	;		  "of	succ=>""=(BASEdo_)))siyvaliMOVE/* M!(diruloc to %d,->x->resing, !i.ialreadybeensposmbudidcombat>(ZOC, etc.)empofenough MP).  Keeisa (of--;
	,end,admquahack;lemo-had = 1 = fc_malloc(sizeof[0]DISBAND: disbanHOMEhome_noATRADEROUTeistrroutdeWONDERwohelpLAST!Yous/* S/* en*/RnbdifffectsMUSTpendfd_brk
 vconst->+bonus		 EFTVISION_RADIUS_SQINVISMIN(, 2COUN00Refre'sis shcan
 *uservrequitwo...it cboptimizs(, vv}ASSERll- se}}
ENDREP
DELTA
SVN   <A@F
D
E^D}EQD_DJG$D,D6D
J@T
J7EDUD
FD
DMD"D
[pEI@G@JMEhNsDJwHPN*FLbPvG8PvH?@I<FDD6D=@HnE3DHHFG%HH8MDFU/DDQH~fhFHJVhEDHnMHnVhEPP:VhE?HIPzVhV=O7WhQDHHEVhFO0]DL@Hq\$GJM$VhH6GQd_NGL"_NG>PV_NQ,G/*
 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
   This program is free software; you can redistribute it and/or modifyit under the terms ofGNU General Public License as pshed b S Foundation; either version 2, or (atr op)any lat.
d inhope thatwill be useful,but WITHOUT ANY WARRANTY; without eveimplied warranty ofMERCHANTABILITYFITNESS FOR A PARTICULAR PURPOSE.  Seefre details.
/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/* common */"player.h"serveraiifacesettlersaicityaiexplorhandtool
  Initialize  ai_funcs  pointvoiit_(struct*p)
{
  ->.auto_ = _;building_advisor_i_manage_schoosfirst_activitiei_do_diplomacyonlaefore_itreaty_evaluateaccepcontacincidentwapillagnucle;
}
ENDREP
DELTA 15727 15444 28127
SVN  'r b  fZs %if (pplayer->ai_funcs.building_advisor) {
    pplayer->ai_funcs.building_advisor(pcity, &choice);

    if (valid_improvement(choice.value.buildingchoice.value.building}
      };

      change_build_target(pplayer, pcity, target, E_IMP_AUTO);
      return;
    }ENDREP
DELTA 8317 11566 4253
SVN  _Vq m . .-= bY cB i	 7T B( {q} gk
 :r/ 9\ i2$ ^w `y \4 O\= c0J cD> 6O _ g{ `dCfc_types.h"

#include "city.h"
#include "connection.h"
#include "nation.h"
#include "shared.h"
#include "spaceship.h"
#include "tech.h"
#include "unitlist.h"
#include "vision"Unassigned"

enum handicap_type {
  H_DIPLOMAT = 0,     /* Can't build offensive diplomats */
  H_AWAY,             /* Away mode */
  H_LIMITEDHUTS,      /* Can get only 25 gold and barbs from huts */
  H_DEFENSIVE,        /* Build defensive buildings without calculating need */
  H_EXPERIMENTAL,     /* Enable experimental AI features (for testing) */
  H_RATES,            /* Can't set its rates beyond government limits */
  H_TARGETS,          /* Can't target anything it doesn't know exists */
  H_HUTS,             /* Doesn't know which unseen tiles have huts on them */
  H_FOG,              /* Can't see through fog of war */
  H_NOPLANES,         /* Doesn't build air units */
  H_MAP,              /* Only knows map_is_known tiles */
  H_DIPLOMACY,        /* Not very good at diplomacy */
  H_REVOLUTION,       /* Cannot skip anarchy */
  H_EXPANSION,        /* Don't like being much larger than human */
  H_DANGER,           /* Always thinks its city is in danger */
  H_LAST
};

BV_DEFINE(bv_player, MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS);

BV_DEFINE(bv_handicap, H_LAST)score {
  int happy;
  int content;
  int unhappy;
  int angry;
  int specialists[SP_MAX]  int game;             /* total score you get in player dialog */prev_gold;
  int maxbuycost;
  int est_upkeep; /* estimated upkeep of buildings in cities */
  /* The units of tech_want seem to be shields */
  int tech_want[A_LAST+1];
  bv_handicap handicaps;        /* sum of enum handicap_type */
  enum ai_level skill_level;   , frost; /* threat of global warming / nuclear winterARMISTICEenum dipl_reason {
  DIPL_OK, DIPL_ERROR, DIPL_SENATE_BLOCKING, DIPL_ALLIANCE_PROBLEM
};

/* the following are for "pacts" */enum diplstate_type max_state; /* maximum treaty level ever had */
  int first_contact_turn; /* turn we had first contact with this playerenum player_debug_types {
  PLAYER_DEBUG_DIPLOMACY, PLAYER_DEBUG_TECH, PLAYER_DEBUG_LAST
};

BV_DEFINE(bv_debug, PLAYER_DEBUG_LAST);

struct attribute_block_s {
  void *data;
  int length;
#define MAX_ATTRIBUTE_BLOCK     (256*1024)	/* largest attribute block */
};

struct Treaty;

struct player {
  bool used;
  char name[MAX_LEN_NAME];
  char username[MAX_LEN_NAME];
  char ranked_username[MAX_LEN_NAME]; /* the user who will be ranked */
  int user_turns;            /* number of turns this user has played */
  bool is_male;
  struct government *government; /* may be NULL in pregame */
  struct government *target_government; /* may be NULL */
  struct nation_type *nation;
  struct team *team;
  bool is_ready; /* Did the player click "start" yet? */
  bool phase_done;
  int nturns_idle;
  bool is_alive;
  bool is_dying; /* set once the player is in the process of dying */
  bool surrendered; /* has indicated willingness to surrenderbv_player embassycity_list *cities;
  struct unit_list *units;
  struct player_score score;
  struct player_economic economic;

  int bulbs_last_turn;    /* # bulbs researched last turn only */
  struct player_spaceship spaceship;
  struct player_ai ai;
  struct {
    void (*auto_settlers)(struct player *pplayer);
    void (*building_advisor_init)(struct player *pplayer);
    void (*building_advisor)(struct city *pcity, struct ai_choice *choice);
    enum unit_move_result (*auto_explorer)(struct unit *punit);
    void (*first_activities)(struct player *pplayer);
    void (*diplomacy_actions)(struct player *pplayer);
    void (*last_activities)(struct player *pplayer);
    void (*before_auto_settlers)(struct player *pplayer);
    void (*treaty_evaluate)(struct player *pplayer, struct player *aplayer, struct Treaty *ptreaty);
    void (*treaty_accepted)(struct player *pplayer, struct player *aplayer, struct Treaty *ptreaty);
    void (*first_contact)(struct player *pplayer, struct player *aplayer);
    void (*incident_diplomat)(struct player *violator, struct player *victim);
    void (*incident_war)(struct player *violator, struct player *victim);
    void (*incident_pillage)(struct player *violator, struct player *victim);
    void (*incident_nuclear)(struct player *violator, struct player *victim);
  } ai_funcs*connections;       /* will replace conn */int small_wonders[B_LAST];              /* contains city id's */
         /* wonders[] may also be (-1), or the id of a city
	    which no longer exists, if the wonder has been destroyed */

  struct attribute_block_s attribute_block;
  struct attribute_block_s attribute_block_buffer;
  bv_debug debug;
};

/* A slot is a possibly uninitialized player. */
int player_slot_count(void);
bool player_slot_is_used(const struct player *pslot);
void player_slot_set_used(struct player *pslot, bool used);
struct player *player_slot_by_number(int player_id);

/* General player accessor functions. */
int player_count(void);
void set_player_count(int count);

int player_index(const struct player *pplayer);
int player_number(const struct player *pplayer);

struct player *player_by_number(const int player_id);
struct player *valid_player_by_number(const int player_id);

const char *player_name(const struct player *pplaye
bool player_set_nation(struct player *pplayer, struct nation_type *pnation);
void player_set_unit_focus_status(struct player *pplayer);
bool player_has_embassy(const struct player *pplayer,
			const struct player *pplayer2);

bool can_player_see_unit(const struct player *pplayer,
			 const struct unit *punit);
bool can_player_see_unit_at(const struct player *pplayer,
			    const struct unit *punit,
			    const struct tile *ptile);

bool can_player_see_units_in_city(const struct player *pplayer,
				  const struct city *pcity);
bool can_player_see_city_internals(const struct player *pplayer,
				   const struct city *pcity);

bool player_owns_city(const struct player *pplayer,
		      constconst struct player *pplayer,
			   const struct tile *ptile);
bool player_knows_techs_with_flag(const struct player *pplayer,
				  enum tech_flag_id flag);
int num_known_tech_with_flag(const struct player *pplayer,
			     enum tech_flag_id flag);
int player_get_expected_income(const struct player *pplayer);

struct player_economic player_limit_to_max_rates(struct player *pplayer);

struct city *find_palace(const struct player *pplayer);

bool ai_handicap(const struct player *pplayer, enum handicap_type htype);
bool ai_fuzzy(const struct player *pplayer, bool normal_decision);
enum dipl_reason pplayer_can_make_treaty(const struct player *p1,
                                         const struct player *p2,
                                         enum diplstate_type treaty);
enum dipl_reason pplayer_can_cancel_treaty(const struct player *p1,
                                           constlayers_non_invade(const struct player *pplayer1,
			const struct player *pplayer,
			constconst struct player *me, const struct player *them);

struct player_research *get_player_research(const struct player *p1);

/* Initialization and iteration */
void player_init(struct player *plr);

#define player_slots_iterate(NAME_pslot)\
do {\
  struct player *NAME_pslot;\
  int MY_i;\
  for (MY_i = 0; MY_i < player_slot_count(); MY_i++) {\
    NAME_pslot = player_slot_by_number(MY_i);\
    if (NAME_pslot != NULL) {\

#define player_slots_iterate_end\
    }\
  }\
} while (0)

/* NB!!! This will only iterate over players for
 * which player_slot_is_used() returns TRUE. */
#define players_iterate(NAME_pplayer)\
do {\
  player_slots_iterate(NAME_pplayer) {\
    if (player_slot_is_used(NAME_pplayer)) {

#define players_iterate_end\
    }\
  } player_slots_iterate_end;\
} while (0)
/* User functions. */
bool is_valid_username(const char *name);

enum ai_level find_ai_level_by_name(const char *name);
const char *ai_level_name(enum ai_level level);
const char *ai_level_cmd(enum ai_level level);
bool is_settable_ai_level(enum ai_level level);
int number_of_ai_levels(void);

#endif  /* FC__PLAYER_H */
ENDREP
DELTA
SVN   -ra@F
D
E^D}EQD_DJG$D,D6D
J@T
J7EDUD
FD
DMD"D
[pEI@GO?DFN?/*
 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
   This program is free software; you can redistribute it and/or modifyit under the terms ofGNU General Public License as pshed b S Foundation; either version 2, or (atr op)any lat.
d inhope thatwill be useful,but WITHOUT ANY WARRANTY; without eveimplied warranty ofMERCHANTABILITYFITNESS FOR A PARTICULAR PURPOSE.  Seefre details.
/
#ifndef FC__AIIFACE_H
#define
voiit_ai_funcs(struct player *p);

#endif /* */
ENDREP
id: 46.5ck.r15755/111504
type: file
pred: 46.5ck.r15744/5630
count: 192
text: 15755 102645 8211 13014 9c7a3a675930f6a6f3c4fd795ac65dff
props: 11057 32360 112 0 008c1f4aede3063a105ee5510d8fc5d7
cpath: /trunk/common/player.h
copyroot: 15280 /trunk

PLAIN
K 11
Makefile.am
V 21
file 5h.5ck.r15634/80
K 6
aicore
V 24
dir 18t.5ck.r15745/15830
K 6
base.c
V 25
file 3jw.5ck.r15428/12402
K 6
base.h
V 24
file 3jx.5ck.r15722/6060
K 9
borders.c
V 24
file 4f0.5ck.r15421/5997
K 9
borders.h
V 24
file 4f1.5ck.r15405/1971
K 8
capstr.c
V 24
file dv.5ck.r15284/31880
K 8
capstr.h
V 24
file dw.5bk.r14881/38989
K 6
city.c
V 23
file q.5ck.r15727/44926
K 6
city.h
V 24
file 3q.5ck.r15727/45166
K 8
combat.c
V 22
file wp.5ck.r15747/123
K 8
combat.h
V 21
file wq.0.r12783/4096
K 12
connection.c
V 23
file un.5ck.r15657/2091
K 12
connection.h
V 23
file uo.5ck.r15657/2333
K 8
dataio.c
V 23
file 15r.5bk.r14513/681
K 8
dataio.h
V 23
file 15s.0.r10480/10050
K 11
diptreaty.c
V 24
file 3r.5ck.r15296/55367
K 11
diptreaty.h
V 20
file 3s.0.r9582/5141
K 9
effects.c
V 25
file 2eo.5ck.r15727/45408
K 9
effects.h
V 25
file 2ep.5ck.r15727/45653
K 8
events.c
V 25
file 33h.5ck.r15681/51107
K 8
events.h
V 24
file 3t.5ck.r15681/51837
K 10
fc_types.h
V 25
file 2ll.5ck.r15745/16316
K 6
game.c
V 23
file 3u.5ck.r15734/6624
K 6
game.h
V 23
file 3v.5ck.r15734/6863
K 19
generate_packets.py
V 24
file 2f4.5bk.r14820/5162
K 12
government.c
V 22
file he.0.r13247/25540
K 12
government.h
V 22
file hf.0.r13136/24006
K 6
idex.c
V 25
file qo.5bk.r14209/153709
K 6
idex.h
V 21
file qp.0.r8119/15235
K 13
improvement.c
V 23
file vb.5ck.r15652/8900
K 13
improvement.h
V 23
file vc.5ck.r15652/9146
K 5
map.c
V 23
file r.5ck.r15403/10583
K 5
map.h
V 23
file 41.5ck.r15386/4048
K 10
movement.c
V 23
file 2xv.5ck.r15748/255
K 10
movement.h
V 23
file 2xw.5ck.r15748/496
K 8
nation.c
V 25
file il.5bk.r14427/268264
K 8
nation.h
V 25
file im.5bk.r14209/153965
K 9
packets.c
V 22
file 43.5bk.r14482/143
K 11
packets.def
V 24
file 2f5.5ck.r15734/6379
K 9
packets.h
V 24
file 44.5bk.r14142/93896
K 8
player.c
V 23
file 45.5ck.r15687/9570
K 8
player.h
V 25
file 46.5ck.r15755/111504
K 14
requirements.c
V 25
file 2wq.5ck.r15700/11444
K 14
requirements.h
V 25
file 2wr.5bk.r13589/12119
K 11
spaceship.c
V 20
file 98.0.r9977/2632
K 11
spaceship.h
V 20
file 99.0.r9977/2979
K 12
specialist.c
V 23
file 33f.0.r13169/67171
K 12
specialist.h
V 23
file 33g.0.r13169/67406
K 6
team.c
V 25
file 33i.5bk.r14258/12852
K 6
team.h
V 23
file 33j.0.r13136/23073
K 6
tech.c
V 23
file t.5ck.r15706/31242
K 6
tech.h
V 23
file u.5bk.r14777/28073
K 9
terrain.c
V 25
file 2fp.5ck.r15700/10707
K 9
terrain.h
V 24
file qs.5ck.r15700/10954
K 6
tile.c
V 24
file 2ys.5ck.r15423/7007
K 6
tile.h
V 24
file 2yt.5ck.r15423/7247
K 6
unit.c
V 23
file v.5ck.r15741/23940
K 6
unit.h
V 24
file 48.5ck.r15741/24422
K 10
unitlist.c
V 25
file 39m.5bk.r15190/77355
K 10
unitlist.h
V 25
file 39n.5bk.r15190/77612
K 10
unittype.c
V 24
file v9.5ck.r15741/24176
K 10
unittype.h
V 24
file va.5ck.r15741/24663
K 9
version.c
V 26
file oe.5bk.r14377/2278985
K 9
version.h
V 21
file e7.0.r13518/7887
K 8
vision.c
V 24
file 4dm.5ck.r15473/4807
K 8
vision.h
V 24
file 4dn.5ck.r15473/5048
K 10
worklist.c
V 23
file o8.0.r13297/437651
K 10
worklist.h
V 23
file o9.0.r13297/438357
END
ENDREP
id: p.5ck.r15755/114787
type: dir
pred: p.5ck.r15748/3772
count: 2557
text: 15755 111751 3023 3023 f3c46a54229dc554e31e237bc8781f0e
props: 12883 2571 96 0 2763e13ff5d021346ae24ff6c9ced232
cpath: /trunk/common
copyroot: 15280 /trunk

id: vg.5ck.r15755/115020
type: file
pred: vg.5ck.r15744/9139
count: 413
text: 15755 1388 494 73361 e054e01df1e6f116dc40f9c4224ab7f3
props: 11057 12128 112 0 85dbe778568e34751643d476c23a0d7c
cpath: /trunk/server/srv_main.c
copyroot: 15280 /trunk

id: 4i.5ck.r15755/115266
type: file
pred: 4i.5ck.r15727/53422
count: 401
text: 15755 102317 297 89842 5ac98ecb6d8ab9bc5d79dd6095e4313e
props: 10955 1971 112 0 e17e3e5087e98ab1d6f041bdc6ae85ee
cpath: /trunk/server/cityturn.c
copyroot: 15280 /trunk

id: 4gm.5ck.r15755/115514
type: file
count: 0
text: 15755 101202 1102 2108 6ddbf2b89b0f9bda0e4bbd07b40bfca2
cpath: /trunk/server/aiiface.c
copyroot: 15280 /trunk

id: 4gn.5ck.r15755/115677
type: file
count: 0
text: 15755 110885 606 813 53936c13ffcd611a64bee55d08be13bc
cpath: /trunk/server/aiiface.h
copyroot: 15280 /trunk

id: 1a.5ck.r15755/115838
type: file
pred: 1a.5ck.r15749/153
count: 512
text: 15755 1910 99265 115780 c486636dad589e21aa1562eea133e2fa
props: 11095 1637 112 0 c5bfe3670c093a84ebf28b66298044e4
cpath: /trunk/server/unittools.c
copyroot: 15280 /trunk

id: vl.5ck.r15755/116086
type: file
pred: vl.5ck.r15729/3952
count: 413
text: 15755 1206 155 188232 88fb0a20cba00280a5e404e1ea13e7bd
props: 11092 74 112 0 de3988801a325e2d7d51fcbc7209a255
cpath: /trunk/server/savegame.c
copyroot: 15280 /trunk

id: 4u.5ck.r15755/116330
type: file
pred: 4u.5ck.r15744/9873
count: 485
text: 15755 994 186 68164 bc25e306b1ef4943376ef10d2bfa7a5c
props: 11057 14272 112 0 ab87823e529bcaae2ff952f918d53839
cpath: /trunk/server/plrhand.c
copyroot: 15280 /trunk

id: 5q.5ck.r15755/116574
type: file
pred: 5q.5ck.r15407/22766
count: 60
text: 15755 0 969 2646 8dce9729a54505dcb25342611184b0b5
props: 10619 59300 111 0 8ba011ca1ef4e408ab91a853a48e15eb
cpath: /trunk/server/Makefile.am
copyroot: 15280 /trunk

PLAIN
K 11
Makefile.am
V 25
file 5q.5ck.r15755/116574
K 9
aiiface.c
V 26
file 4gm.5ck.r15755/115514
K 9
aiiface.h
V 26
file 4gn.5ck.r15755/115677
K 9
airgoto.c
V 25
file 160.5ck.r15741/32247
K 9
airgoto.h
V 22
file 161.0.r12750/6355
K 6
auth.c
V 22
file 39c.5ck.r15360/58
K 6
auth.h
V 23
file 39d.0.r13513/10535
K 11
barbarian.c
V 24
file lw.5ck.r15726/12257
K 11
barbarian.h
V 21
file lx.0.r13220/1454
K 10
cityhand.c
V 25
file 10.5bk.r15266/134871
K 10
cityhand.h
V 23
file 4f.0.r13297/423686
K 11
citytools.c
V 23
file 4g.5ck.r15746/7184
K 11
citytools.h
V 24
file 4h.5ck.r15725/27561
K 10
cityturn.c
V 25
file 4i.5ck.r15755/115266
K 10
cityturn.h
V 24
file 4j.5ck.r15581/29276
K 11
civserver.c
V 24
file 4k.5ck.r15698/22886
K 11
civserver.h
V 21
file 4l.0.r2805/33121
K 10
commands.c
V 25
file 2ly.5ck.r15675/46095
K 10
commands.h
V 25
file 2lz.5ck.r15675/46343
K 13
connecthand.c
V 25
file 2dw.5ck.r15698/23619
K 13
connecthand.h
V 25
file 2dx.5ck.r15647/14992
K 9
console.c
V 25
file dd.5bk.r15266/134612
K 9
console.h
V 21
file de.0.r11697/6876
K 10
diplhand.c
V 23
file 4m.5ck.r15744/9384
K 10
diplhand.h
V 21
file 4n.0.r13421/6826
K 11
diplomats.c
V 23
file vz.5ck.r15744/9627
K 11
diplomats.h
V 24
file w0.5bk.r13745/13943
K 10
edithand.c
V 25
file 3bk.5ck.r15741/32491
K 10
edithand.h
V 23
file 4ez.5ck.r15317/588
K 10
gamehand.c
V 24
file 4o.5ck.r15698/23867
K 10
gamehand.h
V 24
file 4p.5ck.r15698/24111
K 9
generator
V 24
dir 2me.5ck.r15407/21126
K 11
ggzserver.c
V 25
file 39a.5bk.r15001/48736
K 11
ggzserver.h
V 25
file 39b.5bk.r15001/48999
K 10
gotohand.c
V 24
file 11.5ck.r15745/22070
K 10
gotohand.h
V 24
file 7r.5bk.r14972/34009
K 10
handchat.c
V 21
file 4q.5bk.r15243/90
K 10
handchat.h
V 22
file dj.0.r7100/189089
K 9
maphand.c
V 24
file 13.5ck.r15650/17919
K 9
maphand.h
V 24
file 14.5ck.r15650/18158
K 6
meta.c
V 24
file 4s.5ck.r15726/12501
K 6
meta.h
V 23
file 4t.5bk.r14763/1928
K 9
plrhand.c
V 25
file 4u.5ck.r15755/116330
K 9
plrhand.h
V 24
file 4v.5ck.r15675/48199
K 8
report.c
V 23
file vi.5ck.r15631/8157
K 8
report.h
V 23
file vj.5ck.r15631/8397
K 9
ruleset.c
V 24
file 8w.5ck.r15734/13450
K 9
ruleset.h
V 23
file 8x.5ck.r15729/3717
K 13
sanitycheck.c
V 24
file wi.5ck.r15414/14072
K 13
sanitycheck.h
V 23
file wj.5bk.r14639/6548
K 10
savegame.c
V 25
file vl.5ck.r15755/116086
K 10
savegame.h
V 24
file vm.5ck.r15698/25092
K 7
score.c
V 25
file 2eg.5ck.r15726/11524
K 7
score.h
V 22
file 2eh.0.r11430/3487
K 9
scripting
V 24
dir 31x.5ck.r15681/61480
K 8
sernet.c
V 24
file 15.5ck.r15675/47086
K 8
sernet.h
V 25
file 4y.5bk.r14427/262734
K 10
settings.c
V 25
file 2m0.5ck.r15726/12009
K 10
settings.h
V 24
file 2m1.5bk.r15275/3312
K 10
settlers.c
V 24
file 7s.5bk.r15190/81087
K 10
settlers.h
V 24
file 7t.5bk.r14416/98109
K 11
spacerace.c
V 25
file 9a.5bk.r14209/143395
K 11
spacerace.h
V 21
file 9b.0.r11338/1129
K 10
srv_main.c
V 25
file vg.5ck.r15755/115020
K 10
srv_main.h
V 24
file vh.5ck.r15698/23376
K 11
stdinhand.c
V 24
file 4z.5ck.r15698/24599
K 11
stdinhand.h
V 24
file 50.5ck.r15309/18163
K 11
techtools.c
V 25
file 33n.5ck.r15296/67232
K 11
techtools.h
V 24
file 33o.5bk.r14980/5400
K 10
unithand.c
V 24
file 18.5ck.r15686/17225
K 10
unithand.h
V 24
file 19.5bk.r14247/14333
K 11
unittools.c
V 25
file 1a.5ck.r15755/115838
K 11
unittools.h
V 24
file 1b.5ck.r15610/36892
K 8
voting.c
V 25
file 4ex.5ck.r15675/47329
K 8
voting.h
V 25
file 4ey.5ck.r15675/47518
END
ENDREP
id: z.5ck.r15755/120231
type: dir
pred: z.5ck.r15749/3706
count: 3687
text: 15755 116817 3401 3401 3c2f3818473572bb58679ffbaa4df109
props: 13932 1834 123 0 2b883b78ac685994a9940e39e0d24770
cpath: /trunk/server
copyroot: 15280 /trunk

PLAIN
K 9
ABOUT-NLS
V 22
file fu.0.r13215/85704
K 7
AUTHORS
V 19
file 5u.0.r12982/94
K 7
COPYING
V 19
file 1h.0.r9643/400
K 9
ChangeLog
V 23
file 6l.5bk.r13891/2383
K 7
INSTALL
V 21
file 6.5bk.r14672/184
K 11
Makefile.am
V 23
file 59.5bk.r14918/1267
K 4
NEWS
V 22
file 6m.5bk.r13824/202
K 6
README
V 20
file 7.0.r4421/96382
K 2
ai
V 22
dir 8.5ck.r15745/21842
K 10
autogen.sh
V 22
file 12o.5ck.r15690/50
K 9
bootstrap
V 22
dir 2p5.5ck.r15642/859
K 6
client
V 21
dir d.5ck.r15753/4629
K 6
common
V 23
dir p.5ck.r15755/114787
K 12
config.mac.h
V 20
file hb.0.r6045/5982
K 12
configure.ac
V 23
file 149.5ck.r15696/211
K 4
data
V 21
dir w.5ck.r15742/3003
K 6
debian
V 20
dir 5w.0.r13441/7348
K 12
dependencies
V 25
dir 2yu.5ck.r15754/116139
K 11
diff_ignore
V 19
file qq.0.r13200/42
K 3
doc
V 23
dir k7.5ck.r15727/53193
K 2
m4
V 24
dir 12p.5ck.r15640/18619
K 6
manual
V 24
dir 2m2.5ck.r15407/27128
K 2
po
V 22
dir fs.5ck.r15644/1902
K 7
scripts
V 23
dir 2yo.5bk.r14810/1300
K 6
server
V 23
dir z.5ck.r15755/120231
K 10
stamp-h.in
V 19
file 80.0.r1125/241
K 5
tests
V 22
dir 2g9.5ck.r15661/767
K 7
utility
V 23
dir 1c.5ck.r15734/12971
K 10
version.in
V 25
file 2lo.5ck.r15734/10366
K 3
vms
V 21
dir u9.0.r11105/70719
K 5
win32
V 24
dir 2eu.5bk.r13732/30345
END
ENDREP
id: 3.5ck.r15755/121727
type: dir
pred: 3.5ck.r15754/117636
count: 12174
text: 15755 120465 1249 1249 af8b7c563b3b5478b2bb93b05aef5002
props: 11109 0 255 0 8cbc80e0da9c47b05b8ffee17ea9b0f1
cpath: /trunk
copyroot: 15280 /trunk

PLAIN
K 8
branches
V 19
dir 1.0.r15752/6601
K 4
tags
V 21
dir 2.0.r15609/968232
K 5
trunk
V 23
dir 3.5ck.r15755/121727
K 7
website
V 18
dir 3ge.0.r12388/0
END
ENDREP
id: 0.0.r15755/122120
type: dir
pred: 0.0.r15754/118027
count: 15755
text: 15755 121954 153 153 b029b1a47a98fb9b1e5ba373c08ef88e
cpath: /
copyroot: 0 /

_1.5ck.t15754-1 add true false /trunk/server/aiiface.h

5q.5ck.t15754-1 modify true false /trunk/server/Makefile.am

4u.5ck.t15754-1 modify true false /trunk/server/plrhand.c

vl.5ck.t15754-1 modify true false /trunk/server/savegame.c

vg.5ck.t15754-1 modify true false /trunk/server/srv_main.c

1a.5ck.t15754-1 modify true false /trunk/server/unittools.c

_0.5ck.t15754-1 add true false /trunk/server/aiiface.c

4i.5ck.t15754-1 modify true false /trunk/server/cityturn.c

46.5ck.t15754-1 modify true false /trunk/common/player.h


122120 122273
