// vengeance_script.h
#ifndef __vengeance_script_h__
#define __vengeance_script_h__

//#ifndef __myth_defs_h__
//#include "myth_defs.h"
//#endif

#include "tagprivate.h"
#include "mons.h"
#include "obje.h"

// text parsing stuff
bool load_script( XGFileSpecifier *fs );
void free_script( void );
bool parse_token( char *token, bool cross_lines = true, long *line = NULL );
void unparse_token( void );
bool parse_float( float *f );
bool parse_int( int *i );
bool seek_to_token( const char *token_to_find, bool case_sensitive = true );
// end text parsing stuff

#define VS_MAX_PARM_DATA_LENGTH 256
#define VSP_MAX_PARM_ARRAY_LENGTH 32
#define VSP_MAX_PARAMETERS 16384

// vengeance script types
enum
{
	VS_NULL,
	VS_BUILD_MONOLITHIC, // builds a monolithic tag from a list of plugins
	VS_EXPORT_RAW, // exports listed tags as raw local tags
	VS_CREATE_SOUNDS, // automates the creation of sound tags
	VS_REPLACE_SOUNDS, // replaces the sound data in a sound tag (can replace all permutations as well)
	VS_REPLACE_MODELS, // replaces the model data in a model tag (attachments must not change)
	VS_REPLACE_MONSTER_STATS, // updates the stats for a monster (unimplimented)
	VS_CREATE_MONSTER_STATS, // dumps the conents of monster tags to a script file
	VS_EXPORT_TEXT, // saves a stli, temp, or text to a text file
	VS_IMPORT_TEXT, // imports a text file into a stli, temp, or text
	VS_DUMP_NAMES, // saves all tags of a type to a text file
	NUMBER_OF_VS
};

#define BUILD_MONOLITHIC_TOKEN "build_monolithic"
#define EXPORT_RAW_TOKEN "export_raw"
#define REPLACE_SOUNDS_TOKEN "replace_sounds"
#define REPLACE_MODELS_TOKEN "replace_models"
#define REPLACE_MONSTER_STATS_TOKEN "replace_monster_stats"
#define CREATE_MONSTER_STATS_TOKEN "create_monster_stats"
#define CREATE_SOUNDS_TOKEN "create_sounds"
#define EXPORT_TEXT_TOKEN "export_text"
#define IMPORT_TEXT_TOKEN "import_text"
#define DUMP_NAMES_TOKEN "dump_names"

// vengeance script parameter types
enum
{
	VSP_NULL = 0,
	VSP_FILE,
	VSP_TYPE,
	VSP_TAG,
	VSP_MONS,
	VSP_ATTK,
	VSP_OBJE,
	VSP_PROJ,
	VSP_SOUN,
	NUMBER_OF_VSP
};

#define FILE_TOKEN "file"
#define TYPE_TOKEN "type"
#define TAG_TOKEN "tag"
#define MONS_TOKEN "mons"
#define ATTK_TOKEN "attk"
#define OBJE_TOKEN "obje"
#define PROJ_TOKEN "proj"
#define SOUN_TOKEN "soun"

#define AUTOGENERATE_TAG_TOKEN '____'

