feat: Adds SpecialAttack monster ability trigger. Fixes fanning fire. (#2186)
This commit is contained in:
parent
91b2912ee4
commit
e468f79e18
5 changed files with 89 additions and 119 deletions
|
|
@ -890,6 +890,11 @@ public abstract partial class BaseWeapon
|
|||
|
||||
if (attacker is BaseCreature bc)
|
||||
{
|
||||
if (bc.TriggerAbility(MonsterAbilityTrigger.CombatAction, defender))
|
||||
{
|
||||
return GetDelay(attacker);
|
||||
}
|
||||
|
||||
// Only change direction if they are not a player.
|
||||
attacker.Direction = attacker.GetDirectionTo(defender);
|
||||
var ab = bc.GetWeaponAbility();
|
||||
|
|
@ -1350,7 +1355,7 @@ public abstract partial class BaseWeapon
|
|||
theirValue = Math.Max(0.1, defValue + 50.0);
|
||||
}
|
||||
|
||||
var chance = ourValue / (theirValue * 2.0) * 1.0 + (double)bonus / 100;;
|
||||
var chance = ourValue / (theirValue * 2.0) * 1.0 + (double)bonus / 100;
|
||||
|
||||
if (Core.AOS && chance < 0.02)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -70,6 +70,11 @@ namespace Server.Items
|
|||
attacker.DisruptiveAction();
|
||||
attacker.NetState.SendSwing(attacker.Serial, defender.Serial);
|
||||
|
||||
if (attacker is BaseCreature bc && bc.TriggerAbility(MonsterAbilityTrigger.CombatAction, defender))
|
||||
{
|
||||
return GetDelay(attacker);
|
||||
}
|
||||
|
||||
if (OnFired(attacker, defender))
|
||||
{
|
||||
if (CheckHit(attacker, defender))
|
||||
|
|
|
|||
|
|
@ -5,8 +5,23 @@ namespace Server.Mobiles;
|
|||
public class FanningFire : MonsterAbilitySingleTargetDoT
|
||||
{
|
||||
public override MonsterAbilityType AbilityType => MonsterAbilityType.FanningFire;
|
||||
public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.GiveDamage;
|
||||
public override double ChanceToTrigger => 0.05;
|
||||
public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.CombatAction;
|
||||
|
||||
public FanningFire(double chanceToTrigger, int fireResistMod, int minDamage, int maxDamage)
|
||||
{
|
||||
ChanceToTrigger = chanceToTrigger;
|
||||
FireResistMod = fireResistMod;
|
||||
MinDamage = minDamage;
|
||||
MaxDamage = maxDamage;
|
||||
}
|
||||
|
||||
public sealed override double ChanceToTrigger { get; }
|
||||
|
||||
public int FireResistMod { get; }
|
||||
|
||||
public int MinDamage { get; }
|
||||
|
||||
public int MaxDamage { get; }
|
||||
|
||||
public const string Name = "FanningFire";
|
||||
|
||||
|
|
@ -52,16 +67,12 @@ public class FanningFire : MonsterAbilitySingleTargetDoT
|
|||
*/
|
||||
|
||||
source.DoHarmful(defender);
|
||||
var effect = -(defender.FireResistance / 10);
|
||||
defender.AddResistanceMod(new ResistanceMod(ResistanceType.Fire, Name, FireResistMod));
|
||||
|
||||
var mod = new ResistanceMod(ResistanceType.Fire, Name, effect);
|
||||
defender.AddResistanceMod(mod);
|
||||
|
||||
defender.FixedParticles(0x37B9, 10, 30, 0x34, EffectLayer.RightFoot);
|
||||
defender.FixedParticles(0x3709, 10, 30, 0x34, EffectLayer.RightFoot);
|
||||
defender.PlaySound(0x208);
|
||||
|
||||
// TODO: Trigger replaces a normal attack.
|
||||
AOS.Damage(defender, source, Utility.RandomMinMax(35, 45), 0, 100, 0, 0, 0);
|
||||
AOS.Damage(defender, source, Utility.RandomMinMax(MinDamage, MaxDamage), 0, 100, 0, 0, 0);
|
||||
}
|
||||
|
||||
protected override void EffectTick(BaseCreature source, Mobile defender, ref TimeSpan nextDelay)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public static class MonsterAbilities
|
|||
// Resistance Debuffs
|
||||
public static GraspingClaw GraspingClaw => new();
|
||||
public static RuneCorruption RuneCorruption => new();
|
||||
public static FanningFire FanningFire => new();
|
||||
public static FanningFire FanningFire => new(0.05, -10, 35, 45);
|
||||
|
||||
// Summon Undead
|
||||
public static SummonSkeletonsCounter SummonSkeletonsCounter => new();
|
||||
|
|
|
|||
|
|
@ -1,122 +1,71 @@
|
|||
using ModernUO.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Mobiles
|
||||
namespace Server.Mobiles;
|
||||
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class LadyJennifyr : SkeletalKnight
|
||||
{
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class LadyJennifyr : SkeletalKnight
|
||||
[Constructible]
|
||||
public LadyJennifyr()
|
||||
{
|
||||
private static readonly Dictionary<Mobile, ExpireTimer> m_Table = new();
|
||||
IsParagon = true;
|
||||
|
||||
[Constructible]
|
||||
public LadyJennifyr()
|
||||
{
|
||||
IsParagon = true;
|
||||
Hue = 0x76D;
|
||||
|
||||
Hue = 0x76D;
|
||||
SetStr(208, 309);
|
||||
SetDex(91, 118);
|
||||
SetInt(44, 101);
|
||||
|
||||
SetStr(208, 309);
|
||||
SetDex(91, 118);
|
||||
SetInt(44, 101);
|
||||
SetHits(1113, 1285);
|
||||
|
||||
SetHits(1113, 1285);
|
||||
SetDamage(15, 25);
|
||||
|
||||
SetDamage(15, 25);
|
||||
SetDamageType(ResistanceType.Physical, 40);
|
||||
SetDamageType(ResistanceType.Cold, 60);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 40);
|
||||
SetDamageType(ResistanceType.Cold, 60);
|
||||
SetResistance(ResistanceType.Physical, 56, 65);
|
||||
SetResistance(ResistanceType.Fire, 41, 49);
|
||||
SetResistance(ResistanceType.Cold, 71, 80);
|
||||
SetResistance(ResistanceType.Poison, 41, 50);
|
||||
SetResistance(ResistanceType.Energy, 50, 58);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 56, 65);
|
||||
SetResistance(ResistanceType.Fire, 41, 49);
|
||||
SetResistance(ResistanceType.Cold, 71, 80);
|
||||
SetResistance(ResistanceType.Poison, 41, 50);
|
||||
SetResistance(ResistanceType.Energy, 50, 58);
|
||||
SetSkill(SkillName.Wrestling, 127.9, 137.1);
|
||||
SetSkill(SkillName.Tactics, 128.4, 141.9);
|
||||
SetSkill(SkillName.MagicResist, 102.1, 119.5);
|
||||
SetSkill(SkillName.Anatomy, 129.0, 137.5);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 127.9, 137.1);
|
||||
SetSkill(SkillName.Tactics, 128.4, 141.9);
|
||||
SetSkill(SkillName.MagicResist, 102.1, 119.5);
|
||||
SetSkill(SkillName.Anatomy, 129.0, 137.5);
|
||||
|
||||
Fame = 18000;
|
||||
Karma = -18000;
|
||||
}
|
||||
|
||||
public override string CorpseName => "a Lady Jennifyr corpse";
|
||||
public override string DefaultName => "Lady Jennifyr";
|
||||
|
||||
/*
|
||||
// TODO: Uncomment once added
|
||||
public override void OnDeath( Container c )
|
||||
{
|
||||
base.OnDeath( c );
|
||||
|
||||
if (Utility.RandomDouble() < 0.15)
|
||||
c.DropItem( new DisintegratingThesisNotes() );
|
||||
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
c.DropItem( new ParrotItem() );
|
||||
}
|
||||
*/
|
||||
|
||||
public override bool GivesMLMinorArtifact => true;
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.UltraRich, 3);
|
||||
}
|
||||
|
||||
public override void OnGaveMeleeAttack(Mobile defender, int damage)
|
||||
{
|
||||
base.OnGaveMeleeAttack(defender, damage);
|
||||
|
||||
if (Utility.RandomDouble() < 0.9)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Table.Remove(defender, out var timer))
|
||||
{
|
||||
timer.DoExpire();
|
||||
}
|
||||
|
||||
defender.FixedParticles(0x3709, 10, 30, 5052, EffectLayer.LeftFoot);
|
||||
defender.PlaySound(0x208);
|
||||
// The creature fans you with fire, reducing your resistance to fire attacks.
|
||||
defender.SendLocalizedMessage(1070833);
|
||||
|
||||
var mod = new ResistanceMod(ResistanceType.Fire, "FireResistFanningFire", -10);
|
||||
defender.AddResistanceMod(mod);
|
||||
|
||||
m_Table[defender] = timer = new ExpireTimer(defender, mod);
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
private class ExpireTimer : Timer
|
||||
{
|
||||
private readonly Mobile m_Mobile;
|
||||
private readonly ResistanceMod m_Mod;
|
||||
|
||||
public ExpireTimer(Mobile m, ResistanceMod mod)
|
||||
: base(TimeSpan.FromSeconds(10))
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_Mod = mod;
|
||||
}
|
||||
|
||||
public void DoExpire()
|
||||
{
|
||||
m_Mobile.RemoveResistanceMod(m_Mod);
|
||||
|
||||
Stop();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1070834); // Your resistance to fire attacks has returned.
|
||||
DoExpire();
|
||||
m_Table.Remove(m_Mobile);
|
||||
}
|
||||
}
|
||||
Fame = 18000;
|
||||
Karma = -18000;
|
||||
}
|
||||
|
||||
public override string CorpseName => "a Lady Jennifyr corpse";
|
||||
public override string DefaultName => "Lady Jennifyr";
|
||||
|
||||
/*
|
||||
// TODO: Uncomment once added
|
||||
public override void OnDeath( Container c )
|
||||
{
|
||||
base.OnDeath( c );
|
||||
|
||||
if (Utility.RandomDouble() < 0.15)
|
||||
c.DropItem( new DisintegratingThesisNotes() );
|
||||
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
c.DropItem( new ParrotItem() );
|
||||
}
|
||||
*/
|
||||
|
||||
public override bool GivesMLMinorArtifact => true;
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.UltraRich, 3);
|
||||
}
|
||||
|
||||
private static readonly MonsterAbility[] _abilities =
|
||||
[
|
||||
new FanningFire(0.10, -10, 35, 45)
|
||||
];
|
||||
|
||||
public override MonsterAbility[] GetMonsterAbilities() => _abilities;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue