#
# COMBAT.PL
#
# Combat notification messages relayed over chat.
#
# By Sean Butler (Xin)
#
print "${BGreen}Loading combat2.pl\n";

# Variables to enable and disable alerts.

my $MeleeMessagesEnabled = 1;
my $BsMessagesEnabled = 1;
my $EnemyBsMessagesEnabled = 1;


# Variables to set when a bs happened.

my  $was_bsed = 0;
my  $bs_landed = 0;
my  $bs_mult = 0;
my  $target_enemy = "";
my  $alerts = "";
my  $number_bses = 0;
my  $enemy_condition = "none";
my  %MULTS = ();
my  %ALERTS = ();
my  $notperson = "";
my  $howmanyppl = 0;
# Variables for colored alerts
# Seems cleaner to declare these so that we dont have to see this
# messy crap later.

#my $killed      = "${col_R}K${col_r}I${col_R}L${col_r}L${col_R}E${col_r}D";
#my $dispelled   = "${col_R}D${col_r}I${col_R}S${col_r}P${col_R}E${col_r}L${col_R}L${col_r}E${col_R}D";
#my $plagued     = "${col_G}P${col_g}L${col_G}A${col_g}G${col_G}U${col_g}E${col_G}D";
#my $faeriefired = "${col_R}F${col_r}A${col_R}E${col_r}R${col_R}I${col_r}E${col_R}F${col_r}I${col_R}R${col_r}E${col_R}D";
#my $blinded     = "${col_B}B${col_b}L${col_B}I${col_b}N${col_B}D${col_b}E${col_B}D";
#my $drained     = "${col_Y}D${col_Y}R${col_R}A${col_R}I${col_B}N${col_B}E${col_K}D";
#my $cursed      = "${col_r}C${col_R}U${col_r}R${col_R}S${col_r}E${col_R}D";
#my $weakened    = "${col_c}W${col_C}E${col_c}A${col_C}K${col_c}E${col_C}N${col_c}E${col_C}D";
#my $chilled     = "${col_C}C${col_c}H${col_C}I${col_c}L${col_C}L${col_c}E${col_C}D";
#my $tripped     = "${col_Y}T${col_y}R${col_Y}I${col_y}P${col_Y}P${col_y}E${col_Y}D";

my $dispelleds	= "${col_B}DISPELLED(${col_W}sanc${col_B})";
my $plagued	= "${col_W}P${col_B}L${col_W}A${col_B}G${col_W}U${col_B}E${col_W}D";
my $ff		= "${col_W}F${col_B}A${col_W}E${col_B}R${col_W}I${col_B}E${col_W}F${col_B}I${col_W}R${col_B}E${col_W}D";
my $blinded	= "${col_W}B${col_B}L${col_W}I${col_B}N${col_W}D${col_B}E${col_W}D";
my $cursed	= "${col_W}C${col_B}U${col_W}R${col_B}S${col_W}E${col_B}D";
my $weakened	= "${col_W}W${col_B}E${col_W}A${col_B}K${col_W}E${col_B}N${col_W}E${col_B}D";
my $chilled	= "${col_W}C${col_B}H${col_W}I${col_B}L${col_W}L${col_B}E${col_W}D";

my $tripped	= "${col_W}T${col_B}R${col_W}I${col_B}P${col_W}P${col_B}E${col_W}D";
my $bashed	= "${col_W}B${col_B}A${col_W}S${col_B}H${col_W}E${col_B}D";
my $killed	= "${col_W}K${col_B}I${col_W}L${col_B}L${col_W}E${col_B}D";


sub cmd_bson {
	$BsMessagesEnabled = 1;
	$EnemyBsMessagesEnabled = 1;
	run ("/chatall emote ${col_w}just ${col_C}E${col_c}N${col_C}A${col_c}B${col_C}L${col_c}E${col_C}D${col_G} Backstab Notifiers${col_B}!");
}

sub cmd_bsoff {
	$BsMessagesEnabled = 0;
	$EnemyBsMessagesEnabled = 0;
	run ("/chatall emote ${col_w}just ${col_M}D${col_m}I${col_M}S${col_m}A${col_M}B${col_m}L${col_M}E${col_m}D${col_G} Backstab Notifiers${col_B}!");
}

sub cmd_comon { 
	$MeleeMessagesEnabled = 1; 
	run ("/chatall emote ${col_w}just ${col_R}E${col_r}N${col_R}A${col_r}B${col_R}L${col_r}E${col_R}D ${col_C}Combat Notifiers${col_B}!");
}
sub cmd_comoff { 
	$MeleeMessagesEnabled = 0; 
	run ("/chatall emote ${col_w}just ${col_W}D${col_w}I${col_W}S${col_w}A${col_W}B${col_w}L${col_W}E${col_w}D ${col_C}Combat Notifiers${col_B}!");
}

