/*

Syntax:

 Comments:
 =========

  Supported are: c-style (/ * * /), c++-style (//) and python style
  (#). Empty lines will be ignored.

 Typedef lines:
 ==============
 
  Start with "type" and have the format "type <alias> = <src>". You
  can now use <alias> at every place a type is expected. Nested type
  defs are possible.

 Packets:
 ========

  A packet definition starts with a header line, contains variable
  field declarations, and ends with a single line containing the word
  "end".
   
   PACKET_<PACKET_NAME>=<packet num>; [<packet flags>]
     <type1> <field1>; [<field flags>]
     <type2> <field2>; [<field flags>]
     ...
   end

   Header line:
   ------------

    The header line contains the packet name. The packet name is used
    for the naming of the generated code struct and functions:
      struct packet_*;
      send_packet_*
      dsend_packet_*
      dlsend_packet_*
      lsend_packet_*
      receive_packet_*
      handle_packet_*

    The header line also contains the packet number. The packet number
    is used as a numeric identification of a packet between the client
    and server. The packet number shall never change for an existing
    packet without the adding of a mandatory capability. Packets which
    are used for the capability checking PACKET_PROCESSING_STARTED,
    PACKET_PROCESSING_FINISHED, PACKET_SERVER_JOIN_REQ and
    PACKET_SERVER_JOIN_REPLY are excluded here. These packets should
    never change their number. The packet number can be freely choosen
    as long as it is below 255 and unique.

   Packet flags:
   -------------

    Packet flags is a comma seperated list of:

     is-info: a second packet with the same content can be discarded
              WARNING: this flag is dangerous and should not be used for
              a packet that contains information that may be changed in
              the client outside of the reception of that packet, or for
              any packet with side effects at the client.

     pre-send:
     post-recv: 
     post-send: generate calls to pre-send, post-receive and post-send
     hooks. These hooks are named: pre_send_packet_*,
     post_receive_packet_* and post_send_packet_*. The user has to
     provide these. These functions may be used to do extra
     preparations, conversions or checks.

     no-delta: don't use the delta protocol. This is useful for
     packets which contain always different data
     (packet_generic_integer) or are only sent once
     (packet_req_join_game). Sadly this also disables the use of 0 as
     the default value.

     no-packet: don't generate a packet argument for the send
     function. Currently only used by packet_generic_empty.

     no-handle: don't generate handle_* prototypes. The generated
     switch statements (server/srv_main_gen.c, client/civclient_gen.c)
     doesn't include code for this packet. You have to handle this by
     yourself. This may be required for special packets which are
     handled early in the sequence.

     handle-via-packet: force the packet type of the handle
     function. Otherwise the fields are passed to the handle function.
     This is invoked automatically for packets with more than 5 fields
     or packets whose names are of the form foo_ruleset.

     handle-per-conn: normally the first parameter of the handle
     function is the player. handle-per-conn changes this to the
     connection the packet came from.

     dsend: request the creation of a dsend_packet_* function.  This is
     similar to a send function but instead of taking a packet struct
     as a parameter, it takes the fields of the packet as parameters.

     lsend: request the creation of a lsend_packet_* function.  This
     function sends to list of connections instead of just one 
     connection, which is the case for the other send functions.

     cs: a packet which is sent from the client to the server

     sc: a packet which is sent from the server to the client

  Each other packet line has the format "<type> <fields>;<flags>".

    Type:
    ----

      <type> is an alias or a basic type. A basic type has the format
      "<dataio-type>(<public-type>)". Exception here is the float
      type. You can specify with the dataio-type "float<number>" the
      transmission of a float in a uint32 multiplied by this factor.

    Fields:
    -------

      Comma seperated list of names. Each name can have zero, one or
      two array declarations. So "x", "x[10]" and "x[20][10]" is
      possible. The array size in the "[]" can be specified plain as a
      term. In this case all elements will be transmitted. If this is
      not-desired you can specify the amount of elements to be
      transfered by given the number. So the extended format is
      "[<full-array-size>:<elements-to-transfer>]". elements-to-transfer
      is relative to the packet.

   Field flags:
   ------------

      key: create multiple entries in the cache indexed by the key set
      (set of all fields which have the key attribute). This allow a
      better delta compression.

      diff: use the array-diff feature. This will reduce the amount of
      traffic for large arrays in which only a few elements change.

      add-cap: only transfer this field if the given capability is
      available at runtime. If you have a capability named
      "new_version" a field line may look like this:
        COORD x; add-cap(new_version)
      when making an optional capability mandatory, go through and remove
      the add-cap flag for it while leaving the field intact.

      remove-cap: don't transfer this field if the given capability is
      available at runtime.  When making an optional capability manditory,
      go through and remove entirely any fields marked as remove-cap with
      that capability.
*/

# typedefs for numbers
type UINT8		= uint8(int)
type UINT16		= uint16(int)
type UINT32		= uint32(int)
type SINT8		= sint8(int)
type SINT16		= sint16(int)
type SINT32		= sint32(int)
type BOOL		= bool8(bool)
type FLOAT		= float10000(float)
type FLOAT10x7		= float1000000(float)

# typedefs for arrays/structs
type MEMORY		= memory(unsigned char)
type STRING		= string(char)
type BIT_STRING		= bit_string(char)
type WORKLIST		= worklist(struct worklist)
type TECH_LIST		= tech_list(int)
type REQUIREMENT	= requirement(struct requirement)

