View Single Post
  #1  
Old 02-23-2010, 10:14 PM
nenelan
Hill Giant
 
Join Date: Feb 2008
Posts: 116
Default Plugin::ArcheryAttack()

Going to post it for now. May need more work, as I was unable to test the complete functionality for Hitting of All clients (couldn't set it up to connect more than one).

What this plugin will do is allow a mob to do a custom archery attack against either, Current Target, All Targets on hatelist, or a random target on the mob's hatelist.

Certain variables are settable in the main plugin file.

Plugin requires RandomRange() from the following link:
http://www.eqemulator.org/forums/showthread.php?t=30421

Here are the steps to add this plugin to your server:

1. Open notepad, or whatever text editor you prefer.

2. Copy and paste the following code into Notepad:

Code:
# Usage: plugin::ArcheryAttack(MeanDamage, Variance, TargNumber);
# MeanDamage - average damage of the attack
# Variance - +- % of mean as a range.
# TargNumber - 1: Current target, 2: All Targets on Hatelist, 3: Random Target from Hatelist
# Requires most current globals.pl and randomrange.pl plugins.

sub ArcheryAttack {

## Variables, set these to customize how the script works

$ACDiv = 75;     # 35% shielding (max default) at 2625 AC with ACDiv of 75
$PCTMiss = 5;    # Percent chance to miss outright
$PCTCrit = 5;    # Percent chance to critically hit
$MaxShield = 35; # Max Shielding percent
$ThroatDamage = 1.25; # Following variables edit the damage
$HeadDamage = 1.1;    # Based on where the arrow is striking
$ChestDamage = 1.0;   # Feel free to edit these to
$ArmDamage = 0.9;     # Suit your needs.
$LegDamage = 0.9;
$HandDamage = 0.75;
$FootDamage = 0.75;

## End Variables

$PCTMiss = 100-$PCTMiss+1;

	$npc = plugin::val('$npc');
	$entity_list = plugin::val('entity_list');

	my $MeanDamage = $_[0];
	my $Variance = $_[1];
	my $TargNumber = $_[2];
	my $MobName = $npc->GetCleanName();

	my $MinDamage = int ( $MeanDamage * (1-($Variance/100)) );
	my $MaxDamage = int ( $MeanDamage * (1+($Variance/100)) );
	$HitDmg = plugin::RandomRange($MinDamage, $MaxDamage);


	if ($TargNumber == 1) {
	       	$targ = $npc->GetHateTop();
		$hitname = $targ->GetName();
            	$targid = $targ->GetID();
		$targid = $entity_list->GetClientByID($targid);
		LocDmg();
		quest::emote("sights and releases an arrow at his most infuriating enemy, $hitname."); 
		quest::doanim(9);
		ApplyDamage();
	}

	if ($TargNumber == 2) {
		quest::emote("begins to a fire off a furious barrage of arrows, aiming at everyone around him!");
		quest::doanim(9);
		LocDmg();
		HitAllClients();
	}

	if ($TargNumber == 3) {
		$target = $npc->GetHateRandom();
		$targid = $target->GetID();
		$targid = $entity_list->GetClientByID($targid);
		$hitname = $target->GetName();
		LocDmg();	
		quest::emote("looses an arrow at $hitname at random.");
		quest::doanim(9);
		ApplyDamage();
	}
}

sub LocDmg {	

	$HitLoc = quest::ChooseRandom("head","head","leg","arm","chest","chest","throat","throat","hand","foot"); 

	CritOrMiss();

	if ($HitLoc eq "head") {
		$HitDmg = int($HitDmg*$HeadDamage);
	}

	if ($HitLoc eq "leg") {
		$HitDmg = int($HitDmg*$LegDamage);
	}

	if ($HitLoc eq "arm") {
		$HitDmg = int($HitDmg*$ArmDamage);
	}

	if ($HitLoc eq "throat") {
		$HitDmg = int($HitDmg*$ThroatDamage);
	}

	if ($HitLoc eq "hand" ) {
		$HitDmg = int($HitDmg*$HandDamage);
	}

	if ($HitLoc eq "foot") {
		$HitDmg = int($HitDmg*$FootDamage);
	}

	if ($HitLoc eq "chest") {
		$HitDmg = int($HitDmg*$ChestDamage);
	}
}


sub HitAllClients { 	
	my @hatelist = $npc->GetHateList();
	foreach $ent (@hatelist)
	{
		if($ent)
		{
			my $h_ent = $ent->GetEnt();
			if($h_ent)
			{
            			$targid = $h_ent->GetID();
				$targid = $entity_list->GetClientByID($targid);
				ApplyDamage();
			}
		}
	}
}

sub ApplyDamage {
	if ($HitDmg != 0) { 

	$pac = $targid->CastToMob()->GetAC();

	$shielding = $pac/$ACDiv;


	if ($shielding > $MaxShield) {
		$shielding = $MaxShield;
	}

	$shielding = $shielding/100;
	$HitDmg = int ($HitDmg * (1-$shielding));
	$targid->Damage($npc,$HitDmg,0,4);
		if ($DidCrit eq "crit") {
			$targid->Message(13,"You have been CRITICALLY STRUCK by an arrow in the $HitLoc for $HitDmg points of non-melee damage!");  
		}
		else {
			$targid->Message(13,"You have been struck by an arrow in the $HitLoc for $HitDmg points of non-melee damage!");  
		}
	}
	else {
		$targid->Message(13,"You breathe a sigh of relief as the arrow narrowly misses you!"); 
	}
}

sub CritOrMiss {

	$didmiss = int(rand(100));
	if ($didmiss > $PCTMiss) {
		$HitDmg = 0;
	}
	if ($didmiss <= $PCTCrit) {
		$DidCrit = "crit";
		$HitDmg = $HitDmg*2;
	}

	else {
		$DidCrit = "no";
	}
}
3. Save that file to your server /plugins/ folder and name it "ArcheryAttack.pl".

4. Look over the variables in the ArcheryAttack.pl that you just saved, can edit a few different variables to customize how it works in accordance with what you want.

5. Do a #questreload and the new plugin should be ready for use

Here is an example script:


Code:
sub EVENT_SPAWN {
	quest::stoptimer("attack");
}
sub EVENT_COMBAT {
	if ($combat_state == 1) {
		quest::settimer("attack",10);
	}
	if ($combat_state == 0) {
		quest::stoptimer("attack");
	}
}

sub EVENT_TIMER {

	plugin::ArcheryAttack(1000, 10, 1);


}
Every 10 seconds, the example script will fire an arrow at the the main tank. This arrow will have a base damage in the range of 900-1100, which is then further modified by where the arrow will strike. The arrow will then check to see if it crits or misses, and doubles damage on a crit, or set to 0 if it misses. The damage is then applied to the player through an invisible message, and a custom message is sent to the player telling them where they were struck by the arrow, and for how much.

Usage for this Plugin? Can set up a mob to have three timers once aggroed, one for the Single Target, one for the Hit all, one for hit random target on a permarooted mob and you now have a ranged fight. Give the mob high min/max damage to encourage people to stay out of melee. Was more developed as a way to see if I could do something like this.

Current caveat, I could not find a way to pull a player's Shielding, so I used AC to simulate (poorly) a player's shielding. AC / 75 = Shielding Percent. If anyone has any ideas to get around that, please let me know!
Reply With Quote