
#ifndef __map_actions_h__
#define __map_actions_h__

#ifndef __tags_h__
#include "tags.h"
#endif

#ifndef __BYTE_SWAPPING_H__
#include "byte_swapping.h"
#endif

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


/* ---------- types */

typedef unsigned long field_tag;
typedef unsigned long action_tag;

/* ---------- map actions */

enum
{
	MAXIMUM_MAP_ACTION_NAME_LENGTH= 31,
	
	MAP_ACTION_COOKIE= 0xf0cacc1a,
	
	UNUSED_MAP_ACTION_IDENTIFIER= -2,
	MAXIMUM_MAP_ACTION_VISUAL_INDENT= 5
};

enum // map action parameter types
{
	// 1-byte
	_parameter_flag,
	_parameter_character,
	
	// 2-byte
	_parameter_monster_identifier, // monster identifier
	_parameter_action_identifier, // map action identifier
	_parameter_angle, // [0,FULL_CIRCLE)

	// 4-byte
	_parameter_integer, // [LONG_MIN,LONG_MAX]
	_parameter_world_distance,
	_parameter_field_name, // 4-byte, 'xxxx'
	_parameter_fixed,
	_parameter_projectile_group_tag, // resolved when the map is loaded
	_parameter_string_list_tag, // resolved when the map is loaded
	_parameter_sound_tag, // resolved when the map is loaded
	_parameter_projectile_tag,
	
	// 8-byte
	_parameter_world_point2d, // 2d point on the mesh
	
	// 16-byte
	_parameter_world_rectangle2d, // 2d rectangle on the mesh

	// 2-byte
	_parameter_object_identifier, // object identifier
	_parameter_model_identifier,
	_parameter_sound_source_identifier,
	
	// 12-byte
	_parameter_world_point3d, // 3d world point
		
	// 2-byte
	_parameter_local_projectile_group_identifier,
	_parameter_model_animation_identifier,
	
	// new for Myth 3
	_parameter_scenery_identifier,
	_parameter_scenery_tag, // resolved when the map is loaded
	
	NUMBER_OF_MAP_ACTION_PARAMETER_TYPES
};

enum // reserved map action parameter uses
{
	_field_name_link= 'link', // alias to another action (only valid with action_identifier types)
	_field_name_inhibitions= 'inhi', // will fail to trigger if all of the given actions have succeeded (not valid if linked to)
	_field_name_prerequisites= 'prer', // will fail to trigger unless one of the given actions succeeded (not valid if linked to)
	_field_name_deactivates_on_activation= 'deoa', // will deactivate all actions in this list when activated
	_field_name_deactivates_on_success= 'deos', // will deactivate all actions in this list when success occurs
	_field_name_deactivates_on_failure= 'deof', // will deactivate all actions in this list when failure occurs
	_field_name_activates_on_activation= 'acoa', // will activate all actions in this list when activated
	_field_name_activates_on_execution= 'acoe', // will activate all actions in this list when execution (success or failure) ocurrs
	_field_name_activates_on_failure= 'acof', // will activate all actions in this list when failure ocurrs
	_field_name_activates_on_success= 'acos', // will activate all actions in this list when success ocurrs
	_field_name_activates_on_trigger= 'acot', // will activate all actions in this list when triggered

	_field_name_activates_on_deactivation= 'acod', // will activate all actions in this list when deactivated
	_field_name_deactivates_on_deactivation= 'deod', // will deactivate all actions in this list when deactivated
	
	_field_name_activates_on_error= 'acer', // will activate all actions in this list when an error occurs
	_field_name_deactivates_on_error= 'deer', // will deactivate all actions in this list when an error ocurrs

	_field_name_activates_on_inhibition= 'acin', // will activate if the action is inhibited
	_field_name_activates_on_missing_prerequisites= 'acmp', // will activate if the action doesn't have enough prerequisites
	
	_field_name_triggers_simultaneously= 'trsi', // triggering this action simultaneously triggers all these
	_field_name_action_name= 'name',
	_field_name_debug= 'debg' // flag, if set, does map action debugging
};

enum // map action flags
{
	// user flags
	_map_action_initially_active_bit,
	_map_action_activates_only_once_bit,
	_map_action_no_initial_delay_bit,
	_map_action_only_initial_delay_bit,
	
	// runtime flags
	_map_action_is_active_bit,
	_map_action_succeeded_bit, // last return value
	_map_action_has_been_activated_bit,
	_map_action_was_just_activated_bit, // set on transition inactive->active, cleared after first execution
	
	NUMBER_OF_MAP_ACTION_FLAGS,
	
	_map_action_initially_active_flag= FLAG(_map_action_initially_active_bit),
	_map_action_activates_only_once_flag= FLAG(_map_action_activates_only_once_bit),
	_map_action_no_initial_delay_flag= FLAG(_map_action_no_initial_delay_bit),
	_map_action_only_initial_delay_flag= FLAG(_map_action_only_initial_delay_bit),
	_map_action_is_active_flag= FLAG(_map_action_is_active_bit),
	_map_action_succeeded_flag= FLAG(_map_action_succeeded_bit),
	_map_action_has_been_activated_flag= FLAG(_map_action_has_been_activated_bit),
	_map_action_was_just_activated_flag= FLAG(_map_action_was_just_activated_bit)
};

enum // map action deactivation modes
{
	_map_action_deactivates_on_trigger, // always deactivates on trigger
	_map_action_deactivates_on_execution, // only deactivates if it actually got executed
	_map_action_deactivates_on_successful_execution, // only deactivates if action proc returned success
	_map_action_deactivates_never,
	_map_action_deactivates_on_failed_execution,
	NUMBER_OF_MAP_ACTION_DEACTIVATION_MODES
};

#define SIZEOF_STRUCT_MAP_ACTION 64
struct map_action
{
	short identifier;
	short deactivation_mode;
	
	action_tag tag; // the proc which this action will trigger, NONE means none
	
	unsigned long flags;
	
	long trigger_time_lower_bound, trigger_time_delta; // could be absolute time or activation-relative delay
	
	short parameter_count;
	short parameters_size; // in bytes
	
	long parameters_offset;

	short visual_indent;

	short unused[15];

	// internal

	long trigger_time; // only valid if active; absolute time the action will trigger 
};


struct map_action_parameter_header
{
	short type, count;
	unsigned long field_name;
};


extern byte_swap_code map_action_byte_swap_data[];
extern byte_swap_code map_action_parameter_header_byte_swap_data[];



#endif