# typedefs for enums
type CLAUSE		= uint8(enum clause_type)
type ACTIVITY		= uint8(enum unit_activity)
type EVENT		= sint16(enum event_type)
type TERRAIN		= sint16(Terrain_type_id)
type SPECIAL		= uint16(enum tile_special_type)
type RESOURCE           = sint8(Resource_type_id)
type SPECIALIST		= uint8(Specialist_type_id)
type DIPLOMAT_ACTION	= uint8(enum diplomat_actions)
type CMDLEVEL		= uint8(enum cmdlevel_id)
type PLACE_TYPE		= uint8(enum spaceship_place_type)
type RIVER_MOVE		= uint8(enum special_river_move)
type REPORT_TYPE	= uint8(enum report_type)
type AUTH_TYPE		= uint8(enum authentication_type)
type CITY_MAP		= uint8(enum city_tile_type)
type IMPR_RANGE		= uint8(enum impr_range)
type IMPR_GENUS		= uint8(enum impr_genus_id)
type DIRECTION		= uint8(enum direction8)
type ORDERS		= uint8(enum unit_orders)
type SSET_TYPE		= uint8(enum sset_type)
type SSET_CLASS         = uint8(enum sset_class)
type REQ_TYPE	        = uint8(enum req_source_type)
type REQ_RANGE		= uint8(enum req_range)
type EFFECT_TYPE	= uint8(enum effect_type)
type BV_IMPRS		= bitvector(bv_imprs)
type BV_FLAGS		= bitvector(bv_flags)
type BV_ROLES		= bitvector(bv_roles)
type BV_TERRAIN_FLAGS	= bitvector(bv_terrain_flags)
type BV_CITY_OPTIONS    = bitvector(bv_city_options)
type DIPLSTATE		= diplstate(struct player_diplstate)
type VISION		= uint32(unsigned int)

# typedefs for IDs
type PLAYER 		= UINT8
type CITY   		= UINT16
type UNIT   		= UINT16
type TECH     		= UINT8
type UNIT_TYPE		= uint8(Unit_type_id)
type NATION		= sint16(Nation_type_id)
type GOVERNMENT		= UINT8
type CONNECTION		= UINT8
type TEAM		= UINT8
type CONTINENT          = sint16(Continent_id)
type IMPROVEMENT	= uint8(Impr_type_id)

# other typedefs
type COORD  		= UINT8
type XYSIZE  		= UINT16
type YEAR     		= SINT16
type HP     		= UINT8
type PERCENT  		= UINT8
type GOLD		= UINT32
type TURN		= SINT16
type PHASE              = SINT16

/****************************************************
The remaining lines are the definition of the packets. These are
grouped together. There are the following groups:
  General
  Login/pregame/endgame
  Info
  Chat/event
  City
  Player
  Unit
  Diplomacy
  Report
  Connection
  New turn
  Spaceship
  Ruleset

The last used packet number is 138.
****************************************************/


/************** General packets **********************/

PACKET_PROCESSING_STARTED=0; sc
end

PACKET_PROCESSING_FINISHED=1; sc
end

PACKET_FREEZE_HINT=2;sc,lsend
end

PACKET_THAW_HINT=3;sc,lsend
end

/************** Login/pregame/endgame packets **********************/

# This packet is the first real (freeciv specific) packet send by the
# client. The player hasn't been accepted yet.
PACKET_SERVER_JOIN_REQ=4; cs, dsend,no-delta,no-handle
  STRING username[MAX_LEN_NAME];
  STRING capability[MAX_LEN_CAPSTR];
  STRING version_label[MAX_LEN_NAME];
  UINT32 major_version, minor_version, patch_version;
end

# ... and the server replies.
PACKET_SERVER_JOIN_REPLY=5; sc,no-delta
  BOOL you_can_join;
  STRING message[MAX_LEN_MSG];
  STRING capability[MAX_LEN_CAPSTR];
  STRING challenge_file[MAX_LEN_PATH];
  # clients conn id as known in server
  CONNECTION conn_id;
end

PACKET_AUTHENTICATION_REQ=6;sc,handle-per-conn,dsend
  AUTH_TYPE type;
  STRING message[MAX_LEN_MSG]; /* explain to the client if there's a problem */
end

PACKET_AUTHENTICATION_REPLY=7;cs,no-handle
  STRING password[MAX_LEN_PASSWORD];
end


PACKET_SERVER_SHUTDOWN=8;sc,lsend
end

PACKET_NATION_SELECT_REQ=10;cs,dsend
  PLAYER player_no;
  NATION nation_no;
  BOOL is_male;
  STRING name[MAX_LEN_NAME];
  UINT8 city_style;
end

PACKET_PLAYER_READY=116;cs,dsend
  PLAYER player_no;
  BOOL is_ready;
end

PACKET_GAME_STATE=12;post-send,post-recv,sc,dsend,lsend
  UINT32 value;
end

PACKET_ENDGAME_REPORT=13;sc,lsend
  UINT8 nscores;
  PLAYER id[MAX_NUM_PLAYERS:nscores];
  UINT16 score[MAX_NUM_PLAYERS:nscores];
  UINT32 pop[MAX_NUM_PLAYERS:nscores];
  UINT16 bnp[MAX_NUM_PLAYERS:nscores];
  UINT16 mfg[MAX_NUM_PLAYERS:nscores];
  UINT16 cities[MAX_NUM_PLAYERS:nscores];
  UINT16 techs[MAX_NUM_PLAYERS:nscores];
  UINT16 mil_service[MAX_NUM_PLAYERS:nscores];
  UINT8 wonders[MAX_NUM_PLAYERS:nscores];
  UINT16 research[MAX_NUM_PLAYERS:nscores];
  UINT32 landarea[MAX_NUM_PLAYERS:nscores];
  UINT32 settledarea[MAX_NUM_PLAYERS:nscores];
  UINT16 literacy[MAX_NUM_PLAYERS:nscores];
  UINT32 spaceship[MAX_NUM_PLAYERS:nscores];
