// Sniper.txt
//
// by Jeremy "Terror's Martyr" LeVeque
//
// This script is best used with monsters with an archer graphic.
// It has the creature select a target randomly, checks if it
// dislikes the target, and fires an arrow accordingly.  It will
// never run out of ammo (although perhaps you can code that in),
// and has no intelligent method of selecting its targets.  It
// doesn't even vaguely behave like basicnpc.
//
// Memory Cells:
// Cell 0 - Number of times minus one that the Sniper will fire
//          per turn, times TWO.  (Meaning a value of 0 fires
//          twice, 2 fires six times, et cetera.)
// Cell 1 - Percent of times that Sniper will MISS.  (A value of
//          20 means that the Sniper has 80% accuracy.)
// Cell 2 - Minimum damage.
// Cell 3 - Maximum damage.
// Cell 4,5 - 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.)

begincreaturescript;

variables;

short poink,px,py,mx,my,ok,gc;
short hit;

body;

beginstate INIT_STATE;
	break;

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

beginstate START_STATE;

gc = (get_memory_cell(0) + 1);

ok = 0;

// If there's nobody in sight, why waste my time?
if(enemies_nearby(10) == 0)
	end();

while(ok < gc){

// Choose a random character in the town.
	poink = get_ran(1,0,120);

// Is the character alive?  This prevents unary errors- whatever those are.
	if (char_ok(poink)) {
		px = char_loc_x(poink);
		py = char_loc_y(poink);

// We can only hit people who we can't see and who we don't like.
		if(can_see_loc(px,py) == 1 && get_attitude(poink) != get_attitude(ME) && get_attitude(poink) != 4){

// This is where we shoot.
			mx = my_loc_x();
			my = my_loc_y();
// This makes a black beam from me to my target, also makes me "attack"
			put_straight_zap(mx,my,px,py,5);
			set_character_pose(ME,1);
			force_instant_terrain_redraw();
			run_animation_sound(91);
			hit = get_ran(1,1,100);
// This is my accuracy.
			if(hit >= get_memory_cell(1)){
damage_char(poink,get_ran(1,get_memory_cell(2),get_memory_cell(3)),0);
			}
			else{
				play_sound(2);
				print_named_str(ME," misses!");
			}
			pause(5);

// This is where I look like I'm no longer attacking and increase ok by 1.
			set_character_pose(ME,2);
			force_instant_terrain_redraw();
			pause(3);
			ok = ok + 1;
		}
	}
}
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;