// Fly and Retreat v1.0.0
// flyretreat.txt
// by Kelandon (tomwatts@berkeley.edu)
//
// When in combat, this creature will fly in a direction and use melee attacks.
// Then, if it gets hurt badly enough, it will fly back to its original location
// and focus on range attacks.
//
// This script is useful for creatures that fly across chasms or rivers or
// something similarly uncrossable.
//
// Memory Cells:
//   Cell 0 - How creature moves.
//     0 - If 0, wander randomly. 
//     1 - Stands still until a target appears.
//     2 - Completely immobile, even if target appears.
//   Cell 1,2 - Stuff done flag. If both 0, nothing. Otherwise when this 
//     is killed, set to 1. (Example: If cell 1 is 3 and cell 2 is 5, when
//     creature is killed, sets SDF(3,5) to 1.)
//   Cell 3 - Dialogue node to start with if talked to. if left at 0, this
//     character doesn't talk.
//	Cell 4 - Number of spaces to fly north/south (can't be negative).
//	Cell 5 - Direction to fly north/south (0 is north, 1 is south).
//	Cell 6 - Number of spaces to fly east/west (can't be negative).
//	Cell 7 - Direction to fly east/west (0 is east, 1 is west).
//	Cell 8 - What fraction of its health it must be at in order to
//	fly back to its original location. In other words, if this is 4,
//	then the creature will fly when it falls to 1/4 its health. If left at 0,
// defaults to 1.
//	Cell 9 - How likely it is to fly if it is undamaged. This
//	is a percentage (so 100 means it will always fly).

begincreaturescript;

variables;

short start_x,start_y,final_x,final_y,func_return,var1,var2,j;
short flown = 0;

body;

beginstate INIT_STATE;
	start_x = my_loc_x();
	start_y = my_loc_y();
	
	// Figure out final destination
	if (get_memory_cell(5) == 1)
		final_y = my_loc_y() + get_memory_cell(4);
	if (get_memory_cell(5) == 0)
		final_y = my_loc_y() - get_memory_cell(4);
	if (get_memory_cell(7) == 1)
		final_x = my_loc_x() - get_memory_cell(6);
	if (get_memory_cell(7) == 0)
		final_x = my_loc_x() + get_memory_cell(6);
		
	j = 0;
	if (get_memory_cell(8) == 0)
		set_memory_cell(8,1);
	if (get_memory_cell(0) == 2)
		set_mobility(ME,0);
break;

beginstate DEAD_STATE;
	// Set the appropriate stuff done flag for this character being dead
	if ((get_memory_cell(1) != 0) || (get_memory_cell(2) != 0))
		set_flag(get_memory_cell(1),get_memory_cell(2),1);
break;

beginstate START_STATE; 
	// if I have a target for some reason, go attack it
	if (target_ok()) {
		if (dist_to_char(get_target()) <= 16)
			set_state(3);
			else set_target(ME,-1);
		}
	
	// Look for a target, attack it if visible
	if (select_target(ME,8,0)) {
		do_attack();
		set_state(3);
		}
		
	// Have I been hit? Strike back!
	if (who_hit_me() >= 0) {
		set_target(ME,who_hit_me());
		do_attack();
		set_state(3);
		}
		
	// Otherwise, just peacefully move around. Go back to start, if I'm too far
	// from where I started.
	if ((my_dist_from_start() >= 6) || ((my_dist_from_start() > 0) && (get_memory_cell(0) > 0))) {
		if (get_ran(1,1,100) < 40) 
			return_to_start(ME,1);
		}
		else if (get_memory_cell(0) == 0) {
			fidget(ME,25);
			}

	// if we're in combat and the above didn't give me anything to do, just
	// stop now. Otherwise, game will keep running script, and that eats up CPU time.
	if (am_i_doing_action() == FALSE)
		end_combat_turn();
break;

beginstate 3; // attacking
if (func_return == 0)
	{if (target_ok() == FALSE)
		set_state(START_STATE);
	
	var1 = 0;
	var2 = 0;
	
	if ((get_health(ME) > get_max_health(ME) / get_memory_cell(6)) && (get_ran(1,1,100) <= get_memory_cell(9)) && (flown == 0))
		set_state_continue(4);
	
	if ((get_health(ME) < get_max_health(ME) / get_memory_cell(6)) && (flown == 1))
		set_state_continue(5);
	}
	
	func_return = 0;
	do_attack();
break;

beginstate 4; 
// Check if flying will put creature closer to party.
	func_return = 1;
	
	if (group_dist_to_loc(0,my_loc_x(),my_loc_y()) < group_dist_to_loc(0,final_x,final_y))
		set_state_continue(3);
	else 
		set_state_continue(10);
	
break;