end

/************** Info packets **********************/

# Use of is-info on this packet is dangerous but speeds things up greatly.
# Packet spam from excess sending of tiles has slowed the client greatly in
# the past.  However see the comment on is_info at the top about the dangers.
PACKET_TILE_INFO=14; sc,lsend,is-info
  COORD x, y; key

  TERRAIN type;
  UINT8 known;
  BOOL special[S_LAST];
  RESOURCE resource;
  PLAYER owner;
  CONTINENT continent;
  STRING spec_sprite[MAX_LEN_NAME];
end

# This packet used to have is_info set but that doesn't work with the
# seconds_to_phasedone field: sending the same value a second time after a
# while has passed means a completely reset timeout.
PACKET_GAME_INFO=15; sc
  GOLD gold;
  UINT32 tech;
  UINT32 skill_level;
  
  UINT8 aifill;

  BOOL is_new_game;   # TRUE only in pregame for "new" (not loaded) games
  FLOAT seconds_to_phasedone;
  UINT32 timeout;
  TURN turn;
  PHASE phase;
  YEAR year, end_year;

  BOOL simultaneous_phases;
  UINT32 num_phases;

  PLAYER min_players;
  PLAYER max_players;
  PLAYER nplayers;
  PLAYER player_idx;

  UINT32 globalwarming, heating, warminglevel;
  UINT32 nuclearwinter, cooling, coolinglevel;

  UINT8 cityfactor;
  UINT8 diplcost, freecost, conquercost;
  UINT8 unhappysize;
  UINT8 angrycitizen;
  UINT8 techpenalty;
  UINT32 foodbox;
  UINT32 shieldbox;
  UINT32 sciencebox;
  UINT8 diplomacy;
  UINT8 dispersion;
  UINT16 tcptimeout;
  UINT16 netwait;
  UINT16 pingtimeout;
  UINT16 pingtime;
  UINT8 diplchance;
  UINT8 citymindist;
  UINT8 civilwarsize;
  UINT8 contactturns;
  UINT8 rapturedelay;
  UINT8 celebratesize; /* size limit for cities before they can celebrate */
  UINT8 barbarianrate;
  UINT8 onsetbarbarian;
  UINT8 occupychance;
  BOOL autoattack;
  BOOL spacerace;
  UINT8 aqueductloss;
  UINT8 killcitizen;
  UINT8 razechance;
  BOOL savepalace;
  BOOL natural_city_names;
  BOOL turnblock;
  BOOL fixedlength;
  BOOL auto_ai_toggle;
  BOOL fogofwar;  
  UINT8 borders;
  UINT8 nbarbarians;
  BOOL happyborders;
  BOOL slow_invasions;
  UINT8 add_to_size_limit;
  UINT8 notradesize, fulltradesize;
  UINT8 allowed_city_names;
  IMPROVEMENT palace_building;
  IMPROVEMENT land_defend_building;
  BOOL changable_tax;
  UINT8 forced_science;
  UINT8 forced_luxury;
  UINT8 forced_gold;
  UINT8 min_city_center_output[O_MAX];
  UINT8 min_dist_bw_cities;
  UINT8 init_vis_radius_sq;
  UINT8 hut_overflight;
  BOOL pillage_select;
  UINT8 nuke_contamination;
  UINT8 granary_food_ini[MAX_GRANARY_INIS];
  UINT8 granary_num_inis;
  UINT8 granary_food_inc;
  UINT8 tech_cost_style;
  UINT8 tech_leakage;
  YEAR tech_cost_double_year;
  BOOL killstack;
  UINT8 autoupgrade_veteran_loss;
  UINT16 incite_improvement_factor;
  UINT16 incite_unit_factor;
  UINT16 incite_total_factor;
  GOVERNMENT government_when_anarchy_id;
  UINT8 revolution_length;
  SINT16 base_pollution;
  UINT8 happy_cost;
  UINT8 food_cost;
  UINT16 base_bribe_cost;
  UINT16 base_incite_cost;
  UINT8 base_tech_cost;
  UINT16 ransom_gold;

  UINT8 save_nturns;
  UINT8 save_compress_level;

  STRING start_units[MAX_LEN_STARTUNIT];

  UINT8 num_teams;
  STRING team_names_orig[MAX_NUM_TEAMS:num_teams][MAX_LEN_NAME];
  
  /* True if at least one civilization has researched a tech */
  BOOL global_advances[A_LAST]; diff
  UINT16 great_wonders[B_LAST]; diff
end

PACKET_MAP_INFO=16; sc,lsend
  XYSIZE xsize;
  XYSIZE ysize;
  UINT8 topology_id;
end

PACKET_NUKE_TILE_INFO=17;sc,dsend,lsend
  COORD x,y;
end

/************** Chat/event packets **********************/

PACKET_CHAT_MSG=18;sc, pre-send, post-recv,lsend,dsend
  STRING message[MAX_LEN_MSG];
  COORD x, y;
  EVENT event;
  CONNECTION conn_id;
end

PACKET_CHAT_MSG_REQ=19;cs,handle-per-conn,dsend
  STRING message[MAX_LEN_MSG];
end

/************** City packets **********************/

PACKET_CITY_REMOVE=20;sc,dsend,lsend
  CITY city_id;
end

