Go Back   EQEmulator Home > EQEmulator Forums > Quests > Quests::Plugins & Mods

Quests::Plugins & Mods Completed plugins for public use as well as modifications.

Reply
 
Thread Tools Display Modes
  #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
  #2  
Old 02-24-2010, 10:30 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

That looks like a pretty fun plugin for custom servers wanting to simulate ranged attacks. I have actually been wanting to add one in that simulates it more like you might see on Live using the following commands and more:

Code:
CheckLoSToLoc(x, y, z, [mob_size])
ProjectileAnim(mob, item_id, [IsArrow?, speed, angle, tilt, arc])
DoSpecialAttackDamage()
Though, I may have to go even further and try to export some of the damage calculating functions from mob.cpp to perl so I can use the actual damage calculations for the NPC as if it was meleeing the client(s). I will have to look into it, but maybe some of these functions could be exported to allow for some cool flexibility:

Code:
bool Mob::CheckHitChance(Mob* other, SkillType skillinuse, int Hand)
bool Mob::AvoidDamage(Mob* other, sint32 &damage)
void Mob::MeleeMitigation(Mob *attacker, sint32 &damage, sint32 minhit)
bool NPC::Attack(Mob* other, int Hand, bool bRiposte)
sint32 Mob::ReduceDamage(sint32 damage)
sint32 Mob::ReduceMagicalDamage(sint32 damage)
I also think it would be nice to have an option for setting timers to allow it to set the timer in milliseconds instead of seconds. A simple optional bool at the end of the command should work just fine. You could then adjust timers to happen at any interval you could possibly want

Or, maybe I should just do it the right way and try to just write it all in the source code so Ranger class NPCs with Bows in their loot table or with a Bow weapon model equiped will use ranged attacks automatically (maybe with a rule option to enable). I think KLS has some ranged NPC code started already, so it might just mean finishing that code off. I think the hard part will be making it so they don't constantly run toward the character, as I think they should just get within a certain range and check LoS and shoot from that position until they are out of range or lose their LoS to the target.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!

Last edited by trevius; 02-24-2010 at 10:42 PM..
Reply With Quote
  #3  
Old 02-24-2010, 11:02 PM
nenelan
Hill Giant
 
Join Date: Feb 2008
Posts: 116
Default

Hmm. Your option is much better. I'm still rather new to the whole perl scripting side of things, so it was a challenge I made myself to see if I could do something a bit more advanced than "give me this item".
That being said, I did get a nice encounter working with this plugin, however, I will be the first to admit, it has its share of redundancy in the code, it is somewhat sloppy, and could be streamlined.
I admit I am very thrilled with the prospect of ranger (or any bow using npcs) using a bow if they have one in their loot table/model equipped. That's something that even live hasn't done yet!
Reply With Quote
  #4  
Old 12-27-2010, 08:23 PM
krujo81
Fire Beetle
 
Join Date: Feb 2009
Location: Here,There
Posts: 20
Default

kinda old i know but has anyone finshed anything 100%?. Because Necro swarm pet aa are supose to be archers yet they melee lol.

Ill take a look at this code and see if i cant use it but am rather new to this stuff myself
Reply With Quote
  #5  
Old 01-30-2011, 09:03 PM
Randymarsh9
Dragon
 
Join Date: Dec 2007
Posts: 658
Default

Yeah is this functional? I noticed there is a rule in the DB about npc archery damage now, but I haven't found a way to make them actually use bows.
Reply With Quote
  #6  
Old 01-30-2011, 09:59 PM
Caryatis
Dragon
 
Join Date: May 2009
Location: Milky Way
Posts: 541
Default

Add special attack 'Y' to NPCs and they will use archery if their target is out of melee range. The rule is a multiplier of their normal dmg since we dont have values for ranged npc dmg in the db yet.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 06:08 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3