# Enemy backstab alerts
sub MatchEnemyBS {
	if ($EnemyBsMessagesEnabled == 0) { 
	 return 0; 
	}
	if (/^(.*) twists (.*) as (.*) removes it from your back/) {
		return "$1:1.25:TWIST";		
	}
	if (/^You hear footfalls behind, turning your head, you notice (.*)./) {
		return "$1:0.0:footfall";
	}
        if (/^Suddenly (.*) stabs you in the back, RIP.../) {
		return "$1:4.0.0:ice";
	}
	if (/^(.*) critically stabs you in the back with (.*) and your body is wracked with excruciating pain/) {
		return "$1:5.5:5.5x";
	}
	if (/^Pain shoots through your back as (.*) stabs at you with (.*) and slides it through your defenses/) {
		return "$1:5.0:5.0x";
	}
	if (/^(.*) skillfully stabs at your back with (.*) and tears through your defenses, landing a devastating/) {
		return "$1:4.5:4.5x";
	}
	if (/^You convulses in pain as (.*) powerfully stabs you in the back with (.*)/) {
		return "$1:4.0:4.0x";
	}
	if (/^A vicious backstab from (.*) causes you to choke on your own blood./) {
		return "$1:3.5:3.5x";
	}
	if (/^Tendrils of pain shoot through your back as (.*) stabs at your back with (.*) and lands an off-center blow/) {
		return "$1:3.0:3.0x";
	}
	if (/^You reel in pain as (.*) lunges at your back and lazily penetrates your defenses with (.*)/) {
		return "$1:2.5:2.5x";
	}
	if (/^You feel a sharp, stinging pain as (.*) stabs at your shoulder blades with (.*)/) { 
		return "$1:2.0:2.0x"; 
	}
	if (/^You wince in pain as (.*) clumsily stabs at your back/) {
		return "$1:1.5:1.5x";
	}
	if (/^Instinctively, you jump to the side and avoid (.*) as (.*) lunges at your back/) { 
		return "$1:0.0:whiff"; 
	}
}

# Backstab alerts

sub MatchBS {
	if ($BsMessagesEnabled == 0) { 
		return 0; 
	}
	if (/^(.*) turns (.*) head, noticing you./) {
		return "$1:0:footfall";
	}
	if (/^You twist (.*) as you remove it from (.*)\'s back/) {
		return "$2:1.25:TWIST";
	}
	if (/^(.*) makes a strange sound but is suddenly very silent, as you place (.*) in (.*) back/) {
		return "$1:4.0:ice";
	}
	if (/^(.*) finds its true mark as you stab at (.*)\'s back, as if it were guided by Vryce himself/) {
		return "$2:5.5:5.5x";
	}
	if (/^(.*) finds a chink in (.*)\'s defenses and slides in for a direct hit!/) {
		return "$2:5.0:5.0x";
	}
	if (/^Before (.*) can react, (.*) tears through (.*)\'s defenses and plunges into (.*) back/) {
		return "$3:4.5:4.5x";
	}
	if (/^(.*) convulses in pain as you land a powerful backstab/) {
		return "$1:4.0:4.0x";
	}
	if (/^You plunge (.*) into the back of (.*)./) {
		return "$2:3.5:3.5x";
	}
	if (/^A flash of metal interrupts your concentration and your pierce lands slightly off-target as you stab at (.*)\'s back/) {
		return "$1:3.0:3.0x";
	}
	if (/^You attempt to stab (.*) in the back, but your thrust is partially deflected before penetrating (.*) defenses/) {
		return "$1:2.5:2.5x";
	}
	if (/^Your grip on (.*) slips, and its tip only finds (.*)\'s shoulder blades/) {
		return "$2:2.0:2.0x";
	}
	if (/^Your clumsy attempt at a backstab barely hurts (.*) at all/) {
		return "$1:1.5:1.5x";
	}
	if (/^With unbelievable luck, (.*) moves away just as you slash at (.*) back/) {
		return "$1:0.0:whiff";
	}
}

# Melee alerts