PACKET_CITY_INFO=21; sc,lsend
  CITY id; key
  PLAYER owner;
  COORD x,y;
  STRING name[MAX_LEN_NAME];
  UINT8 size;

  UINT8 ppl_happy[5], ppl_content[5], ppl_unhappy[5], ppl_angry[5];

  UINT8 specialists_size;
  UINT8 specialists[SP_MAX:specialists_size];

  SINT16 surplus[O_MAX];
  UINT16 waste[O_MAX];
  SINT16 unhappy_penalty[O_MAX];
  UINT16 prod[O_MAX];
  SINT16 citizen_base[O_MAX];
  SINT16 usage[O_MAX];
  UINT16 food_stock, shield_stock;

  UINT16 trade[NUM_TRADEROUTES];
  UINT8 trade_value[NUM_TRADEROUTES];

  UINT16 pollution;

  BOOL production_is_unit;
  UINT8 production_value;

  TURN turn_last_built;
  UINT8 changed_from_id;
  BOOL changed_from_is_unit;
  UINT16 before_change_shields;
  UINT16 disbanded_shields;
  UINT16 caravan_shields;
  UINT16 last_turns_shield_surplus;
  
  WORKLIST worklist;

  BV_IMPRS improvements;
  CITY_MAP city_map[CITY_MAP_SIZE * CITY_MAP_SIZE];

  BOOL did_buy, did_sell, was_happy, airlift, diplomat_investigate;

  BV_CITY_OPTIONS city_options;
  TURN turn_founded;

  BOOL walls;
end

PACKET_CITY_SHORT_INFO=22; sc,lsend
  CITY id;key
  PLAYER owner;
  COORD x;
  COORD y;
  STRING name[MAX_LEN_NAME];
  UINT8 size;
  BOOL happy;
  BOOL unhappy;
  BV_IMPRS improvements;
  BOOL occupied;
  BOOL walls;
  UINT16 tile_trade;
end

PACKET_CITY_SELL=23;cs,dsend
  CITY city_id;
  UINT8 build_id;
end

PACKET_CITY_BUY=24;cs,dsend
  CITY city_id;
end

PACKET_CITY_CHANGE=25;cs,dsend
  CITY city_id;
  UINT8 build_id;
  BOOL is_build_id_unit_id;
end

PACKET_CITY_WORKLIST=26;cs,dsend
  CITY city_id;
  WORKLIST worklist;
end

PACKET_CITY_MAKE_SPECIALIST=27;cs,dsend
  CITY city_id;
  COORD worker_x, worker_y;
end

PACKET_CITY_MAKE_WORKER=28;cs,dsend
  CITY city_id;
  COORD worker_x, worker_y;
end

PACKET_CITY_CHANGE_SPECIALIST=29;cs,dsend
  CITY city_id;
  SPECIALIST from, to;
end

PACKET_CITY_RENAME=30;cs,dsend
  CITY city_id;
  STRING name[MAX_LEN_NAME];
end

PACKET_CITY_OPTIONS_REQ=31;cs,dsend
  CITY city_id;
  BV_CITY_OPTIONS options;
end

PACKET_CITY_REFRESH=32;cs,dsend
  CITY city_id;
end

# 33-34 removed in 2.1

# For city name suggestions, client sends unit id of unit building the
# city.  The server does not use the id, but sends it back to the
# client so that the client knows what to do with the suggestion when
# it arrives back. (Currently, for city renaming, default is existing
# name; if wanted to suggest a new name, could do the same thing
# sending the city id as id, and only client needs to change.)
PACKET_CITY_NAME_SUGGESTION_REQ=35;cs,dsend
  UNIT unit_id;
end

PACKET_CITY_NAME_SUGGESTION_INFO=36;sc,dsend,lsend
  UNIT unit_id;
  STRING name[MAX_LEN_NAME];
end

PACKET_CITY_SABOTAGE_LIST=37;sc,lsend
  UNIT diplomat_id;
  CITY city_id;
  BV_IMPRS improvements;
end

/************** Player packets **********************/

PACKET_PLAYER_REMOVE=38; sc,dsend,lsend
  PLAYER player_id;
end

