Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
202
Scripts/Mobiles/AI/Magical AI/NinjaAI.cs
Normal file
202
Scripts/Mobiles/AI/Magical AI/NinjaAI.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server.Items;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Ninjitsu;
|
||||
#endregion
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class NinjaAI : MeleeAI
|
||||
{
|
||||
private DateTime m_NextCastTime;
|
||||
private DateTime m_NextRanged;
|
||||
|
||||
public NinjaAI(BaseCreature bc)
|
||||
: base(bc)
|
||||
{
|
||||
m_NextCastTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
private void TryPerformHide()
|
||||
{
|
||||
if (!m_Mobile.Alive || m_Mobile.Deleted)
|
||||
return;
|
||||
|
||||
if (!m_Mobile.Hidden && Core.TickCount - m_Mobile.NextSkillTime >= 0)
|
||||
{
|
||||
var chance = 0.05;
|
||||
|
||||
if (m_Mobile.Hits < 20)
|
||||
chance = 0.10;
|
||||
|
||||
if (m_Mobile.Poisoned)
|
||||
chance = 0.01;
|
||||
|
||||
if (Utility.RandomDouble() < chance)
|
||||
HideSelf();
|
||||
}
|
||||
}
|
||||
|
||||
private void HideSelf()
|
||||
{
|
||||
Effects.SendLocationParticles(
|
||||
EffectItem.Create(m_Mobile.Location, m_Mobile.Map, EffectItem.DefaultDuration),
|
||||
0x3728,
|
||||
10,
|
||||
10,
|
||||
2023);
|
||||
|
||||
m_Mobile.PlaySound(0x22F);
|
||||
m_Mobile.Hidden = true;
|
||||
|
||||
m_Mobile.UseSkill(SkillName.Stealth);
|
||||
}
|
||||
|
||||
public virtual SpecialMove GetHiddenSpecialMove()
|
||||
{
|
||||
var skill = (int)m_Mobile.Skills[SkillName.Ninjitsu].Value;
|
||||
|
||||
if (skill < 40)
|
||||
return null;
|
||||
|
||||
if (skill >= 60)
|
||||
{
|
||||
//return .5 > Utility.RandomDouble() ? new SupriseAttack() : new Backstab();
|
||||
return .5 > Utility.RandomDouble() ? SpellRegistry.GetSpecialMove(504) : SpellRegistry.GetSpecialMove(505);
|
||||
}
|
||||
|
||||
return SpellRegistry.GetSpecialMove(505); //new Backstab();
|
||||
}
|
||||
|
||||
public virtual SpecialMove GetSpecialMove()
|
||||
{
|
||||
var skill = (int)m_Mobile.Skills[SkillName.Ninjitsu].Value;
|
||||
|
||||
if (skill < 40)
|
||||
return null;
|
||||
|
||||
var avail = 1;
|
||||
|
||||
if (skill >= 85)
|
||||
avail = 3;
|
||||
else if (skill >= 80)
|
||||
avail = 2;
|
||||
|
||||
switch (Utility.Random(avail))
|
||||
{
|
||||
case 0:
|
||||
return SpellRegistry.GetSpecialMove(500); //new FocusAttack();
|
||||
case 1:
|
||||
return SpellRegistry.GetSpecialMove(503); //new KiAttack();
|
||||
case 2:
|
||||
return SpellRegistry.GetSpecialMove(501); //new DeathStrike();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void DoRangedAttack()
|
||||
{
|
||||
var c = m_Mobile.Combatant as Mobile;
|
||||
|
||||
if (c == null)
|
||||
return;
|
||||
|
||||
var list = new List<INinjaWeapon>();
|
||||
var d = (int)m_Mobile.GetDistanceToSqrt(c.Location);
|
||||
|
||||
foreach (var item in m_Mobile.Items)
|
||||
if (item is INinjaWeapon && ((INinjaWeapon)item).UsesRemaining > 0 && d >= ((INinjaWeapon)item).WeaponMinRange &&
|
||||
d <= ((INinjaWeapon)item).WeaponMaxRange)
|
||||
list.Add(item as INinjaWeapon);
|
||||
|
||||
if (m_Mobile.Backpack != null)
|
||||
{
|
||||
foreach (var item in m_Mobile.Backpack.Items)
|
||||
if (item is INinjaWeapon && ((INinjaWeapon)item).UsesRemaining > 0 && d >= ((INinjaWeapon)item).WeaponMinRange &&
|
||||
d <= ((INinjaWeapon)item).WeaponMaxRange)
|
||||
list.Add(item as INinjaWeapon);
|
||||
}
|
||||
|
||||
if (list.Count > 0)
|
||||
{
|
||||
var toUse = list[Utility.Random(list.Count)];
|
||||
|
||||
if (toUse != null)
|
||||
NinjaWeapon.Shoot(m_Mobile, c, toUse);
|
||||
}
|
||||
|
||||
ColUtility.Free(list);
|
||||
|
||||
m_NextRanged = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(30, 120));
|
||||
}
|
||||
|
||||
public override bool DoActionWander()
|
||||
{
|
||||
base.DoActionWander();
|
||||
|
||||
if (m_Mobile.Combatant == null)
|
||||
TryPerformHide();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool DoActionCombat()
|
||||
{
|
||||
base.DoActionCombat();
|
||||
|
||||
if (m_Mobile.Combatant == null)
|
||||
return true;
|
||||
|
||||
var special = SpecialMove.GetCurrentMove(m_Mobile);
|
||||
|
||||
if (special == null && m_NextCastTime < DateTime.UtcNow && 0.05 > Utility.RandomDouble())
|
||||
{
|
||||
if (0.05 > Utility.RandomDouble())
|
||||
{
|
||||
new MirrorImage(m_Mobile, null).Cast();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Mobile.Hidden)
|
||||
special = GetHiddenSpecialMove();
|
||||
else
|
||||
special = GetSpecialMove();
|
||||
|
||||
if (special != null)
|
||||
{
|
||||
SpecialMove.SetCurrentMove(m_Mobile, special);
|
||||
m_NextCastTime = DateTime.UtcNow + GetCastDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_NextRanged < DateTime.UtcNow && 0.08 > Utility.RandomDouble())
|
||||
DoRangedAttack();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool DoActionFlee()
|
||||
{
|
||||
base.DoActionFlee();
|
||||
TryPerformHide();
|
||||
return true;
|
||||
}
|
||||
|
||||
public TimeSpan GetCastDelay()
|
||||
{
|
||||
var skill = (int)m_Mobile.Skills[SkillName.Ninjitsu].Value;
|
||||
|
||||
if (skill >= 85)
|
||||
return TimeSpan.FromSeconds(15);
|
||||
if (skill > 40)
|
||||
return TimeSpan.FromSeconds(30);
|
||||
|
||||
return TimeSpan.FromSeconds(45);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user