#if 1
#define CREATE_MONSTER_STATS_MONS_TEXT \
"left hand frac\t\
turning speed\t\
hard death\t\
flinch shock\t\
absorbed frac\t\
healing frac\t\
combined pow\t\
exp value\t\
cost\t\
pathing radius\t\
max mana\t\
mana recharge\t\
berserk shock\t\
berserk frac\t\
dist: warning\t\
dist: critical\t\
dist: activate\t\
init ammo max\t\
init ammo min\t\
max ammo\t\
t: base speed\t\
t: dwarf media\t\
t: human media\t\
t: giant media\t\
t: undead media\t\
t: sloped\t\
t: steep\t\
t: grass\t\
t: sand\t\
t: rock\t\
t: marsh\t\
t: snow\t\
t: unused (-1!)\t\
t: unused (-1!)\t\
t: unused (-1!)\t\
t: grnd impass\t\
t: air impass\t\
flags\n"
#else
#define CREATE_MONSTER_STATS_MONS_TEXT \
"left handed fraction\t\
turning speed\t\
hard death system shock\t\
flinch system shock\t\
absorbed fraction\t\
healing fraction\t\
combined power\t\
longest range\t\
experience point value\t\
cost\t\
pathfinding radius\t\
maximum mana\t\
mana recharge rate\t\
berserk system shock\t\
berserker health fraction\t\
distance warning\t\
distance critical\t\
distance activation\t\
initial ammunition minimum\t\
initial ammunition maximum\t\
maximum ammunition count\t\
terrain: base speed\t\
terrain: dwarf-depth\t\
terrain: human-depth\t\
terrain: giant-depth\t\
terrain: undead-depth\t\
terrain: sloped\t\
terrain: steep\t\
terrain: grass\t\
terrain: sand\t\
terrain: rock\t\
terrain: marsh\t\
terrain: snow\t\
terrain:unused (use -1!)\t\
terrain:unused (use -1!)\t\
terrain:unused (use -1!)\t\
terrain: ground impassable\t\
terrain: air impassable\t\
flags: trans_constant, holds_with_clear_shot, floats, flies, allows_proj_pass_thru, exp_proportional, is_anit-missle_unit, is_anti-missle_target, turns_to_stone, concentrates_on_single_target, is_undead, cannot_be_autotargeted, is_giant_sized, does_not_respect_visibility, is_not_solid, leaves_contrail, invisible_on_overhead, cannot_be_healed, does_not_drop_ammo, is_inanimate, is_skittish, has_3d_model, small_radius_with_alies\n"
#endif

#if 1
#define CREATE_MONSTER_STATS_ATTK_TEXT \
"min range\t\
max range\t\
repititions\t\
miss fraction\t\
min init vel\t\
max init vel\t\
init vel error\t\
vel exp delta\t\
recovery time\t\
recover delta\t\
mana cost\t\
flags\n"
#else
#define CREATE_MONSTER_STATS_ATTK_TEXT \
"minimum range\t\
maximum range\t\
repititions\t\
miss fraction\t\
minimum initial velocity\t\
maximum initial velocity\t\
initial velocity error\t\
velocity experience delta\t\
recovery time\t\
recovery time experience delta\t\
mana cost\t\
flags: is_indirect, does_not_require_solution, aimed_at_feet, leads_target, uses_ammo, uses_carried_projectile, is_reflexive, is_special_ability, cannot_be_aborted, is_primary_attack, avoids_friendly_units, vs_giant_sized, prohibit_vs_giant_sized, is_fixed_pitch, dont_shoot_over_nearby, lob_to_hit_lower_nearby, can_be_used_against_friendlies, vs_small_sized, prohibit_vs_small_sized\n"
#endif

#if 1
#define CREATE_MONSTER_STATS_OBJE_TEXT \
"min health\t\
max health\t\
min scale\t\
max scale\t\
min damage\t\
flags\t\
slashing\t\
kinetic\t\
explosive\t\
electrical\t\
fire\t\
paralysis\t\
stone\t\
gas\t\
confusion\n"
#else
#define CREATE_MONSTER_STATS_OBJE_TEXT \
"min vitality\t\
max vitality\t\
min scale\t\
max scale\t\
minimum damage\t\
flags: draw_selection, draw_vitality, maintain_constant_height, ignore_collisions\t\
effect mod: slashing damage\t\
effect mod: kinetic damage\t\
effect mod: explosive damage\t\
effect mod: electrical damage\t\
effect mod: fire damage\t\
effect mod: paralysis\t\
effect mod: stone\t\
effect mod: gas damage\t\
effect mod: confusion\n"
#endif

