// View plain text
// cycleguard.txt
// Niemand - niemandcw@gmail.com
// Based on basicnpc
// A town guard which patrols around a series of waypoints in a cycle. 
// Each memory cell designates the number of a waypoint to walk to, but a memory_cell 
// with a value of 10 or greater (note that waypoints in a town are numbers from 0 to 9) 
// indicates the end of the list. Alternately, if all ten memory cells are filled with valid waypoint 
// numbers the list is implicitly terminated. Waypoints may appear in the list in any order, 
// including being repeated. One simple setup would be: 
//	 Cell:	0	1	2	3
//	 Value:	4	5	6	10
// This will instruct the guard to walk to waypoint 4, then 5, then 6, and then go back to 4 and start again. 
// A more complex example is: 
//	 Cell:	0	1	2	3	4	5	6
//	 Value:	0	1	2	0	3	4	10
// This will have the guard walk in a loop among waypoints 0, 1, and 2, then in a loop among points 
// 0, 3, and 4, and then start over. 

//Note that since all memory cells are potentially used for the waypoint list, this guard with never talk. 
// It is also important that the distance waypoint in the guard's list to the subsequent waypoint be small 
// enough that the game's path-finding engine will not give up. In practice it appears that allowing subsequent 
// waypoints to be no more than 32 distance units apart is a good rule of thumb. 
// In order to be able to keep moving even if the party is far away, this script uses mode 3, so be careful not to 
// use too many in a single town (or to change this behavior). 

begincreaturescript;

variables;
int cur, max;

body;

beginstate INIT_STATE;
	cur = 0;
	while(cur < 10){
		if(get_memory_cell(cur) >= 10){
			max = cur;
			cur = 100; //break
		}
		cur = cur+1;	
	}
	if(cur==10)
		max = 10;
	cur = 0;
	set_script_mode(3); //don't over use these!
break;

beginstate DEAD_STATE;
	//Does nothing
break;

beginstate START_STATE; 
	// If the town has gone hostile, seek out the party
	if (town_status(current_town()) == 2) {
		stop_moving(ME);
		alert_char(ME);
	}
	
	// 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))
		set_state_continue(3);
	
	// Have I been hit? Strike back!
	if (who_hit_me() >= 0) {
		stop_moving(ME);
		set_target(ME,who_hit_me());
		set_state_continue(3);
	}
	
	if (get_attitude(ME) >= 10) 
		approach_char(ME,random_party_member(),6);
	else if (get_ran(1,0,100) < 80) {
		if (approach_waypoint(ME,get_memory_cell(cur),1)){
			cur = cur + 1;
			if(cur >= max)
				cur = 0;
		}
	}
	//Otherwise just stop
	if (am_i_doing_action() == FALSE)
		end_combat_turn();
break;

beginstate 3; // attacking
	if (target_ok() == FALSE)
		set_state(START_STATE);
	do_attack();
break;

beginstate TALKING_STATE;
	print_str("Talking: The town watchman nods to you but doesn't speak.");
	end();
break