sub MatchMelee {
	if ($MeleeMessagesEnabled == 0) {
		return 0;
	}
	if (/^(.*) chokes and utters some muffled noises./) {
		$notperson = substr($1, 2, (length($1)-2));
		return "${col_B}$notperson ${col_W}has been $plagued";
	}
	if (/^You choke and utter some muffled noises/) {
		return "${col_B}I ${col_W}have been $plagued"; 
}
	if (/^(.*) is surrounded by a pink outline/) {
		return "${col_B}$1 ${col_W}has been $ff";
	 }
	if (/^(.*) seems weaker./) {
		return "${col_B}$1 ${col_W}has been $weakened";
	}
	if (/^(.*) briefly reveals a red aura!/) {
		return "${col_B}$1 ${col_W}has been $cursed";
	}
	if (/^(.*) tenses for a moment, and moans in agony./) {
		return "${col_B}$1 ${col_W}has been $chilled";
	}
	if (/^You trip (.*) and/) {
		return "${col_B}I just $tripped ${col_G}$1 ${col_B}|| ${col_R}HP(${col_W}$hp${col_R}). ROOM(${col_Y}$room_name${col_R})";
	}
	if (/^You try to trip (.*), but/) {
		return "${col_B}I just ${col_W}MISSED ${col_B}a ${col_W}TRIP ${col_B}on ${col_G}$1 ${col_B}|| ${col_R}HP(${col_W}$hp${col_R}). ROOM(${col_Y}$room_name${col_R})";
	}
	if (/^You bash (.*) over the head/) {
		return "${col_B}I just $bashed ${col_G}$1 ${col_B}|| ${col_R}HP(${col_W}$hp${col_R}). ROOM(${col_Y}$room_name${col_R})";
	}
	if (/^As (.*) avoids your bash/) {
		return "${col_B}I just ${col_W}MISSED ${col_B}a ${col_W}BASH ${col_B}on ${col_G}$1 ${col_B}|| ${col_R}HP(${col_W}$hp${col_R}). ROOM(${col_Y}$room_name${col_R})";
	}
	if (/^The white glow around (.*) body fades/) {
		return "${col_B}$1 ${col_W} has just been $dispelleds";
	}
	if (/^Your white aura flashes brightly and disappears/) {
		return "${col_B}I ${col_W} have just been $dispelleds";
	} 
	if (/^(.*) turns his eyes away and screams/) {
		return "${col_B}$1 ${col_W} has just been $blinded";
	}
	if (/^(.*) seems to be blinded/) {
		return "${col_B}$1 ${col_W} has just been $blinded";
	}
	if (/^The bright burst of colors has blinded you/) {
		return "${col_B}I ${col_W} have just been $blinded";
	}
	if (/^Your (.*) kills (.*)/) {
		return "${col_W}My ${col_B}$1 ${col_W} just $killed ${col_B}$1"; 
	}
	if (/hurl a stream of violent wind at (.*)!/) {
			if (/is removed from/) { $howmanyppl += 1; } 
#		return "${col_G}$1 ${col_B}has just been ${col_W}HANDSED! ${col_B}|| ${col_R}HP(${col_W}$hp${col_R}). ROOM(${col_Y}$room_name${col_R})";
		return "$1 has been HANDSED, removing $howmanyppl members!";
	}
	if (/^You dodge a bash from (.*) who (.*)/) {
		return "${col_G}$1 ${col_B}just ${col_W}MISSED ${col_B}a ${col_W}BASH ${col_B}on ME! ${col_B}|| ${col_R}HP(${col_W}$hp${col_R}). ROOM(${col_Y}$room_name${col_R})";
	}
	if (/(.*) sends you sprawling with/) {
		return "${col_B}I was just ${col_W}BASHED ${col_B}by ${col_G}$1. ${col_B}|| ${col_R}HP(${col_W}$hp${col_R}). ROOM(${col_Y}$room_name${col_R})";
	}
	if (/(.*) tries to trip you/) {	
		return "${col_G}$1 ${col_B}just ${col_W}MISSED ${col_B}a ${col_W}TRIP ${col_B}on me! ${col_B}|| ${col_R}HP(${col_W}$hp${col_R}). ROOM(${col_Y}$room_name${col_R})";
	}
	if (/(.*) trips you and/) {
		return "${col_G}$1 ${col_B}just ${col_W}TRIPPED ${col_B}me! || ${col_R}HP(${col_W}$hp${col_R}). ROOM(${col_Y}$room_name${col_R})";
	}

}


# Alerts for status of enemy's health.