#if 1
#define CREATE_MONSTER_STATS_PROJ_TEXT \
"normal det freq\t\
media det freq\t\
det velocity\t\
det flags\t\
phys vol\t\
phys inert min\t\
phys inert max\t\
phys rand init\t\
physics flags\t\
near target rad\t\
tracking pri\t\
guided turn speed\t\
dam type\t\
dam min\t\
dam max\t\
radius min\t\
radius max\t\
rate of exp\t\
dam to vel\t\
damage flags\t\
flags\n"
#else
#define CREATE_MONSTER_STATS_PROJ_TEXT \
"detonation normal frequency\t\
detonation media frequency\t\
detonation velocity\t\
detonation flags: when_animation_loops, when_transfer_loops, at_rest, remains_after_detonation\t\
physics volume\t\
physics inertia min\t\
physics inertia max\t\
physics random initial velocity\t\
physics flags: affected_by_wind, cannot_be_accelerated, melee_attack\t\
nearby target radius\t\
tracking prioriy\t\
guided turning speed\t\
projectile damage type: none, explosion, magical, holding, healing, kinetic, slashing_metal, stoning, slashing_claws, explosive_electricity, fire, gas, charm\t\
damage: damage min\t\
damage: damage max\t\
damage: radius min\t\
damage: radius max\t\
damage: rate of expansion\t\
damage: damage to velocity\t\
damage flags: proportional_to_velocity, area_of_effect, does_not_interrupt_events, cannot_be_healed, can_cause_paralysis, can_stun, cannot_be_blocked, does_not_affect_monsters, detonated_explosive_immediately, proportional_to_mana, can_destroy_large_objects, instantaneous, cannot_hurt_owner, does_not_make_monsters_flinch, can_cause_confusion\t\
projectile flags: uses_owner_color_table_index, angle_follows_trajectory, can_be_mirrored, becomes_dormant_at_rest, animates_at_rest, bloodies_landscape, is_on_fire, passes_through_target, cannot_be_mirrored_vertically, floats, is_media_surface_effect, continually_detonates, is_lightning, chooses_nearby_target, is_only_destroyed_by_lifespan, makes_owner_monster_visible, can_set_landscape_on_fire, centered_on_target, marks_target_as_having_been_chosen, is_bloody, is_guided, detonates_immediately\n"
#endif


// a list of script parameter types each script type can recognize
enum
{
	BUILD_MONOLITHIC_TOKEN_MASK = FLAG(VSP_FILE),
	EXPORT_RAW_TOKEN_MASK = FLAG(VSP_TAG) | FLAG(VSP_TYPE),
	REPLACE_SOUNDS_TOKEN_MASK = FLAG(VSP_TAG),
	REPLACE_MODELS_TOKEN_MASK = FLAG(VSP_TAG),
	REPLACE_MONSTER_STATS_TOKEN_MASK = FLAG(VSP_MONS) |FLAG(VSP_ATTK) | FLAG(VSP_OBJE) | FLAG(VSP_PROJ),
	CREATE_MONSTER_STATS_TOKEN_MASK = FLAG(VSP_TYPE) | FLAG(VSP_TAG),
	CREATE_SOUNDS_TOKEN_MASK = FLAG(VSP_SOUN),
	EXPORT_TEXT_TOKEN_MASK = FLAG(VSP_TYPE) | FLAG(VSP_TAG),
	IMPORT_TEXT_TOKEN_MASK = FLAG(VSP_TYPE) | FLAG(VSP_TAG),
	DUMP_NAMES_TOKEN_MASK = FLAG(VSP_TYPE) | FLAG(VSP_FILE)
};


struct vengeance_script_table
{
	unsigned long id;
	char token[VS_MAX_PARM_DATA_LENGTH];
};

struct vengeance_script_mons
{
	short desired_projectile_volume;
	fixed_fraction left_handed_fraction;
	angle turning_speed;
	fixed_fraction hard_death_system_shock;
	fixed_fraction flinch_system_shock;
	fixed_fraction absorbed_fraction;
	short_fixed healing_fraction;
	short combined_power;
	short_world_distance longest_range;
	short experience_point_value;
	short cost;
	short_world_distance pathfinding_radius;
	short_fixed maximum_mana;
	short_fixed mana_recharge_rate;
	fixed_fraction berserk_system_shock;
	fixed_fraction berserk_vitality;
	short kills_for_maximum_experience_bonus;
	short experience_bonus_size;
	short_world_distance experience_bonus_radius;
	fixed_fraction blocking_fraction;
	short_world_distance warning_distance;
	short_world_distance critical_distance;
	short_world_distance activation_distance;
	short initial_ammunition_lower_bound;
	short initial_ammunition_delta;
	short maximum_ammunition_count;
	short_world_distance base_movement_speed;
	char terrain_costs[MAXIMUM_NUMBER_OF_TERRAIN_TYPES]; // 0 if used, -1 if not used
	short_fixed_fraction movement_modifiers[MAXIMUM_NUMBER_OF_TERRAIN_TYPES];
	unsigned long flags;
	
	short number_of_attacks;
	unsigned long flag_mask;
};

