/* Main include file for Xconq.
   Copyright (C) 1991-1999 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

/* Declarations of globally visible globals. */

extern int typesdefined;
extern int gamedefined;
extern int compromised;
extern int cursequence;
extern int beforestart;
extern int endofgame;
extern int gamestatesafe;
extern int interfacestatesafe;
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 short daynight;

/* 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 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, ...);
#ifdef ANSI_PROTOTYPES
extern void vnotify(Side *side, char *fmt, va_list ap);
#endif
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 close_displays(void);

/* Declarations of functions not elsewhere declared. */

/* init.c */

extern void init_library_path(char *path);
extern void init_data_structures(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 void init_side_advantage(Side *side);
extern int add_side_and_player(void);
extern int exchange_players(int n, int n2);
extern int remove_side_and_player(void);
extern void run_synth_methods(void);
extern int make_random_date(int calls, int runs);
extern int make_weather(int calls, int runs);
extern void final_init(void);
extern void configure_sides(void);
extern void init_all_views(void);
extern int make_initial_materials(int calls, int runs);
extern void init_supply(Unit *unit);
extern int saved_game(void);
extern void init_side_balance(void);
extern void check_consistency(void);
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);

/* read.c */

extern void syntax_error(Obj *x, char *msg);
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 do_module_variants(Module *module, Obj *lis);
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);

/* actions.c */
extern int can_extract_at(Unit *unit, int x, int y, int *mp);
extern int can_load_at(Unit *unit, int x, int y, int *mp);
extern void init_actions(void);
extern int can_move_via_conn(Unit *unit, int nx, int ny);
extern int can_occupy_conn(Unit *unit, int nx, int ny, int nz);
extern int can_move_at_all(Unit *unit);
extern int in_blocking_zoc(Unit *unit, int x, int y, int z);
extern int unit_blockable_by(Unit *unit, Unit *unit2);
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 total_entry_cost(int u1, int u3, int x1, int y1, int z1, int u2, int x2, int y2, int z2);
extern int transfer_supply(Unit *from, Unit *to, int m, int amount);
extern void adjust_tech_crossover(Side *side, int u);
extern void adjust_tooling_crossover(Unit *unit, int u2);
extern void garrison_unit(Unit *unit, Unit *unit2);
extern void make_unit_complete(Unit *unit);
extern void distribute_material(Unit *unit, int m, int amt);
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 people_surrender_chance(int u, int x, int y);
extern void detonate_on_approach_around(Unit *unit);
extern int unit_speed(Unit *unit, int nx, int ny);
extern int zoc_range(Unit *unit, int u2);
extern int damaged_value(Unit *unit, Obj *effect, int maxval);

extern int can_develop(Unit *unit);
extern int type_can_develop(int u);
extern int can_toolup(Unit *unit);
extern int type_can_toolup(int u);
extern int can_create(Unit *unit);
extern int type_can_create(int u);
extern int can_complete(Unit *unit);
extern int type_can_complete(int u);
extern int can_repair(Unit *unit);
extern int type_can_repair(int u);
extern int can_change_type(Unit *unit);
extern int type_can_change_type(int u);
extern int can_disband(Unit *unit);
extern int type_can_disband(int u);
extern int side_can_disband(Side *side, Unit *unit);
extern int can_add_terrain(Unit *unit);
extern int type_can_add_terrain(int u);
extern int can_remove_terrain(Unit *unit);
extern int type_can_remove_terrain(int u);
extern int any_construction_possible(void);
extern char *action_desig(Action *act);

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 occ_can_defend_transport(int o, int t);
extern int found_blocking_elevation(int u, int ux, int uy, int uz, int u2, int u2x, int u2y, int u2z);
extern int enough_ammo(Unit *unit, Unit *other);
extern int capture_chance(int u, int u2, Side *side2);
extern int multiply_dice(int dice, int mult);

/* run.c */

extern void init_run(void);
extern int run_game(int maxactions);
extern int run_local_ai(int when, int maxplanning);
extern void test_for_game_start(void);
extern void test_for_game_end(void);
extern int damaged_acp(Unit *unit, Obj *effect);
extern int all_sides_finished(void);
extern void check_realtime(void);
extern int exceeded_rt_for_game(void);
extern int exceeded_rt_per_turn(void);
extern void compute_acp(Unit *unit);
extern int units_still_acting(Side *side);
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 int people_surrender_chance(int u, int x, int y);
extern int unit_priority(Unit *unit);
extern int num_people_at(int x, int y);

extern void parse_player_spec(Player *player, char *spec);