PACKET_PLAYER_INFO=39; sc
  PLAYER playerno; key 
  STRING name[MAX_LEN_NAME];
  STRING username[MAX_LEN_NAME];

  UINT32 score;
  BOOL is_male;
  GOVERNMENT government;
  GOVERNMENT target_government;
  BOOL embassy[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
  UINT8 city_style;
  NATION nation;
  TEAM team;
  BOOL is_ready;
  BOOL phase_done;
  TURN nturns_idle;
  BOOL is_alive;

  DIPLSTATE diplstates[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
  
  GOLD gold;
  PERCENT tax, science,luxury;

  UINT16 bulbs_last_turn;
  UINT32 bulbs_researched;
  UINT32 techs_researched;
  UINT8 researching;
  UINT16 science_cost;

  UINT16 future_tech;
  UINT8 tech_goal;
  BOOL is_connected;
  TURN revolution_finishes;
  BOOL ai;
  UINT8 ai_skill_level;
  UINT8 barbarian_type;
  VISION gives_shared_vision;
  BIT_STRING inventions[A_LAST+1];
  SINT16 love[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];

  UINT16 small_wonders[B_LAST]; diff
end

PACKET_PLAYER_PHASE_DONE=40;cs,dsend
  TURN turn;
end

PACKET_PLAYER_RATES=41;cs,dsend
  PERCENT tax, luxury, science;
end

PACKET_PLAYER_CHANGE_GOVERNMENT=43;cs,dsend
  GOVERNMENT government;
end

PACKET_PLAYER_RESEARCH=44;cs,dsend
  TECH tech;
end

PACKET_PLAYER_TECH_GOAL=45;cs,dsend
  TECH tech;
end

PACKET_PLAYER_ATTRIBUTE_BLOCK=46;cs
end

PACKET_PLAYER_ATTRIBUTE_CHUNK=47; pre-send, sc,cs,handle-via-packet
  UINT32 offset, total_length, chunk_length;
  /* to keep memory management simple don't allocate dynamic memory */
  MEMORY data[ATTRIBUTE_CHUNK_SIZE:chunk_length];
end

/************** Unit packets **********************/

PACKET_UNIT_REMOVE=48;sc,dsend,lsend
  UNIT unit_id;
end

PACKET_UNIT_INFO=49; sc,lsend
  UNIT id; key
  PLAYER owner;
  COORD x,y;
  CITY homecity;

  UINT8 veteran;
  BOOL ai, paradropped;
  BOOL transported, done_moving;

  UNIT_TYPE type;
  UNIT transported_by; /* Only valid if transported is set. */
  UINT8 movesleft, hp, fuel, activity_count;
  UINT8 unhappiness, upkeep[O_MAX], occupy;
  COORD goto_dest_x,goto_dest_y;
  ACTIVITY activity;
  SPECIAL activity_target;

  SINT8 battlegroup;

  BOOL has_orders;
  UINT16 orders_length, orders_index;
  BOOL orders_repeat, orders_vigilant;
  ORDERS orders[MAX_LEN_ROUTE:orders_length];
  DIRECTION orders_dirs[MAX_LEN_ROUTE:orders_length];
  ACTIVITY orders_activities[MAX_LEN_ROUTE:orders_length];
end

PACKET_UNIT_SHORT_INFO=50; sc,lsend
  UNIT id; key
  PLAYER owner;
  COORD x,y;
  UNIT_TYPE type;

  UINT8 veteran;
  BOOL occupied, goes_out_of_sight, transported;

  UINT8 hp, activity;
  UNIT transported_by; /* Only valid if transported is set. */

  /* in packet only, not in unit struct */
  UINT8 packet_use;	/* see enum unit_info_use */
  CITY info_city_id;	/* for UNIT_INFO_CITY_SUPPORTED
  			   and UNIT_INFO_CITY_PRESENT uses */
  UINT16 serial_num;	/* a 16-bit unsigned number, never zero
			   (not used by UNIT_INFO_IDENTITY) */
end

PACKET_UNIT_COMBAT_INFO=51; sc,lsend
  UNIT attacker_unit_id;
  UNIT defender_unit_id;
  HP attacker_hp;
  HP defender_hp;
  BOOL make_winner_veteran;
end

PACKET_UNIT_MOVE=52;cs,dsend
  UNIT unit_id;
  COORD x, y;
end

PACKET_UNIT_BUILD_CITY=53;cs,dsend
  UNIT unit_id;
  STRING name[MAX_LEN_NAME];
end

PACKET_UNIT_DISBAND=54;cs,dsend
  UNIT unit_id;
end

PACKET_UNIT_CHANGE_HOMECITY=55;cs,dsend
  UNIT unit_id;
  CITY city_id;
end

PACKET_UNIT_ESTABLISH_TRADE=56;cs,dsend
  UNIT unit_id;
end

PACKET_UNIT_BATTLEGROUP=117;cs,dsend
  UNIT unit_id;
  SINT8 battlegroup;
end

PACKET_UNIT_HELP_BUILD_WONDER=57;cs,dsend
  UNIT unit_id;
end

# used for client orders: currently client-side goto and patrol
PACKET_UNIT_ORDERS=59;cs
  UNIT unit_id;
  COORD src_x, src_y; # Origin tile, included for sanity checking

  UINT16 length;
  BOOL repeat, vigilant;
  ORDERS orders[MAX_LEN_ROUTE:length];
  DIRECTION dir[MAX_LEN_ROUTE:length];
  ACTIVITY activity[MAX_LEN_ROUTE:length];
  COORD dest_x, dest_y;
end

# Enable autosettlers for a unit.  Only works for settler units naturally.
PACKET_UNIT_AUTOSETTLERS=60;cs,dsend
  UNIT unit_id;
end

# Load the given cargo into the transporter.
PACKET_UNIT_LOAD=107;cs,dsend
  UNIT cargo_id, transporter_id;
end

# Unload the given cargo from the transporter.
PACKET_UNIT_UNLOAD=61;cs,dsend
  UNIT cargo_id, transporter_id;
end

PACKET_UNIT_UPGRADE=62;cs,dsend
  UNIT unit_id;
end

PACKET_UNIT_NUKE=63;cs,dsend
  UNIT unit_id;
end

PACKET_UNIT_PARADROP_TO=64;cs,dsend
  UNIT unit_id;
  COORD x, y;
end

PACKET_UNIT_AIRLIFT=65;cs,dsend
  UNIT unit_id;
  CITY city_id;
end

PACKET_UNIT_DIPLOMAT_QUERY=66;cs,handle-per-conn,dsend
  UNIT diplomat_id;
  UNIT target_id;   # city_id or unit_id target_id;
  SINT16 value;
  DIPLOMAT_ACTION action_type;
end

# 67-68 removed in 2.1

PACKET_UNIT_TYPE_UPGRADE=69;cs,dsend
  UNIT_TYPE type;
end

PACKET_UNIT_DIPLOMAT_ACTION=70;cs,dsend
  UNIT diplomat_id;
  UNIT target_id;   # city_id or unit_id target_id;
  SINT16 value;
  DIPLOMAT_ACTION action_type;
end

PACKET_UNIT_DIPLOMAT_ANSWER=71;sc,dsend,lsend
  UNIT diplomat_id;
  UNIT target_id;   # city_id or unit_id target_id;
  GOLD cost;
  DIPLOMAT_ACTION action_type;
end

PACKET_UNIT_CHANGE_ACTIVITY=72; cs,dsend
  UNIT unit_id;
  ACTIVITY activity;
  SPECIAL activity_target;
end

/************** Diplomacy packets **********************/

PACKET_DIPLOMACY_INIT_MEETING_REQ=73;cs,dsend
  PLAYER counterpart;
end

PACKET_DIPLOMACY_INIT_MEETING=74;sc,dsend,lsend
  PLAYER counterpart, initiated_from;
end

PACKET_DIPLOMACY_CANCEL_MEETING_REQ=75;cs,dsend
  PLAYER counterpart;
end

PACKET_DIPLOMACY_CANCEL_MEETING=76;sc,dsend,lsend
  PLAYER counterpart, initiated_from;
end

PACKET_DIPLOMACY_CREATE_CLAUSE_REQ=77;cs,dsend
  PLAYER counterpart, giver;
  CLAUSE type;
  UINT32 value;
end

PACKET_DIPLOMACY_CREATE_CLAUSE=78;sc,dsend,lsend
  PLAYER counterpart, giver;
  CLAUSE type;
  UINT32 value;
end

PACKET_DIPLOMACY_REMOVE_CLAUSE_REQ=79;cs,dsend
  PLAYER counterpart, giver;
  CLAUSE type;
  UINT32 value;
end

PACKET_DIPLOMACY_REMOVE_CLAUSE=80;sc,dsend,lsend
  PLAYER counterpart, giver;
  CLAUSE type;
  UINT32 value;
end

PACKET_DIPLOMACY_ACCEPT_TREATY_REQ=81;cs,dsend
  PLAYER counterpart;
end

PACKET_DIPLOMACY_ACCEPT_TREATY=82;sc,dsend,lsend
  PLAYER counterpart;
  BOOL I_accepted, other_accepted;
end

PACKET_DIPLOMACY_CANCEL_PACT=83;cs,dsend
  PLAYER other_player_id;
  CLAUSE clause;
end

/**************  Report packets **********************/

PACKET_PAGE_MSG=84;sc,lsend
  STRING message[MAX_LEN_MSG];
  EVENT event;
end

PACKET_REPORT_REQ=85;cs,handle-per-conn,dsend
  REPORT_TYPE type;
end

/************** Connection packets **********************/

# For telling clients information about other connections to server.
# Clients may not use all info, but supply now to avoid unnecessary
# protocol changes later.
PACKET_CONN_INFO=86; sc,lsend
  CONNECTION id; key

  # 0 means client should forget its
  # info about this connection
  BOOL used;
  BOOL established;
  BOOL observer;
  PLAYER player_num;
  CMDLEVEL access_level;
  STRING username[MAX_LEN_NAME];
  STRING addr[MAX_LEN_ADDR];
  STRING capability[MAX_LEN_CAPSTR];
end

# Information about the ping times of the connections.
PACKET_CONN_PING_INFO=87; sc,lsend
  UINT8 connections;
  CONNECTION conn_id[MAX_NUM_CONNECTIONS:connections];
  FLOAT10x7 ping_time[MAX_NUM_CONNECTIONS:connections];
end

PACKET_CONN_PING=88;sc
end

PACKET_CONN_PONG=89;cs,handle-per-conn
end

/************** New turn packets **********************/

PACKET_END_PHASE=90;sc,lsend
end

# sent to everyone, not just the player whose phase it is
PACKET_START_PHASE=91;sc,lsend,dsend
  PHASE phase;
end

# send to each client whenever the turn has ended.
PACKET_NEW_YEAR=92;sc,lsend
  YEAR year;
  TURN turn;
end

# Server has finished processing turn change
PACKET_BEGIN_TURN=137;sc,lsend
end

# Server starts processing turn change
PACKET_END_TURN=138;sc,lsend
end

# Freeze reports and agents
PACKET_FREEZE_CLIENT=135;sc,lsend
end

# Thaw reports and agents
PACKET_THAW_CLIENT=136;sc,lsend
end

/************** Spaceship packets **********************/

PACKET_SPACESHIP_LAUNCH=93;cs
end

PACKET_SPACESHIP_PLACE=94;cs,dsend
  PLACE_TYPE type;

  # Meaning of num:
  #  - if type==SSHIP_ACT_PLACE_STRUCTURAL: 
  #      index to sship->structure[]
  #  - if type!=SSHIP_ACT_PLACE_STRUCTURAL:
  #      new value for sship->fuel etc; should be just one more than
  #      current value of ship->fuel etc Used to avoid possible
  #      problems if we send duplicate packets when client
  #      auto-builds?
  UINT8 num;
end

PACKET_SPACESHIP_INFO=95; sc,lsend
  PLAYER player_num; key
  UINT8 sship_state;
  UINT8 structurals;
  UINT8 components;
  UINT8 modules;
  UINT8 fuel;
  UINT8 propulsion;
  UINT8 habitation;
  UINT8 life_support;
  UINT8 solar_panels;
  YEAR launch_year;
  UINT32 population;
  UINT32 mass;
  BIT_STRING structure[NUM_SS_STRUCTURALS+1];
  FLOAT support_rate;
  FLOAT energy_rate;
  FLOAT success_rate;
  FLOAT travel_time;
end

/************** Ruleset packets **********************/

PACKET_RULESET_UNIT=96;sc,lsend
  UNIT_TYPE id;
  STRING name[MAX_LEN_NAME];
  STRING graphic_str[MAX_LEN_NAME];
  STRING graphic_alt[MAX_LEN_NAME];
  STRING sound_move[MAX_LEN_NAME];
  STRING sound_move_alt[MAX_LEN_NAME];
  STRING sound_fight[MAX_LEN_NAME];
  STRING sound_fight_alt[MAX_LEN_NAME];
  UINT8 move_type;
  UINT8 unit_class_id;
  UINT16 build_cost;
  UINT8 pop_cost;
  UINT8 attack_strength;
  UINT8 defense_strength;
  UINT8 move_rate;
  TECH tech_requirement;
  UINT8 impr_requirement;
  GOVERNMENT gov_requirement;
  UINT16 vision_radius_sq;
  UINT8 transport_capacity;
  UINT8 hp;
  UINT8 firepower;
  SINT8 obsoleted_by;
  UINT8 fuel;

  UINT8 happy_cost;   # unhappy people in home city
  UINT8 upkeep[O_MAX]; # normal upkeep cost (food, gold, shields)

  UINT8 paratroopers_range;  # max range of paratroopers, F_PARATROOPERS
  UINT8 paratroopers_mr_req;
  UINT8 paratroopers_mr_sub;

  STRING veteran_name[MAX_VET_LEVELS][MAX_LEN_NAME];
  FLOAT power_fact[MAX_VET_LEVELS];
  UINT8 move_bonus[MAX_VET_LEVELS];

  UINT8 bombard_rate;

  STRING helptext[MAX_LEN_PACKET];

  BV_FLAGS flags;
  BV_ROLES roles;
end

PACKET_RULESET_GAME=97;sc,lsend
  UINT8 default_specialist;

  TECH_LIST global_init_techs[MAX_NUM_TECH_LIST];
  UINT8 trireme_loss_chance[MAX_VET_LEVELS];
  UINT8 work_veteran_chance[MAX_VET_LEVELS];
  UINT8 veteran_chance[MAX_VET_LEVELS];
end

PACKET_RULESET_SPECIALIST=58;sc,lsend
  SPECIALIST id;
  STRING name[MAX_LEN_NAME];
  STRING short_name[MAX_LEN_NAME];
  UINT8 reqs_count;
  REQUIREMENT reqs[MAX_NUM_REQS:reqs_count];
end

PACKET_RULESET_GOVERNMENT_RULER_TITLE=98;sc,lsend
  GOVERNMENT gov;
  UINT8 id;
  NATION nation;
  STRING male_title[MAX_LEN_NAME];
  STRING female_title[MAX_LEN_NAME];
end

PACKET_RULESET_TECH=99;sc,lsend
  TECH id;
  TECH req[2];
  TECH root_req;
  UINT32 flags, preset_cost, num_reqs;
  STRING name[MAX_LEN_NAME];
  STRING helptext[MAX_LEN_PACKET];
  STRING graphic_str[MAX_LEN_NAME];
  STRING graphic_alt[MAX_LEN_NAME];
end

PACKET_RULESET_GOVERNMENT=100;sc,lsend
  GOVERNMENT id;

  UINT8 reqs_count;
  REQUIREMENT reqs[MAX_NUM_REQS:reqs_count];

  UINT8 num_ruler_titles;
       
  STRING name[MAX_LEN_NAME];
  STRING graphic_str[MAX_LEN_NAME];
  STRING graphic_alt[MAX_LEN_NAME];
  STRING helptext[MAX_LEN_PACKET];
end

PACKET_RULESET_TERRAIN_CONTROL=101;sc,lsend
  BOOL may_road;       /* may build roads/railroads */
  BOOL may_irrigate;   /* may build irrigation/farmland */
  BOOL may_mine;       /* may build mines */
  BOOL may_transform;  /* may transform terrain */

  /* parameters */
  UINT8 ocean_reclaim_requirement_pct; /* # adjacent land tiles for reclaim */
  UINT8 land_channel_requirement_pct; /* # adjacent ocean tiles for channel */
  RIVER_MOVE river_move_mode;

  SINT16 river_defense_bonus;           /* % added to defense if Civ2 river */
  UINT16 river_trade_incr;              /* added to trade if Civ2 river */
  STRING river_help_text[MAX_LEN_PACKET]; # help for Civ2-style rivers

  SINT16 fortress_defense_bonus;        /* % added to defense if fortress */
  UINT16 road_superhighway_trade_bonus;  # % added to trade if road/s-highway
  UINT16 rail_tile_bonus[O_MAX];        /* % added to output if railroad */
  UINT8 pollution_tile_penalty[O_MAX]; /* % taken from output if polluted */
  UINT8 fallout_tile_penalty[O_MAX]; /* % taken from output if polluted */
end

PACKET_RULESET_NATION_GROUPS=118;sc,lsend
  UINT8 ngroups;
  STRING groups[MAX_NUM_NATION_GROUPS:ngroups][MAX_LEN_NAME];
end

PACKET_RULESET_NATION=102;sc,lsend
  NATION id; key

  STRING name[MAX_LEN_NAME];
  STRING name_plural[MAX_LEN_NAME];
  STRING graphic_str[MAX_LEN_NAME];
  STRING graphic_alt[MAX_LEN_NAME];
  STRING legend[MAX_LEN_MSG];

  UINT8 city_style;
  TECH_LIST init_techs[MAX_NUM_TECH_LIST];
  UNIT_TYPE init_units[MAX_NUM_UNIT_LIST];
  IMPROVEMENT init_buildings[MAX_NUM_BUILDING_LIST];
  GOVERNMENT init_government;

  UINT8 leader_count;
  STRING leader_name[MAX_NUM_LEADERS:leader_count][MAX_LEN_NAME];
  BOOL leader_sex[MAX_NUM_LEADERS:leader_count];

  BOOL is_available, is_playable, is_barbarian;
  
  UINT8 ngroups;
  UINT8 groups[MAX_NUM_NATION_GROUPS:ngroups];
end

PACKET_RULESET_CITY=103;sc,lsend
  UINT8 style_id; 
  STRING name[MAX_LEN_NAME];
  STRING citizens_graphic[MAX_LEN_NAME];
  STRING citizens_graphic_alt[MAX_LEN_NAME];
  UINT8 reqs_count;
  REQUIREMENT reqs[MAX_NUM_REQS:reqs_count];
  STRING graphic[MAX_LEN_NAME];
  STRING graphic_alt[MAX_LEN_NAME];
  SINT8 replaced_by;
end

PACKET_RULESET_BUILDING=104;sc,lsend
  IMPROVEMENT id;
  IMPR_GENUS genus;
  STRING name[MAX_LEN_NAME];
  STRING graphic_str[MAX_LEN_NAME];
  STRING graphic_alt[MAX_LEN_NAME];
  UINT8 reqs_count;
  REQUIREMENT reqs[MAX_NUM_REQS:reqs_count];
  TECH obsolete_by;
  IMPROVEMENT replaced_by;
  UINT16 build_cost;
  UINT8 upkeep, sabotage;
  UINT16 flags;
  STRING soundtag[MAX_LEN_NAME];
  STRING soundtag_alt[MAX_LEN_NAME];
  STRING helptext[MAX_LEN_PACKET];
end

PACKET_RULESET_TERRAIN=105;sc,lsend
  TERRAIN id;

  BV_TERRAIN_FLAGS flags;

  STRING name_orig[MAX_LEN_NAME];
  STRING graphic_str[MAX_LEN_NAME];
  STRING graphic_alt[MAX_LEN_NAME];

  UINT8 movement_cost;
  SINT16 defense_bonus;

  UINT8 output[O_MAX];
  UINT8 num_resources;
  RESOURCE resources[MAX_NUM_RESOURCES:num_resources];

  UINT8 road_trade_incr;
  UINT8 road_time;

  TERRAIN irrigation_result;
  UINT8 irrigation_food_incr;
  UINT8 irrigation_time;

  TERRAIN mining_result;
  UINT8 mining_shield_incr;
  UINT8 mining_time;

  TERRAIN transform_result;
  UINT8 transform_time;
  UINT8 rail_time;
  UINT8 airbase_time;
  UINT8 fortress_time;
  UINT8 clean_pollution_time;
  UINT8 clean_fallout_time;
  
  STRING helptext[MAX_LEN_PACKET];
end

/*********************************************************
  Ruleset control values: single values, some of which are
  needed before sending other ruleset data (eg,
  num_unit_types, government_count).  This is only sent
  once at the start of the game, eg unlike game_info which
  is sent again each turn.  (Terrain ruleset has enough
  info for its own "control" packet, done separately.)
*********************************************************/
PACKET_RULESET_CONTROL=106;sc,lsend
  UINT8 num_unit_types;
  UINT8 num_impr_types;
  UINT8 num_tech_types;
  UINT8 government_count;
  UINT8 nation_count;
  UINT8 styles_count;
  UINT8 terrain_count;
  UINT8 resource_count;
  UINT8 num_specialist_types;

  STRING prefered_tileset[MAX_LEN_NAME];
end

/*********************************************************
 Below are the packets that control single-player mode.  
*********************************************************/
PACKET_SINGLE_WANT_HACK_REQ=108;cs,handle-per-conn,handle-via-packet
 STRING token[MAX_LEN_NAME];
end

PACKET_SINGLE_WANT_HACK_REPLY=109;sc,dsend
 BOOL you_have_hack;
end

PACKET_RULESET_CHOICES=115;sc
  UINT8 ruleset_count;
  STRING rulesets[MAX_NUM_RULESETS:ruleset_count][MAX_RULESET_NAME_LENGTH];
end

PACKET_GAME_LOAD=111;sc,handle-via-packet,lsend
  BOOL load_successful;
  UINT8 nplayers;
  STRING load_filename[MAX_LEN_PACKET];
  STRING name[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME]; 
  STRING username[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME]; 
  NATION nations[MAX_NUM_PLAYERS:nplayers];
  BOOL is_alive[MAX_NUM_PLAYERS:nplayers];
  BOOL is_ai[MAX_NUM_PLAYERS:nplayers];
end

PACKET_OPTIONS_SETTABLE_CONTROL=112;sc,handle-via-packet,lsend
  UINT16 num_settings;
  UINT8 num_categories;
  STRING category_names[256:num_categories][MAX_LEN_NAME];
end

PACKET_OPTIONS_SETTABLE=113;sc,lsend
  UINT16 id;
  STRING name[MAX_LEN_NAME];
  STRING short_help[MAX_LEN_PACKET];
  STRING extra_help[MAX_LEN_PACKET];

  SSET_TYPE type;
  SSET_CLASS class;
  BOOL is_visible;

  SINT32 val;					/* value for bool or int */
  SINT32 default_val;				/* default for bool or int */
  SINT32 min;					/* min value for int */
  SINT32 max;					/* max value for int */

  STRING strval[MAX_LEN_PACKET];		/* space for string */
  STRING default_strval[MAX_LEN_PACKET];	/* space for string */

  UINT8 category;				/* which category this is in */
end

/************** Effects hash packets **********************/

PACKET_RULESET_EFFECT=122;sc,lsend
  EFFECT_TYPE effect_type;
  SINT32 effect_value;
end

PACKET_RULESET_EFFECT_REQ=123;sc,lsend
  UINT32 effect_id;
  BOOL neg;
	
  REQ_TYPE source_type;
  SINT32 source_value;

  REQ_RANGE range;
  BOOL survives;
  BOOL negated;
end

PACKET_RULESET_RESOURCE=124;sc,lsend
  RESOURCE id;
  
  STRING name_orig[MAX_LEN_NAME];
  UINT8 output[O_MAX];
  STRING graphic_str[MAX_LEN_NAME];
  STRING graphic_alt[MAX_LEN_NAME];
end
