// shaman.txt
// Like basicnpc.txt, but with a host of magical abilities. The abilities it 
// uses depends on the level of the character.

// Memory Cells:
//   Cell 0 - 
//     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 - Which special character code is active?
//     1 - Trinket Consort Esmerelda
//	   2 - Chrysander
//     3 - Horde Demonmaster
//     4 - Horde Apprentice
//     5 - Horde hunting shaman
//     6 - Dragonscale Shaman
//      7 - General Zhavress

// spell_class - The quality of spells this character can cast, is level / 4, 
//    starts at 1
// 1 - can haste, bless, slow
// 2 - single target terror, summon help
// 3 - can ae bless, daze
// 4 - can ae haste, slow
// 5 - ae rain of poison
// 6 - 

begincreaturescript;

variables;

short i,target;
short spell_class;
short haste_target;
short bless_target;
short did_spell;
short tried_return = 0;
short last_abil;
short misc_var = 0;

body;

beginstate INIT_STATE;
	if (get_memory_cell(0) == 2)
		set_walk_speed(ME,0);

	last_abil = get_current_tick();
	spell_class = get_level(ME) / 4;
	if (spell_class == 0)
		spell_class = 1;
	bless_char(ME,spell_class - 1);

	set_courage(ME,100);
	set_resistance(ME,7,90);


	if (get_memory_cell(4) == 1) { // Esmerelda
		set_name(ME,"Consort Esmerelda");
		//set_boss_level(ME,1);
		set_level(ME,2);
		}
	if (get_memory_cell(4) == 2) { // Chrysander
		set_name(ME,"Chrysander");
		set_boss_level(ME,1);
		}
	if (get_memory_cell(4) == 3) { // Horde Demonmaster
		set_name(ME,"Horde Demonmaster");
		set_boss_level(ME,1);
		set_level(ME,18);
		}
	if (get_memory_cell(4) == 4) { // Horde Apprentice
		set_name(ME,"Horde Apprentice");
		set_boss_level(ME,1);
		set_level(ME,15);
		}
	if (get_memory_cell(4) == 6) { //Dragonscale Shaman
		set_name(ME,"Dragonscale Shaman");
		set_boss_level(ME,2);
		set_level(ME,25);
		}
	if (get_memory_cell(4) == 7) { // General Zhavress
		set_name(ME,"General Zhavress");
		set_level(ME,25);
		set_boss_level(ME,2);
		}
		
//		change_max_health(ME,50);
//		set_char_unkillable(ME,1);
		
	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);

	if (get_memory_cell(4) == 1) { 
		if (get_quest_status(40) == 2) {
			print_str_color("You make sure to claim the consort's ear.",2);
			set_spec_item(get_memory_cell(5),1);
			}
		if (gf(160,0) == 0) {
			heal_char(17344,40);
			begin_talk_mode(12);
			}
		}
	if (get_memory_cell(4) == 2) { 
			print_str_color("The boss of this camp of skribbane addicts is dead.",2);
			print_str_color("This camp will soon be empty.",2);
		toggle_quest(85,4);
		toggle_quest(86,4);
		}

	if (get_memory_cell(4) == 7) { // General Zhavress
		begin_talk_mode(20);
		}
break;

