// v1.0.3
// trap.txt
// Xoid (xoid@hotmail.com)

// Version History:
//   v1.0.3 - Uses all sorts of pretty effects and death dealing.  Mwahahaha!
//   v1.0.2 - Rewrote most of the script from the ground up. Buggy.
//   v1.0.1 - Altered to bring it more in line with how Avernum 2 dealt with
//            traps.  They have a higher chance of being lethal
//   v1.0.0 - Original version by Jeff Vogel.

// trap.txt - This is the basic script that powers all traps in boxes, chests,
// etc., or traps places in open spaces and corridors. If you are working on a
// scenario that contains traps, DO NOT REMOVE THIS SCRIPT.

// When you want to put a trap on a section of floor or container, you need to
// use the create terrain script button. Then you need to set the memory cells
// for the sort of trap.

// Memory Cells -
//   0 - Trap difficulty. This is the tool use skill needed to disarm the trap.
//     Lockpicks don't help. If set to a really high number (like 200), it
//     cannot be disarmed by normal means. It left at 0, the trap difficulty
//     will default to 10.

//   1 - Special Item needed. If left at 0, no special item helps disarm the
//     trap. Otherwise, if the party has this special item, the trap is
//     automatically disarmed.

//   2,3 - SDF coordinates. If these are left at 0 and 0, then it is ignored.
//     Otherwise, the stuff done flag is set to 1 when the trap is disarmed. If
//     the flag is non-zero, than when the party enters this zone, trap is still
//     disarmed.

//   4 - Trap type.
//     0 - Ordinary
//     1 - Fire
//     2 - Poison
//     3 - Generic Magic
//     4 - Unavoidable
//     5 - Cold damage
//     6 - Acid levels
//     7 - Summon Creature
//     8 - Dread Curse
//     9 - Death
//     10 - Random faulty trap.

//   5 - Trap mode.
//     IF (Trap type >= 0 && <= 6) && (Trap mode == 0) :: The trap does damage
//     of trap type, or inflicts acid/poison levels. Only affects the character
//     who triggered the trap.
//
//     IF (Trap type == 0 || 3) && (Trap mode > 0) :: The trap does damage of
//     trap type. Affects the entire party.
//
//     IF (Trap type >= 1 && <= 6 && != 3) && (Trap mode > 0) :: The trap causes
//     area of effect damage of trap type centered on the trap.
//
//     IF (Trap type == 7) :: Trap mode is ignored for this type of trap.
//
//     IF (Trap type == 8) && (Trap mode == 0) :: The trap inflicts dread curse
//     levels. Only affects the character who triggered the trap.
//
//     IF (Trap type == 8) && (Trap mode > 0) :: The trap inflicts dread curse
//     levels upon the entire party.
//
//     IF (Trap type == 9) && (Trap mode == 0) :: The trap gives characters a
//     chance to 'luck out' of certain death. Only affects the character who
//     triggered the trap.
//
//     IF (Trap type == 9) && (Trap mode > 0) :: The trap gives characters a
//     chance to 'luck out' of certain death. Affects the entire party.

//   6 - Trap severity.
//     IF (Trap type >= 0 && <= 6) :: The trap does damage, or inflicts
//     acid/poison levels equal to trap severity * 1d8.
//
//     IF (Trap type == 7) :: The trap summons a creature of the type equal to
//     trap severity.  If left at 0, it summons Garzahd.
//
//     IF (Trap type == 8) :: The trap inflicts dread curse levels equal to trap
//     severity + 1d3.
//
//     IF (Trap type == 9) :: The trap causes death of type trap severity. Legal
//     values are: 2 = We got a cadaver here.
//                 3 = Ashes to ashes, dust to dust.
//                 4 = Viva le bong.
//     If an illegal value is entered, I will arrest you. Or the script will
//     act as if you had entered 2.

beginterrainscript;

variables;
	int activator,choice,i,j,r1,r2,r3,x,y;
	int i_am_active = 0;
body;

