/* Main include file for Xconq.
   Copyright (C) 1991-2000 Stanley T. Shebs.

Xconq is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.  See the file COPYING.  */

/* This is the include file that nearly all Xconq source files
   should include (exceptions would be very low-level or generic
   sources). */

#include "config.h"
#include "misc.h"
#include "dir.h"
#include "lisp.h"
#include "module.h"
#include "game.h"
#include "player.h"
#include "side.h"
#include "unit.h"
#include "world.h"
#include "history.h"
#include "score.h"
#include "help.h"
#include "tp.h"
#include "system.h"

/* Elements of bitmask controlling display updates. */

#define UPDATE_ALWAYS 1
#define UPDATE_ADJ 2
#define UPDATE_COVER 4
#define UPDATE_TEMP 8
#define UPDATE_CLOUDS 16
#define UPDATE_WINDS 32

/* The several stages of game setup. */

enum setup_stage {
    initial_stage,
    game_load_stage,
    variant_setup_stage,
    player_pre_setup_stage,
    player_setup_stage,
    game_ready_stage
};

extern enum setup_stage current_stage;

/* Declarations of globally visible globals. */

extern int gamedefined;
extern int gameinited;
extern int compromised;
extern int beforestart;
extern int endofgame;
extern int gamestatesafe;
extern int any_post_action_scores;
extern short any_people_side_changes;
extern int max_zoc_range;
extern int warnings_suppressed;
extern time_t game_start_in_real_time;
extern time_t turn_play_start_in_real_time;

extern short *u_possible;

extern int checkpoint_interval;
extern int statistics_wanted;
extern int numsoundplays;

extern int allbedesigners;

extern int tmphevtdata1;
extern int max_detonate_on_approach_range;
extern int max_u_detonate_effect_range;
extern int max_t_detonate_effect_range;

extern int xmalloc_warnings;
extern int memory_exhausted;
extern Feature *featurelist;
extern Doctrine *doctrine_list;

extern char *curdatestr;

extern int sunx, suny;

extern int daynight;
extern int area_lighting;

extern int warnings_logged;

/* Declarations of functions that must be supplied by an interface. */

extern void announce_read_progress(void);
extern void announce_lengthy_process(char *msg);
extern void announce_progress(int pctdone);
extern void finish_lengthy_process(void);

extern Player *add_default_player(void);

extern UnitVector *get_selected_units(Side *side);

extern void init_ui(Side *side);

extern int active_display(Side *side);

extern void update_turn_display(Side *side, int rightnow);
extern void update_area_display(Side *side);
extern void update_action_display(Side *side, int rightnow);
extern void update_action_result_display(Side *side, Unit *unit, int rslt, int rightnow);
extern void update_event_display(Side *side, HistEvent *hevt, int rightnow);
extern void update_fire_at_display(Side *side, Unit *unit, Unit *unit2, int m, int rightnow);
extern void update_fire_into_display(Side *side, Unit *unit, int x, int y, int z, int m, int rightnow);
extern void update_clock_display(Side *side, int rightnow);
extern void update_side_display(Side *side, Side *side2, int rightnow);
extern void update_unit_display(Side *side, Unit *unit, int rightnow);
extern void update_unit_acp_display(Side *side, Unit *unit, int rightnow);
extern void update_message_display(Side *side, Side *side2, char *str, int rightnow);
extern void update_cell_display(Side *side, int x, int y, int flags);
extern void update_all_progress_displays(char *str, int s);
extern void update_everything(void);
extern void flush_display_buffers(Side *side);

extern int schedule_movie(Side *side, char *movie, ...);
extern void play_movies(SideMask sidemask);

extern void action_point(Side *side, int x, int y);

extern void notify_all(char *str, ...);
extern void notify(Side *side, char *str, ...);
extern void vnotify(Side *side, char *fmt, va_list ap);
extern void low_notify(Side *side, char *str);