beginstate START_STATE; 
	// SPECIAL STUFF
	
	if ((get_memory_cell(4) == 3) && (misc_var == 0)) { // Horde Demonmaster
		if ((get_nearest_party_char(7) >= 0) || (who_shot_me() >= 0)) {
			misc_var = 1;
			
			set_attitude(7143,10);
			set_attitude(7144,10);
			set_attitude(7145,10);
			set_act_at_dist(7143,1);
			set_act_at_dist(7144,1);
			set_act_at_dist(7145,1);
			alert_char(7143);
			alert_char(7144);
			alert_char(7145);
			
			begin_talk_mode(5);
			}
		}
	if ((get_memory_cell(4) == 3) && (misc_var == 0)) { // Horde Apprentice
		if ((get_attitude(ME) >= 10) && (misc_var == 0)) {
			misc_var = 1;
			set_attitude(7143,10);
			set_attitude(7144,10);
			set_attitude(7145,10);
			}
		}
	if ((get_memory_cell(4) == 6) && (misc_var == 0)) { // Horde Demonmaster
		if ((get_nearest_party_char(5) >= 0) || (who_shot_me() >= 0)) {
			misc_var = 1;
			
			begin_talk_mode(5);
			}
		}
		
	// REGULAR CODE
	
	// 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_foe_target(ME,-1);
		}
	
	// Look for a target, attack it if visible
	if (get_foe_target(ME,12,0)) {
		if (dist_to_party() > 8)
			approach_char(ME,30000,7);
			else {
				do_attack();
				set_state(3);
				}
		}
		
	// Have I been hit? Strike back!
	if (who_shot_me() >= 0) {
		set_foe_target(ME,who_shot_me());
		do_attack();
		set_state(3);
		}
		
	// hunter code
	// if we're hostile, hunt party down
	if ((get_memory_cell(4) == 2) || (get_memory_cell(4) == 5)) { 
		if (get_attitude(ME) >= 10) {
			set_foe_target(ME,random_group_member(0));
			set_state(3);
			}
		}

	if (get_memory_cell(4) == 7) { // General Zhavress
		set_foe_target(ME,random_group_member(0));
		set_state(3);
		}
		
	// 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
	spell_class = get_level(ME) / 4;
	if (spell_class == 0)
		spell_class = 1;

	if (am_i_doing_action())
		end();
		
	if (target_ok() == FALSE)
		set_state(START_STATE);

	// SPECIAL CODE

	if ((get_memory_cell(4) == 6) && (misc_var == 0)) { // Horde Demonmaster
			misc_var = 1;
			
			begin_talk_mode(5);
		}

	if ((get_memory_cell(4) == 7) && (get_ran(1,0,100) < 75) && (is_combat()) && (get_nearest_hate_char(8) >= 0) && (tick_difference(last_abil,get_current_tick()) > 1)) { // General Zhavress
		i = get_ran(1,0,3);
		last_abil = get_current_tick();
		if (char_ok(4387 + i) == FALSE) {
			print_named_str(ME,"calls a beast of the caves to aid him.");
			run_char_animation(2,1,35);	
			summon_creature(4387 + i);
			place_particle_num(4387 + i,1,1,8);
			set_summon_level(4387 + i,1);
			pc_heard_sound_delay(136,100);						
			set_char_status(4387 + i,1,8);
			set_char_status(ME,1,8);
			}
		}
	
	// REGULAR CODE
	
	if ((my_dist_from_start() >= 25) && (tried_return == 0)) {
		tried_return = 1;
		set_foe_target(ME,-1);
		return_to_start(ME,2);
		set_state(4);
		}

	// if our target is terrified or charmed or dazed, get new target
	if ((get_char_status(get_target(),7) > 0) || (get_char_status(get_target(),5) > 0) || (get_char_status(get_target(),17) > 0)) {
		get_foe_target(ME,12,0);
		if (target_ok() == FALSE)
			set_state(START_STATE);	
		}
		 
	// if party ducks out of combat mode, force it to restart
	if ((is_combat() == FALSE) && (can_see_char(get_target()))) {
		do_attack();
		end();
		}
	
	if (can_see_char(get_target()) == FALSE) {
		do_attack();
		end();
		}

	// now we are seeing if we want to cast a spell. the answer is probably yes.
	did_spell = 0;
	
	
	// first, if slowed, haste self or those nearby
	haste_target = -3;
	if (((get_char_status(ME,1) < 0) && (get_ran(1,0,100) < 80)) ||
	  ((get_char_status(ME,1) == 0) && (get_ran(1,0,100) < 25))) {
	  	if (spell_class >= 2)
	  		haste_target = -2;
	  		else haste_target = -1;
	  	}
	if ((haste_target == -3) && (friends_nearby(6) > 1) &&
	  (get_friendly_target(ME,8,3) > 0) && (get_ran(1,0,100) < 40)) {
	  	if (spell_class >= 2)
	  		haste_target = -2;
	  		else haste_target = get_friend_target();
	  	}

	if ((haste_target == -3) && (friends_nearby(6) > 1) &&
	  (get_friendly_target(ME,8,4) > 0) && (get_ran(1,0,100) < 20) && (get_char_status(ME,1) <= 0)) { 
	  	if (spell_class >= 2)
	  		haste_target = -2;
	  		else haste_target = get_friend_target();
	  	}
	if (haste_target == -2) { // AE haste
		if (get_char_status(ME,1) <= 0) { // don't rehaste myself
			print_named_str(ME,"casts a powerful haste spell.");
			status_nearby(12 + get_level(ME),8,1,3);
			if (spell_class >= 6)
				status_nearby(5,8,24,3);

			run_char_animation(2,1,35);	
			pc_heard_sound_delay(101,100);						
			deduct_ap(9);
			did_spell = 1;
			}
		}
			
	if (haste_target >= -1) { // 1 target haste
		if (haste_target == -1)
			haste_target = my_id();
		if (get_char_status(haste_target,1) <= 0) { // don't rehaste
			if (haste_target == my_id())
				print_named_str(ME,"casts a haste spell.");
				else print_named_str(ME,"hastes an ally.");
		  	//place_particle_num(haste_target,3,0,8);

			set_char_status(haste_target,1,get_level(ME));
			run_char_animation(2,1,35);	
			pc_heard_sound_delay(101,100);						
			deduct_ap(9);
			did_spell = 1;
			}
		}		

	// first, bless and shield
	// all casters now always ae bless and shield
	bless_target = -3;
	if (((get_char_status(ME,0) < 0) && (get_ran(1,0,100) < 80)) ||
	  ((get_char_status(ME,0) == 0) && (get_ran(1,0,100) < 20))) {
	  	if (spell_class > 0)
	  		bless_target = -2;
	  		else bless_target = -1;
	  	}
	if ((bless_target == -3) && (friends_nearby(6) > 2) &&
	  (get_friendly_target(ME,8,0) > 0) && (get_ran(1,0,100) < 40)) {
	  	if (spell_class > 0)
	  		bless_target = -2;
	  		else bless_target = get_friend_target();
	  	}

	if (bless_target == -2) { // AE bless
		if (get_char_status(ME,0) <= 0) { // don't rebless myself
			print_named_str(ME,"blesses allies.");
			status_nearby(8 + spell_class,8,0,3);
			status_nearby(8 + spell_class,8,8,3);
			//particle_nearby(8,1,0,3,8);
			run_char_animation(2,1,35);	
			pc_heard_sound_delay(100,100);						
			deduct_ap(9);
			did_spell = 1;
			}
		}
			
	if (bless_target >= -1) { // 1 target bless
		if (bless_target == -1)
			bless_target = my_id();
		if (get_char_status(bless_target,0) <= 0) { // don't rebless
			if (bless_target == my_id())
				print_named_str(ME,"gives a blessing.");
				else print_named_str(ME,"blesses an ally.");
		  	//place_particle_num(bless_target,1,0,8);
			set_char_status(bless_target,0,8 + spell_class);
			set_char_status(bless_target,8,8 + spell_class);
			run_char_animation(2,1,35);	
			pc_heard_sound_delay(100,100);						
			deduct_ap(9);
			did_spell = 1;
			}
		}		

	// now maybe do quick buffs
	if ((get_char_status(ME,20) <= 0) && (get_ran(1,0,100) < 50) && (spell_class > 1)) {
		set_char_status(ME,20,8);
		set_char_status(ME,21,8);
		print_named_str(ME,"takes on the aspect of a wild beast.");
		run_char_animation(2,1,35);	
		pc_heard_sound_delay(147,100);						
		deduct_ap(4);
		}
	
	// if alone, summon aid
	if ((did_spell == 0) && (spell_class >= 1) &&
	  (((friends_nearby(6) < enemies_nearby(6)) && 
		(get_ran(1,0,100) < 35)) || (get_ran(1,0,100) < 25))) {
			if (spell_class >= 7)
				i = return_summon_char(7);
				else if (spell_class >= 6)
					i = return_summon_char(3);
				else if (spell_class >= 4)
					i = return_summon_char(2);
				else if (spell_class >= 2)
					i = return_summon_char(1);
				else i = return_summon_char(0);
			summon_char(i,12);
			i = get_summoned_char_id();
			if (i >= 0) {
				print_named_str(ME,"summons aid.");
				run_char_animation(2,1,35);	
				pc_heard_sound_delay(136,100);						
				deduct_ap(9);
				did_spell = 1;

				if (get_level(ME) >= 10)
					change_max_health(i,1 * get_level(ME));

				if ((get_level(ME) * 3) / 4 > get_level(i))
					set_level(i,(get_level(ME) * 3) / 4);
				}
			}
			
	// cast daze on a foe
	if ((did_spell == 0) && (spell_class > 1) && (num_party_uncharmed() > 1) && 
	  (get_char_status(get_target(),17) <= 0) && (get_ran(1,0,100) < 25)) {
		print_named_str(ME,"dazes a foe.");
	  	//place_particle_num(get_target(),9,2,8);
		set_char_status(get_target(),17,get_level(ME) + 10);
		run_char_animation(2,1,35);	
		pc_heard_sound_delay(123,100);						
		deduct_ap(9);
		did_spell = 1;
	  	}
	  
	// slow or AE slow?
	if ((did_spell == 0) && (spell_class > 3) && 
	  ((get_ran(1,0,100) < 15) || ((get_char_status(get_target(),1) >= 0) && (get_ran(1,0,100) < 30)))) {
		print_named_str(ME,"radiates slowing energy.");
		status_nearby(-4 * spell_class,8,1,4);
		//particle_nearby(8,2,2,4,8);
		run_char_animation(2,1,35);	
		pc_heard_sound_delay(124,100);						
		deduct_ap(9);
		did_spell = 1;
		}
	if ((did_spell == 0) && (spell_class <= 3) &&
	  ((get_ran(1,0,100) < 15) || ((get_char_status(get_target(),1) >= 0) && (get_ran(1,0,100) < 30)))) {
		print_named_str(ME,"fires a beam of slowing energy.");
		set_char_status(get_target(),1,-4 * spell_class);
	  	//place_particle_num(get_target(),2,6,8);
		run_char_animation(2,1,35);	
		pc_heard_sound_delay(124,100);						
		deduct_ap(9);
		did_spell = 1;
		}

	
	// curse or AE curse?
	if ((did_spell == 0) && (spell_class >= 2) &&
	  ((get_ran(1,0,100) < 15) || ((get_char_status(get_target(),0) >= 0) && (get_ran(1,0,100) < 30)))) {
		print_named_str(ME,"casts a powerful curse.");
		status_nearby(-8 - spell_class,8,0,4);
		status_nearby(-8 - spell_class,8,8,4);
		//particle_nearby(8,3,2,4,8);
		run_char_animation(2,1,35);	
		pc_heard_sound_delay(128,100);						
		deduct_ap(9);
		did_spell = 1;
		}
	if ((did_spell == 0) && (spell_class < 2) &&
	  ((get_ran(1,0,100) < 15) || ((get_char_status(get_target(),0) >= 0) && (get_ran(1,0,100) < 30)))) {
		print_named_str(ME,"casts a curse.");
		set_char_status(get_target(),0,-8);
		set_char_status(get_target(),8,-8);
	  	//place_particle_num(get_target(),3,6,8);
		run_char_animation(2,1,35);	
		pc_heard_sound_delay(128,100);						
		deduct_ap(9);
		did_spell = 1;
		}	
					
	// AE poison?
	if ((did_spell == 0) && (spell_class >= 5) &&
	  (enemies_nearby(8) > 1) && (get_ran(1,0,100) < 50)) {
		print_named_str(ME,"summons a rain of poison.");
		damage_nearby(get_ran(get_level(ME) + get_attack_bonus(ME),1,5),7,4,0);
		status_nearby(get_level(ME),7,2,4);
	  		create_missile_spiral(142,40,7,2);
		run_char_animation(2,1,35);	
		pc_heard_sound_delay(174,100);						
		deduct_ap(9);
		did_spell = 1;
	  	}

	// single targ poison	
	if ((did_spell == 0) && (spell_class < 3) &&
	  (get_ran(1,0,100) < 30)) {
		print_named_str(ME,"flings a magical spray of venom.");
		damage_char(get_target(),get_ran(get_level(ME) + get_attack_bonus(ME),1,3),4);
		set_char_status(get_target(),2,5 + get_ran(get_level(ME) + get_attack_bonus(ME),1,2));
	  	//place_particle_num(get_target(),7,2,8);
		run_char_animation(2,1,35);	
		pc_heard_sound_delay(174,100);						
		deduct_ap(9);
		did_spell = 1;
		}	
	if ((did_spell == 0) && (spell_class >= 3) &&
	  (get_ran(1,0,100) < 30)) {
		print_named_str(ME,"summons a powerful bolt of venom.");
		damage_char(get_target(),get_ran(get_level(ME) + get_attack_bonus(ME),1,8),4);
		set_char_status(get_target(),2,5 + get_ran(get_level(ME) + get_attack_bonus(ME),1,4));
	  	//place_particle_num(get_target(),7,2,8);
		run_char_animation(2,1,35);	
		pc_heard_sound_delay(174,100);						
		deduct_ap(9);
		did_spell = 1;
		}	

	if (did_spell > 0)
		end();

	//if (my_ap() < 5)
	//	end_combat_turn();
		
	if (am_i_doing_action() == FALSE)
		do_attack();
break;

beginstate 4; // returning to start
	if (my_dist_from_start() < 10)
		set_state(START_STATE);

	// Have I been hit? Strike back!
	if (who_shot_me() >= 0) {
		set_foe_target(ME,who_shot_me());
		do_attack();
		set_state(3);
		}
	
	return_to_start(ME,2);
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;