sub MatchCond {
	if (/^(.*) barely clings to life/) {
		return "clings(1-7%)";
	} 
	if (/^(.*) grimaces with pain/) {
		return "grimaces(48-54%)";
	}
	if (/^(.*) has a few scratches/) {
		return "scratches(90-99%)";
	}
	if (/^(.*) has a nasty looking welt on the forehead/) {
		return "welt(83-89%)";
	}
	if (/^(.*) has many grievous wounds/) {
		return "grieves(22%-28%)";
	}
	if (/^(.*) has quite a few wounds/) {
		return "quite a few wounds(55%-61%)";
	}
	if (/^(.*) has some large, gaping wounds/) {
		return "gaping wounds(36%-40%)";
	}
	if (/^(.*) has some minor wounds/) {
		return "minor(69-75%)";
	}
	if (/^(.*) has some nasty wounds and bleeding cuts/) {
		return "nasties(41-47%)";
	}
	if (/^(.*) has some small wounds and bruises/) {
		return "small wounds(76-82%)";
	}
	if (/^(.*) is covered with blood from oozing wounds/) {
		return "oozes(15-21%)";
	}
	if (/^(.*) is DEAD/) {
		return "DEAD";
	}
	if (/^(.*) is in excellent condition./) {
		return "excellent(100%)";
	}
	if (/^(.*) looks pretty awful/) {
		return "awful(29-35%)";
	}
	if (/^(.*) pales visibly as death nears/) {
		return "pales(8-14%)";
	}
	if (/^(.*) winces in pain/) {
		return "winces(62-68%)";
	}
}


sub trigger_alerts {
	my $output="";
	my $text = $_;

	# Strip Ansi Codes
	$text =~ s/(\xEA.|\xEA\n)//g;
	
	if ($output = MatchCond $text) {
		$enemy_condition = $output;
		return;
	}
	if ($output = MatchMelee $text) {
		run "${commandCharacter}chatall $output";
		return;
	}
	if ($output = MatchBS $text) {
		$bs_landed = 1;
		process_bs($output);
		return;		
	}
	if ($output = MatchEnemyBS $text) {
		$was_bsed = 1;
		process_bs($output);
		return;		
	}	
}


# Called when a line matched one of the bs messages.
# The parameter is the value that was hashed for that
# bs message.
sub process_bs($) {
	($enemy, $mult, $alert) = split ':', shift;
	$number_bses++;
	$target_enemy = $enemy;
	if ($alert =~ /TWIST/) {
		$MULTS{$last_mult} -= 1.0;
		$MULTS{$last_mult} += 1.5;
		$ALERTS{"TWIST"} += 1.0;
	}
	else {
		$MULTS{$mult} += 1.0;
		$ALERTS{$alert} += 1;
		# remember the last multiplier in case we twist.
		$last_mult = $mult;
	}
}

# This is called for each prompt.  If a bs occured since
# the last prompt, notify all listeners on chat.

sub bs_notify {	
	if ($bs_landed) {  
		foreach $key (keys %MULTS) {
			$bs_mult += ($key * $MULTS{$key});
		}
		foreach $key (keys %ALERTS) {
			if ($ALERTS{$key} > 1) {
				$alerts .= "$col_K($col_R$ALERTS{$key}${col_G}x$col_R$key$col_K)";
			}
			else {
				$alerts .= "$col_K($col_R$key$col_K)";
			}
		}
		$avg = sprintf("%.2f", $bs_mult);
		run "${commandCharacter}chatall emote just ${alerts} ${col_B}Mul${col_K}(${col_G}${avg}${col_K}) ${col_G}${target_enemy}${col_K}(${col_M}${enemy_condition}${col_K}) ${col_K}(${col_Y}${room_name}${col_K}) ${col_K}(${col_R}${new_hp} ${col_B}HP${col_K})";
		reset_variables();
	}
	if ($was_bsed) {
		foreach $key (keys %MULTS) {
			$bs_mult += ($key * $MULTS{$key});
		}
		foreach $key (keys %ALERTS) {
			if ($ALERTS{$key} > 1) {
				$alerts .= "$col_K($col_R$ALERTS{$key}${col_G}x$col_R$key$col_K)";
			}
			else {
				$alerts .= "$col_K($col_R$key$col_K)";
			}
		}
		$avg = sprintf("%.2f", $bs_mult);
		run "${commandCharacter}chatall emote ${col_B}was BSed by ${col_W}${target_enemy} ${col_B}\[${alerts}\] ${col_W}(${col_B}${room_name}${col_W}) (${col_B}${hp_change}${col_W}Dmg ${col_B}CurHp ${new_hp}${col_W})";
		reset_variables();
	}
}

sub reset_variables {
	$was_bsed = 0;
	$bs_landed = 0;
	$alerts = "";
	$target_enemy = "";
	$bs_mult = 0;
	$number_bses = 0;
	$enemy_condition = "";
	%MULTS = ();
	%ALERTS = ();
}


output_add(\&trigger_alerts);
prompt_add(\&bs_notify);