extern void init_warning(char *str, ...);
extern void low_init_warning(char *str);
extern void init_error(char *str, ...);
extern void low_init_error(char *str);
extern void run_warning(char *str, ...);
extern void low_run_warning(char *str);
extern void run_error(char *str, ...);
extern void low_run_error(char *str);

extern void print_form(Obj *form);
extern void end_printing_forms(void);

extern void unit_research_dialog(Unit *unit);

extern void close_displays(void);

/* Declarations of functions not elsewhere declared. */

/* actions.c */

extern void init_actions(void);
extern int transfer_supply(Unit *from, Unit *to, int m, int amount);
extern void garrison_unit(Unit *unit, Unit *unit2);
extern void make_unit_complete(Unit *unit);
extern int execute_action(Unit *unit, Action *action);
extern int can_have_enough_acp(Unit *unit, int acp);
extern int has_enough_acp(Unit *unit, int acp);
extern int has_supply_to_act(Unit *unit);
extern void use_up_acp(Unit *unit, int acp);
extern int construction_possible(int u2);
extern int any_construction_possible(void);
extern int storage_possible(int m);
extern int any_storage_possible(void);
extern char *action_desig(Action *act);

/* ai.c */

extern void init_ai(Side *side);
extern void init_ai_types(void);
extern void ai_init_shared(void);
extern int find_ai_type(char *typename);
extern void set_side_ai(Side *side, char *typename);
extern int run_local_ai(int when, int maxplanning);
extern char *ai_type_name(int n);
extern char *next_ai_type_name(char *typename);
extern char *ai_type_help(int n);
extern void ai_react_to_new_side(Side *side, Side *side2);
extern void ai_receive_message(Side *side, Side *sender, char *str);
extern void ai_save_state(Side *side);
extern int ai_region_at(Side *side, int x, int y);
extern char *ai_at_desig(Side *side, int x, int y);
extern Goal *create_goal(GoalType type, Side *side, int tf);
extern char *goal_desig(Goal *goal);

/* combat.c */

extern int can_attack(Unit *unit);
extern int type_can_attack(int u);
extern int can_fire(Unit *unit);
extern int type_can_fire(int u);
extern int type_can_capture(int u);
extern int can_detonate(Unit *unit);
extern int can_capture_directly(Unit *unit);
extern int type_can_capture_directly(int u);
extern int type_can_carry(int u);
extern int defended_by_occupants(Unit *unit);
extern int occ_can_defend_transport(int o, int t);
extern int enough_to_garrison(Unit *unit, int defenders);
extern int capture_chance(int u, int u2, Side *side2);
extern int could_hit(int u1, int u2);

/* init.c */

extern void init_library_path(char *path);
extern void init_data_structures(void);
extern void start_game_load_stage(void);
extern void start_variant_setup_stage(void);
extern void start_player_pre_setup_stage(void);
extern void start_player_setup_stage(void);
extern void start_game_ready_stage(void);
extern void check_game_validity(void);
extern void calculate_globals(void);
extern void patch_object_references(void);
extern void make_trial_assignments(void);
extern Side *make_up_a_side(void);
extern int add_side_and_player(void);
extern int remove_side_and_player(void);
extern void run_synth_methods(void);
extern void final_init(void);
extern void init_supply(Unit *unit);
extern void assign_players_to_sides(void);
extern char *version_string(void);
extern char *copyright_string(void);
extern char *license_string(void);
extern int already_seen_chance(Side *side, Unit *unit);
extern int get_synth_method_uses(int methkey, int *calls, int *runs);
extern int indepside_needed(void);

/* mknames.c */

extern Obj *make_namer(Obj *sym, Obj *meth);
extern void init_namers(void);
extern void make_up_side_name(Side *side);
extern int name_in_use(Side *side, char *str);
extern int name_units_randomly(int calls, int runs);
extern char *unit_namer(Unit *unit);
extern char *propose_unit_name(Unit *unit);
extern void make_up_unit_name(Unit *unit);
extern void assign_unit_number(Unit *unit);
extern char *run_namer(Obj *namer);

/* mkrivers.c */

extern int make_rivers(int calls, int runs);