extern int get_synth_method_uses(int methkey, int *calls, int *runs);

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

/* run2.c */

extern void update_cell_display_all_sides(int x, int y, int flags);
extern void update_side_display_all_sides(Side *side, int rightnow);

/* 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);

/* mkrivers.c */

extern int make_rivers(int calls, int runs);

/* mkroads.c */

extern int make_roads(int calls, int runs);

/* 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);
extern char *name_from_grammar(Obj *grammar);
extern void gen_name(Obj *nonterm, Obj *rules, int depth, char *rslt);
extern void gen_from_rule(Obj *rule, Obj *rules, int depth, char *rslt);

/* nlang.c */

extern void init_nlang(void);
extern void pad_out(char *buf, int n);
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 void side_and_type_name(char *buf, Side *side, int u, Side *side2);
extern char *unit_handle(Side *side, Unit *unit);
extern char *short_unit_handle(Unit *unit);
extern void name_or_number(Unit *unit, char *buf);
extern void construction_desc(char *buf, Unit *unit, int u);
extern void constructible_desc(char *buf, Side *side, int u, Unit *unit);
extern int est_completion_time(Unit *unit, int u2);
extern void historical_event_date_desc(HistEvent *hevt, char *buf);
extern void historical_event_desc(Side *side, HistEvent *hevt, char *buf);
extern char *action_result_desc(int rslt);
extern void linear_desc(char *buf, int x, int y);
extern void elevation_desc(char *buf, int x, int y);
extern char *feature_desc(Feature *feature, char *buf);
extern char *feature_name_at(int x, int y);
extern void temperature_desc(char *buf, int x, int y);
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 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 char *summarize_units(char *buf, int *ucnts);
extern void notify_doctrine(Side *side, char *spec);
extern void report_combat(Unit *unit, Unit *atker, char *str);
extern void report_take(Side *side, Unit *unit, int needed, short *rslts);
extern char *exit_commentary(Side *side);
extern char *ordinal_suffix(int n);
extern char *plural_form(char *word);
extern char *make_text(char *buf, Obj *maker, long a1, long a2, long a3, long a4);
extern char *absolute_date_string(int date);
extern char *relative_date_string(int date, int base);
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 char *past_unit_handle(Side *side, PastUnit *past_unit);
extern char *short_past_unit_handle(PastUnit *past_unit);
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 *short_side_title_with_adjective(Side *side, char *adjective);
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 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);

/* module.c */

extern void doublecheck_state(Side *side);
extern void set_u_internal_name(int u, char *s);
extern void set_u_type_name(int u, char *s);
extern void set_m_type_name(int m, char *s);
extern void set_t_type_name(int t, char *s);
extern void set_a_type_name(int a, char *x);

extern int coerce_to_side_id(Obj *x);
extern Side *coerce_to_side(Obj *x);
extern int coerce_to_unit_id(Obj *x);
extern Unit *coerce_to_unit(Obj *x);

/* write.c */

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

/* (should organize) */

extern int total_gain(Side *side, int u);
extern int total_loss(Side *side, int u);

extern int lookup_plan_type(char *name);
extern int lookup_task_type(char *name);
extern int lookup_goal_type(char *name);

extern void set_play_rate(int slow, int fast);
extern int n_ms_elapsed(int n);
extern void record_ms(void);
extern int all_human_only_sides_finished(void);

extern int get_synth_method_uses(int methkey, int *calls, int *runs);
extern void set_initial_date(char *str);
extern int turns_between(char *str1, char *str2);
extern int visible_to(Unit *unit, Unit *unit2);

extern int construction_possible(int u2);
extern int can_build_or_help(Unit *unit);
extern int can_build_or_help(Unit *unit);
extern int can_produce(Unit *unit);
extern void add_to_unit_hp(Unit *unit, int hp);
extern void try_sharing(Unit *from, Unit *to, int m);
extern int number_member(int x, Obj *lis);
extern int wind_value(Unit *unit, int angle, int force, Obj *effect, int maxval);
extern char *shortest_escaped_name(int u);

extern int side_owns_occupant(Side *side, Unit *unit);
extern char *goal_desc(char *buf, Goal *goal);

/* supply.c */

void run_supply(void);
void run_supply_side(Side *side);
int supply_system_in_use(void);
void compute_supply_zones(Side *side, int m);
void compute_unit_supply_zone(Side *side, Unit *unit, int m);
extern int has_advance_to_build(Side *side, int a);
extern int unit_actually_visible(Side *side, Unit *unit);