beginstate 5; // Check if flying back will put creature farther from party.
	func_return = 1;
	final_x = start_x;
	final_y = start_y;
	if (group_dist_to_loc(0,my_loc_x(),my_loc_y()) >= group_dist_to_loc(0,start_x,start_y))
		set_state_continue(3);
	else 
		set_state_continue(11);
break;

beginstate 6; // Flying north and east.
	force_view_center(my_loc_x(),my_loc_y());
	force_instant_terrain_redraw();
	pause(5);
	if (my_loc_y() != final_y)
		{relocate_character(my_number(),my_loc_x(),my_loc_y() - 1);
		var1 = 1;
		}
	if (my_loc_x() != final_x)
		{relocate_character(my_number(),my_loc_x() + 1,my_loc_y());
		var2 = 1;
		}
	
	if (var1) // set the creature facing the appropriate direction
		{if (var2)
			set_character_facing(my_number(),7);
		else
			set_character_facing(my_number(),0);
		}
	else if (var2)
			set_character_facing(my_number(),6);
			
	if (char_dist_to_loc(my_number(),final_x,final_y) != 0)
		set_state_continue(6);
		
	set_state_continue(3);
break;

beginstate 7; // Flying south and east.
	force_view_center(my_loc_x(),my_loc_y());
	force_instant_terrain_redraw();
	pause(5);
	if (my_loc_y() != final_y)
		{relocate_character(my_number(),my_loc_x(),my_loc_y() + 1);
		var1 = 1;
		}
	if (my_loc_x() != final_x)
		{relocate_character(my_number(),my_loc_x() + 1,my_loc_y());
		var2 = 1;
		}
	
	if (var1) // set the creature facing the appropriate direction
		{if (var2)
			set_character_facing(my_number(),5);
		else
			set_character_facing(my_number(),4);
		}
	else if (var2)
			set_character_facing(my_number(),6);
	
	if (char_dist_to_loc(my_number(),final_x,final_y) != 0)
		set_state_continue(7);
		
	set_state_continue(3);
break;

beginstate 8; // Flying north and west.
	force_view_center(my_loc_x(),my_loc_y());
	force_instant_terrain_redraw();
	pause(5);
	if (my_loc_y() != final_y)
		{relocate_character(my_number(),my_loc_x(),my_loc_y() - 1);
		var1 = 1;
		}
	if (my_loc_x() != final_x)
		{relocate_character(my_number(),my_loc_x() - 1,my_loc_y());
		var2 = 1;
		}
	
	if (var1) // set the creature facing the appropriate direction
		{if (var2)
			set_character_facing(my_number(),1);
		else
			set_character_facing(my_number(),0);
		}
	else if (var2)
			set_character_facing(my_number(),2);
	
	if (char_dist_to_loc(my_number(),final_x,final_y) != 0)
		set_state_continue(8);
	
	set_state_continue(3);
break;

beginstate 9; // Flying south and west.
	force_view_center(my_loc_x(),my_loc_y());
	force_instant_terrain_redraw();
	pause(5);
	if (my_loc_y() != final_y)
		{relocate_character(my_number(),my_loc_x(),my_loc_y() + 1);var1 = 1;
		
		}
	if (my_loc_x() != final_x)
		{relocate_character(my_number(),my_loc_x() - 1,my_loc_y());
		var2 = 1;
		}
	
	if (var1) // set the creature facing the appropriate direction
		{if (var2)
			set_character_facing(my_number(),3);
		else
			set_character_facing(my_number(),4);
		}
	else if (var2)
			set_character_facing(my_number(),2);
	
	if (char_dist_to_loc(my_number(),final_x,final_y) != 0)
		set_state_continue(9);
	
	set_state_continue(3);
break;

beginstate 10; // Begin flying towards party.
	print_named_str(ME,"takes to the air and flies!");
	flown = 1;
	set_strategy(ME,0);
	if (get_memory_cell(5) == 0)
		{if (get_memory_cell(7) == 0)
			set_state_continue(6);
		if (get_memory_cell(7) == 1)
			set_state_continue(7);
		}
	if (get_memory_cell(5) == 1)
		{if (get_memory_cell(7) == 0)
			set_state_continue(8);
		if (get_memory_cell(7) == 1)
			set_state_continue(9);
		}
break;

beginstate 11; // Begin flying away from party.
	print_named_str(ME,"flies back to safety!");
	flown = 0;
	set_strategy(ME,1);
	if (get_memory_cell(5) == 0)
		{if (get_memory_cell(7) == 0)
			set_state_continue(9);
		if (get_memory_cell(7) == 1)
			set_state_continue(8);
		}
	if (get_memory_cell(5) == 1)
		{if (get_memory_cell(7) == 0)
			set_state_continue(7);
		if (get_memory_cell(7) == 1)
			set_state_continue(6);
		}
break;

beginstate TALKING_STATE;
	if (get_memory_cell(3) == 0) {
		print_str("Talking: It doesn't respond.");
		end();
		}
	begin_talk_mode(get_memory_cell(3));
break;