/* mkroads.c */

extern int make_roads(int calls, int runs);

/* mkterr.c */

extern int make_fractal_terrain(int calls, int runs);
extern int make_random_terrain(int calls, int runs);
extern int make_earthlike_terrain(int calls, int runs);
extern int make_maze_terrain(int calls, int runs);
extern int name_geographical_features(int calls, int runs);
extern void add_edge_terrain(void);

/* mkunits.c */

extern int make_countries(int calls, int runs);
extern int make_independent_units(int calls, int runs);

/* move.c */

extern int total_move_cost(int u, int u2, int x1, int y1, int z1, int x2, int y2, int z2);
extern int zoc_move_cost(Unit *unit, int ox, int oy, int oz);
extern int sides_allow_entry(Unit *unit, Unit *transport);
extern int in_blocking_zoc(Unit *unit, int x, int y, int z);
extern int can_move_at_all(Unit *unit);
extern int can_move_via_conn(Unit *unit, int nx, int ny);
extern int unit_speed(Unit *unit, int nx, int ny);
extern int terrain_always_impassable(int u, int t);

/* nlang.c */

extern void init_nlang(void);
extern char *short_side_title(Side *side);
extern char *shortest_side_title(Side *side2, char *buf);
extern char *long_player_title(char *buf, Player *player,
			       char *thisdisplayname);
extern char *short_player_title(char *buf, Player *player,
				char *thisdisplayname);
extern char *unit_handle(Side *side, Unit *unit);
extern char *short_unit_handle(Unit *unit);
extern char *medium_long_unit_handle(Unit *unit);
extern void name_or_number(Unit *unit, char *buf);
extern char *apparent_unit_handle(Side *side, Unit *unit, Side *side2);
extern void construction_desc(char *buf, Unit *unit, int u);
extern void research_desc(char *buf, Unit *unit, int a);
extern void researchible_desc(char *buf, Unit *unit, int a);
extern void constructible_desc(char *buf, Side *side, int u, Unit *unit);
extern void historical_event_desc(Side *side, HistEvent *hevt, char *buf);
extern char *action_result_desc(int rslt);
extern void advance_failure_desc(char *buf, Unit *unit, HistEventType reason);
extern char *feature_desc(Feature *feature, char *buf);
extern void size_desc(char *buf, Unit *unit, int label);
extern void hp_desc(char *buf, Unit *unit, int label);
extern void acp_desc(char *buf, Unit *unit, int label);
extern void cxp_desc(char *buf, Unit *unit, int label);
extern void morale_desc(char *buf, Unit *unit, int label);
extern void point_value_desc(char *buf, Unit *unit, int label);
extern void plan_desc(char *buf, Unit *unit);
extern void task_desc(char *buf, Side *side, Unit *unit, Task *task);
extern void time_desc(char *buf, int time, int maxtime);
extern void notify_doctrine(Side *side, char *spec);
extern void report_combat(Unit *unit, Unit *atker, char *str);
extern void report_give(Side *side, Unit *unit, Unit *unit2, short *rslts);
extern void report_take(Side *side, Unit *unit, int needed, short *rslts);
extern char *ordinal_suffix(int n);
extern char *plural_form(char *word);
extern char *capitalize(char *buf);
extern char *absolute_date_string(int date);
extern void write_unit_record(FILE *fp, Side *side);
extern void write_side_results(FILE *fp, Side *side);
extern void write_combat_results(FILE *fp, Side *side);
extern void dice_desc(char *buf, int dice);
extern void record_missing_image(int typtyp, char *str);
extern int missing_images(char *buf);
extern void notify_all_of_resignation(Side *side, Side *side2);
extern int short_side_title_plural_p(Side *side);
extern char *side_score_desc(char *buf, Side *side, Scorekeeper *sk);
extern void location_desc(char *buf, Side *side, Unit *unit, int u,
			  int x, int y);
extern void destination_desc(char *buf, Side *side, Unit *unit,
			     int x, int y, int z);