beginstate INIT_STATE;
	if (get_memory_cell(0) == 0)
		set_memory_cell(0,10);

	if ((get_memory_cell(6) == 0) && (get_memory_cell(4) != 7))
		set_memory_cell(6,10);

	i_am_active = 1;
	set_mechanism_difficulty(get_memory_cell(0));
	if ((get_memory_cell(2) > 0) || (get_memory_cell(3) > 0)) {
		if (get_sdf(get_memory_cell(2),get_memory_cell(3)) > 0)
			i_am_active = 0;
	}
break;

beginstate START_STATE;
break;

beginstate SEARCH_STATE;
	set_state_continue(3);
break;


beginstate STEP_INTO_SPOT_STATE;
	set_state_continue(3);
break;

beginstate 3;
	if (i_am_active == 1) {
		reset_dialog();
		if (get_highest_skill(15) < get_memory_cell(0) - 6)
			add_dialog_str(0,"You think that you have detected a trap. Your character with the highest Tool Use skill can attempt to disarm it. However, the trap seems impossibly difficult.",0);
		else if (get_highest_skill(15) < get_memory_cell(0))
			add_dialog_str(0,"You think that you have detected a trap. Your character with the highest Tool Use skill can attempt to disarm it. However, the trap seems very difficult.",0);
		else add_dialog_str(0,"You think that you have detected a trap. Your character with the highest Tool Use skill can attempt to disarm it. The trap doesn't seem difficult.",0);

		add_dialog_choice(0,"Leave it alone.");
		add_dialog_choice(1,"Try to disarm the trap.");
		choice = run_dialog(0);

		if (choice == 1) {
			block_entry(1);
			end();
		}

		i_am_active = 0;
		if ((get_memory_cell(2) > 0) || (get_memory_cell(3) > 0))
			set_flag(get_memory_cell(2),get_memory_cell(3),1);

		if ((get_highest_skill(15) > get_mechanism_difficulty()) && ((get_memory_cell(1) == 0) || (has_special_item(get_memory_cell(1)) == 0))) {
			activator = char_who_activated_script();
			r1 = get_ran(get_memory_cell(6),1,8);
			x = my_loc_x();
			y = my_loc_y();

			if (get_memory_cell(4) == 0) {
				print_str_color("Trap: Several knives fly out!",2);
				r1 = get_ran((get_memory_cell(6) / 3),1,8);
				r2 = get_ran((get_memory_cell(6) % 3),1,8);
				if (get_memory_cell(5) == 0) {
					// Very close to how Avernum 2 did it...
					damage_char(activator,r1,0);
					damage_char(activator,r1,0);
					damage_char(activator,r2,0);
				}
				else {
					damage_char(1000,r1,0);
					damage_char(1000,r1,0);
					damage_char(1000,r2,0);
				}
			}

			if ((get_memory_cell(4) == 1) || (get_memory_cell(4) == 4)) { // Fire or Unblock
				print_str_color("Trap: There is an explosion.",2);
				if (get_memory_cell(5) == 0) {
					put_boom_on_char(activator,0,0);
					run_animation_sound(51);
					damage_char(activator,r1,get_memory_cell(4));
				}
				else {
					put_boom_on_space(x,y,0,1);
					// Random SFX
					i = 0;
					j = 0;
					r2 = get_ran(1,2,3);
					r3 = get_ran(1,2,3);
					while ((get_floor(x + r2,y) == 255) && (i < 5)) {
						r1 = get_ran(1,2,3);
						i = i + 1;
					}
					while ((get_floor(x,y + r3) == 255) && (j < 5)) {
						r2 = get_ran(1,2,3);
						j = j + 1;
					}
					if (i < 5)
						put_boom_on_space(x + r2,y,0,1);
					if (j < 5)
						put_boom_on_space(x,y + r3,0,1);
					run_animation_sound(51);
					damage_nearby(r1,4,get_memory_cell(4),2);
				}
			}

			if (get_memory_cell(4) == 2) {
				print_str_color("Trap: Poisonous vapours fill the air.",2);
				if (get_memory_cell(5) == 0) {
					put_effect_on_char(i,13,8,1);
					run_animation_sound(17);
					set_char_status(activator,0,r1,0,1);
				}
				else {
					i = 0;
					while (i < party_size()) {
						put_effect_on_char(i,13,8,1);
						i = i + 1;
					}
					put_effect_on_space(x,y,13,8,1);
					// Random SFX
					i = 0;
					j = 0;
					r2 = get_ran(1,1,3);
					r3 = get_ran(1,1,3);
					while ((get_floor(x + r2,y) == 255) && (i < 5)) {
						r2 = get_ran(1,1,3);
						i = i + 1;
					}
					while ((get_floor(x,y + r3) == 255) && (j < 5)) {
						r3 = get_ran(1,1,3);
						j = j + 1;
					}
					if (i < 5)
						put_effect_on_space(x + r2,y,13,8,1);
					if (j < 5)
						put_effect_on_space(x,y + r3,13,8,1);
					run_animation_sound(17);
					status_nearby(r1,4,0,2,r1);
				}
			}

			if (get_memory_cell(4) == 3) {
				if (r1 < 100)
					r2 = 4;
				else r2 = 6;
				print_str_color("Trap: There is a searing burst of magical energy.",2);
				if (get_memory_cell(5) == 0) {
					if (r1 < 100) {
						put_boom_on_char(activator,r2,0);
						put_straight_zap(x,y,char_loc_x(activator),char_loc_y(activator),1);
					}
					else {
						put_boom_on_char(activator,r2,0);
						put_jagged_zap(x,y,char_loc_x(activator),char_loc_y(activator),2);
					}
					if (r1 < 100)
						run_animation_sound(54);
					else run_animation_sound(102);
					damage_char(activator,r1,1);
				}
				else {
					i = 0;
					while (i < party_size()) {
						if (r1 < 100) {
							put_boom_on_char(i,r2,0);
							put_straight_zap(x,y,char_loc_x(i),char_loc_y(i),1);
						}
						else {
							put_boom_on_char(i,r2,0);
							put_jagged_zap(x,y,char_loc_x(i),char_loc_y(i),5);
						}
						i = i + 1;
					}
					if (r1 < 100)
						run_animation_sound(54);
					else run_animation_sound(102);
					damage_char(1000,r1,3);
				}
			}

			if (get_memory_cell(4) == 5) {
				print_str_color("Trap: A gust of bone-chilling wind fills air.",2);
				if (get_memory_cell(5) == 0) {
					put_effect_on_char(i,0,8,0);
					run_animation_sound(52);
					damage_char(activator,r1,5);
				}
				else {
					i = 0;
					while (i < party_size()) {
						put_effect_on_char(i,0,8,0);
						i = i + 1;
					}
					put_effect_on_space(x,y,0,8,0);
					// Random SFX
					i = 0;
					j = 0;
					r2 = get_ran(1,1,3);
					r3 = get_ran(1,1,3);
					while ((get_floor(x + r2,y) == 255) && (i < 5)) {
						r1 = get_ran(1,1,3);
						i = i + 1;
					}
					while ((get_floor(x,y + r3) == 255) && (j < 5)) {
						r2 = get_ran(1,1,3);
						j = j + 1;
					}
					if (i < 5)
						put_effect_on_space(x + r2,y,0,8,1);
					if (j < 5)
						put_effect_on_space(x,y + r3,0,8,1);
					run_animation_sound(52);
					damage_nearby(r1,4,5,2);
				}
			}

			if (get_memory_cell(4) == 6) {
				print_str_color("Trap: A thick mist of acid engulfs the area.",2);
				if (get_memory_cell(5) == 0) {
					put_effect_on_char(i,7,8,1);
					run_animation_sound(42);
					set_char_status(activator,12,r1,0,1);
				}
				else {
					i = 0;
					while (i < party_size()) {
						put_effect_on_char(i,7,8,1);
						i = i + 1;
					}
					put_effect_on_space(x,y,7,8,1);
					// Random SFX
					i = 0;
					j = 0;
					r2 = get_ran(1,1,3);
					r3 = get_ran(1,1,3);
					while ((get_floor(x + r2,y) == 255) && (i < 5)) {
						r1 = get_ran(1,1,3);
						i = i + 1;
					}
					while ((get_floor(x,y + r3) == 255) && (j < 5)) {
						r2 = get_ran(1,1,3);
						j = j + 1;
					}
					if (i < 5)
						put_effect_on_space(x + r2,y,7,8,1);
					if (j < 5)
						put_effect_on_space(x,y + r3,7,8,1);
					run_animation_sound(42);
					status_nearby(r1,4,12,2,r1);
				}
			}

			if (get_memory_cell(4) == 7) {
				if (get_memory_cell(6) == 0)
					set_memory_cell(6,109);
				put_boom_on_space(x,y,2,0);
				run_animation_sound(10);
// Try to ensure we don't put our friend into solid stone. As long as you
// guarantee at least one empty space near the trap, there will be no problems.
// Otherwise it will not appear.
				r1 = -1;
				r2 = -1;
				while ((char_on_loc(x + r1,y + r2) != -1) || (get_floor(x + r1,y + r2) == 255)) {
					if (r1 == 1) {
						r2 = r2 + 1;
						r1 = -1;
					}
					else r1 = r1 + 1;
					// Do not check the place trap is on...
					if ((r1 == 0) && (r2 == 0))
						r1 = r1 + 1;
				}
				place_monster(x + r1,y + r2,get_memory_cell(6),1);
			}

			if (get_memory_cell(4) == 8) {
// Dread curses do not display properly in BoA, (giving a reading of 0 levels of
// dread curse), this is because Jeff sucks. Keep that in mind.
				print_str_color("Trap: You feel terribly weak.",2);
				r2 = get_memory_cell(6) + get_ran(1,1,3);
				if (get_memory_cell(5) == 0) {
					put_sparkles_on_char(activator,7,12);
					run_animation_sound(163);
					alter_stat(activator,31,r2);
				}
				else {
					i = 0;
					while (i < party_size()) {
						put_sparkles_on_char(i,7,12);
						i = i + 1;
					}
					run_animation_sound(163);
					alter_stat(1000,31,r2);
				}
			}

			if (get_memory_cell(4) == 9) {
				// Error detection and correction...
				if ((get_memory_cell(6) < 2) || (get_memory_cell(6) > 4))
					set_memory_cell(6,2);
				if (get_memory_cell(6) == 4)
					print_str_color("Trap: A flesh to stone spell attempts to petrify you.",2);
				else print_str_color("Trap: Hostile energies attempt to strip your soul away.",2);

				if (get_memory_cell(5) == 0) {
					put_effect_on_char(activator,5,8,1);
					put_jagged_zap(x,y,char_loc_x(activator),char_loc_y(activator),2);
					kill_char(activator,get_memory_cell(6),1);
					if (get_memory_cell(6) == 4)
						run_animation_sound(43);
					else run_animation_sound(65);
				}
				else {
					i = 0;
					while (i < party_size()) {
						put_effect_on_char(i,5,8,1);
						put_jagged_zap(x,y,char_loc_x(i),char_loc_y(i),2);
						i = i + 1;
					}
					kill_char(1000,get_memory_cell(6),1);
					if (get_memory_cell(6) == 4)
						run_animation_sound(43);
					else run_animation_sound(65);
				}
			}
			// Error detection, and notificaiton...
			if (get_memory_cell(4) > 9) {
				r1 = get_ran(1,1,3)
				if (r1 == 1)
					print_str_color("Trap: There is a momentary flash of light, then, nothing. The trap was faulty.",2);
				else if (r1 == 2)
					print_str_color("Trap: There is a shower of sparks, then, nothing. The trap was faulty.",2);
				else print_str_color("Trap: There is a puff of smoke, then, nothing. The trap was faulty.",2);
			}
		}

		else {
			play_sound(-136);
			print_str_color("You have disarmed the trap.",2);
			if ((get_memory_cell(2) > 0) || (get_memory_cell(3) > 0))
				award_party_xp(BASE_TRAP_XP,1 + 2 * get_mechanism_difficulty());
		}
	}
break;