struct vengeance_script_attk
{
	short_world_distance minimum_range;
	short_world_distance maximum_range;
	short repetitions;
	fixed_fraction miss_fraction;
	short_world_distance initial_velocity_lower_bound;
	short_world_distance initial_velocity_delta;
	short_world_distance initial_velocity_error;
	short_world_distance velocity_improvement_with_experience;
	short recovery_time;
	short recovery_time_experience_delta;
	short_fixed mana_cost;
	word flags;
	word extra_flags;
	
	short index;
};

struct vengeance_script_obje
{
	short_fixed maximum_vitality;
	short_fixed maximum_vitality_delta;
	short_fixed scale_lower_bound;
	short_fixed scale_delta;
	short_fixed minimum_damage;
	word flags;
	short_fixed effect_modifiers[MAXIMUM_NUMBER_OF_EFFECT_MODIFIERS];
	
	word flag_mask;
};

struct vengeance_script_proj_damage
{
	short type;
	word flags;
	short_fixed damage_lower_bound;
	short_fixed damage_delta;
	short_world_distance radius_lower_bound;
	short_world_distance radius_delta;
	short_world_distance rate_of_expansion;
	short_fixed damage_to_velocity;
	
	word flag_mask;
};

struct vengeance_script_proj
{
	fixed_fraction detonation_frequency;
	fixed_fraction media_detonation_frequency;
	short_world_distance detonation_velocity;
	unsigned long flags;
	short volume;
	short_fixed inertia_lower_bound;
	short_fixed inertia_delta;
	short_world_distance random_initial_velocity;
	// physics flags use the same flags variable
	short nearby_target_radius;
	short tracking_priority;
	angle guided_turning_speed;
	
	// normally in the damage_definition
	vengeance_script_proj_damage damage;
	
	// projectile flags also uses the same flags variable
	
	unsigned long flag_mask;
};

struct vengeance_script_soun
{
	char name[TAG_NAME_LENGTH + 1];
	tag id;
	int loudness; // 1, 2, 3, or 4
	tag subtitle_stringlist;
	int subtitle_index;
	float play_fraction; // 1-100
	float frequency_modifier; // 0-1
	float pitch_min; // range?
	float pitch_max; // range?
	float volume_min; // 0-1
	float volume_max; //0-1
	unsigned long flags;
};

struct vengeance_script_parm
{
	long line;
	long parm;
	long count;

	// parameter data	
	tag tag_type;
	tag tag_id;
	char strings[VSP_MAX_PARM_ARRAY_LENGTH][VS_MAX_PARM_DATA_LENGTH];
	union
	{
		vengeance_script_mons mons;
		vengeance_script_attk attk;
		vengeance_script_obje obje;
		vengeance_script_proj proj;
		vengeance_script_soun soun;
	} create_type;
};
		
struct vengeance_script
{
	XGFileSpecifier *fs;
	long type;
	char data[VS_MAX_PARM_DATA_LENGTH];
	
	long parms_size;
	long parms_used;
	vengeance_script_parm *parms;
};


class vengeance_script_exception
{
public:
	vengeance_script_exception( int line, char *detail );
	
	void message_box( void );

private:
	int m_line;
	char *m_detail;
};

bool parse_vengeance_script( XGFileSpecifier *fs );
void dispose_vengeance_script( void );
bool grow_vengeance_script_parm_block( void );
bool execute_vengeance_script( void );

// external to scripting prototypes
int replace_sound_data_at_index( tag_entry *e, XGFileSpecifier *fs, float skip_percentage, int index );
bool create_sound_data( tag_file *tf, vengeance_script_soun *soun );
bool replace_model_data_at_index( tag_entry *e, XGFileSpecifier *fs, int index );

bool replace_monster_data( tag_entry *te, vengeance_script_mons *mons );
bool retrive_monster_data( tag_entry *te, vengeance_script_mons *mons );

bool replace_attack_data( tag_entry *te, vengeance_script_attk *attk );
bool retrive_attack_data( tag_entry *te, vengeance_script_attk *attk );

bool replace_object_data( tag_entry *te, vengeance_script_obje *obje );
bool retrive_object_data( tag_entry *te, vengeance_script_obje *obje );

bool replace_projectile_data( tag_entry *te, vengeance_script_proj *proj );
bool retrive_projectile_data( tag_entry *te, vengeance_script_proj *proj );


#endif // __vengeance_script_h__