extern int supply_desc(char *buf, Unit *unit, int mrow);
extern int tooling_desc(char *buf, Unit *unit);
extern char *sidemask_desc(char *buf, SideMask sidemask);
extern void latlong_desc(char *buf, int x, int y, int xf, int yf, int which);
extern void others_here_desc(char *buf, Unit *unit);
extern void occupants_desc(char *buf, Unit *unit);
extern void set_initial_date(char *str);
extern int find_event_type(Obj *sym);
extern int pattern_matches_event(Obj *pattern, HistEvent *hevt);
extern void event_desc_from_list(Side *side, Obj *lis, HistEvent *hevt,
				 char *buf);
extern int turns_between(char *str1, char *str2);
extern char *goal_desc(char *buf, Goal *goal);
extern char *feature_name_at(int x, int y);
extern void linear_desc(char *buf, int x, int y);
extern void elevation_desc(char *buf, int x, int y);
extern void temperature_desc(char *buf, int x, int y);

/* plan.c */

	/* called by ais - should not be in plan.c. */

extern int victim_here(int x, int y);
extern int target_here(int x, int y);
extern int useful_captureable_here(int x, int y);
extern int est_completion_time(Unit *unit, int u2);
extern char *plan_desig(Plan *plan);
extern int low_on_supplies_one(Unit *unit);
extern int low_on_ammo_one(Unit *unit);

	/* called by take_supplies in ui.c (should not be in ui.c). */

extern int past_halfway_point(Unit *unit);

	/* called by skelconq which should not do that. */

extern void make_plausible_random_args(char *argtypestr, int i, int *args, Unit *unit);

/* read.c */

extern void type_error(Obj *x, char *msg);
extern void interp_form(Module *module, Obj *form);
extern void interp_game_module(Obj *form, Module *module);
extern void fill_in_side(Side *side, Obj *props, int userdata);
extern void read_warning(char *str, ...);
extern int utype_from_name(char *str);
extern int utype_from_symbol(Obj *sym);
extern int mtype_from_name(char *str);
extern int ttype_from_name(char *str);
extern int atype_from_name(char *str);
extern int lookup_task_type(char *name);

/* run.c */

extern void init_run(void);
extern int run_game(int maxactions);
extern int realtime_game(void);
extern int all_others_willing_to_save(Side *side);
extern int all_others_willing_to_quit(Side *side);
extern void end_the_game(void);
extern void update_canresearch_vector(Side *side);
extern void update_canbuild_vector(Side *side);
extern void kick_out_enemy_users(Side *side, int x, int y);
extern void set_play_rate(int slow, int fast);
extern int production_at(int x, int y, int m);
extern void auto_pick_unit_research(Unit *unit);
extern void auto_pick_side_research(Side *side);

/* run2.c */

extern int people_surrender_chance(int u, int x, int y);
extern void update_cell_display_all_sides(int x, int y, int flags);
extern void try_sharing(Unit *from, Unit *to, int m);
extern int damaged_acp(Unit *unit, Obj *effect);
extern void compute_acp(Unit *unit);
extern int people_surrender_chance(int u, int x, int y);
extern void parse_player_spec(Player *player, char *spec);

/* supply.c */

extern void run_supply(void);
extern int supply_system_in_use(void);

/* task.c */

	/* called by the ais - should not be in task.c. */

extern int choose_move_dirs(Unit *unit, int tx, int ty, int shortest, int (*dirtest)(Unit *, int), void (*dirsort)(Unit *, int *, int), int *dirs);
extern int plausible_move_dir(Unit *unit, int dir);
extern Unit *find_unit_to_complete(Unit *unit, Task *task);
extern int real_capture_chance(Unit *unit, Unit *unit2);
extern int attack_can_damage_or_capture(Unit *unit, Unit *unit2);
extern int fire_can_damage_or_capture(Unit *unit, Unit *unit2);

	/* called by skelconq - which should not do that. */

extern Task *create_task(TaskType type);

/* write.c */

extern void init_write(void);
extern int write_game_module(Module *module);
