Compare commits
4 commits
main
...
kbatman/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51a57f98fc | ||
|
|
520a521c94 | ||
|
|
25bed78b59 | ||
|
|
5fe42912de |
6 changed files with 133 additions and 115 deletions
|
|
@ -1350,7 +1350,7 @@ public abstract partial class BaseWeapon
|
||||||
theirValue = Math.Max(0.1, defValue + 50.0);
|
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)
|
if (Core.AOS && chance < 0.02)
|
||||||
{
|
{
|
||||||
|
|
@ -1997,6 +1997,11 @@ public abstract partial class BaseWeapon
|
||||||
Bladeweave.BladeWeaving(attacker, out var bladeweavingAbi) &&
|
Bladeweave.BladeWeaving(attacker, out var bladeweavingAbi) &&
|
||||||
bladeweavingAbi is ArmorIgnore;
|
bladeweavingAbi is ArmorIgnore;
|
||||||
|
|
||||||
|
if (bcAtt?.TriggerAbilitySpecialAttack(defender) != true)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var damageGiven = AOS.Damage(
|
var damageGiven = AOS.Damage(
|
||||||
defender,
|
defender,
|
||||||
attacker,
|
attacker,
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,23 @@ namespace Server.Mobiles;
|
||||||
public class FanningFire : MonsterAbilitySingleTargetDoT
|
public class FanningFire : MonsterAbilitySingleTargetDoT
|
||||||
{
|
{
|
||||||
public override MonsterAbilityType AbilityType => MonsterAbilityType.FanningFire;
|
public override MonsterAbilityType AbilityType => MonsterAbilityType.FanningFire;
|
||||||
public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.GiveDamage;
|
public override MonsterAbilityTrigger AbilityTrigger => MonsterAbilityTrigger.SpecialAttack;
|
||||||
public override double ChanceToTrigger => 0.05;
|
|
||||||
|
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";
|
public const string Name = "FanningFire";
|
||||||
|
|
||||||
|
|
@ -52,16 +67,12 @@ public class FanningFire : MonsterAbilitySingleTargetDoT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
source.DoHarmful(defender);
|
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.FixedParticles(0x3709, 10, 30, 0x34, EffectLayer.RightFoot);
|
||||||
defender.AddResistanceMod(mod);
|
|
||||||
|
|
||||||
defender.FixedParticles(0x37B9, 10, 30, 0x34, EffectLayer.RightFoot);
|
|
||||||
defender.PlaySound(0x208);
|
defender.PlaySound(0x208);
|
||||||
|
|
||||||
// TODO: Trigger replaces a normal attack.
|
AOS.Damage(defender, source, Utility.RandomMinMax(MinDamage, MaxDamage), 0, 100, 0, 0, 0);
|
||||||
AOS.Damage(defender, source, Utility.RandomMinMax(35, 45), 0, 100, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void EffectTick(BaseCreature source, Mobile defender, ref TimeSpan nextDelay)
|
protected override void EffectTick(BaseCreature source, Mobile defender, ref TimeSpan nextDelay)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ public static class MonsterAbilities
|
||||||
// Resistance Debuffs
|
// Resistance Debuffs
|
||||||
public static GraspingClaw GraspingClaw => new();
|
public static GraspingClaw GraspingClaw => new();
|
||||||
public static RuneCorruption RuneCorruption => new();
|
public static RuneCorruption RuneCorruption => new();
|
||||||
public static FanningFire FanningFire => new();
|
public static FanningFire FanningFire => new(0.05, -10, 35, 45);
|
||||||
|
|
||||||
// Summon Undead
|
// Summon Undead
|
||||||
public static SummonSkeletonsCounter SummonSkeletonsCounter => new();
|
public static SummonSkeletonsCounter SummonSkeletonsCounter => new();
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ public enum MonsterAbilityTrigger : ulong
|
||||||
CombatAction = 0x0000000000000020,
|
CombatAction = 0x0000000000000020,
|
||||||
Death = 0x0000000000000040,
|
Death = 0x0000000000000040,
|
||||||
Movement = 0x0000000000000080,
|
Movement = 0x0000000000000080,
|
||||||
|
SpecialAttack = 0x0000000000000100, // Triggers instead of a regular attack
|
||||||
|
|
||||||
GiveDamage = GiveMeleeDamage | GiveSpellDamage,
|
GiveDamage = GiveMeleeDamage | GiveSpellDamage,
|
||||||
TakeDamage = TakeMeleeDamage | TakeSpellDamage
|
TakeDamage = TakeMeleeDamage | TakeSpellDamage
|
||||||
|
|
|
||||||
|
|
@ -1313,6 +1313,28 @@ namespace Server.Mobiles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool TriggerAbilitySpecialAttack(Mobile target)
|
||||||
|
{
|
||||||
|
var abilities = GetMonsterAbilities();
|
||||||
|
|
||||||
|
if (abilities == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < abilities.Length; i++)
|
||||||
|
{
|
||||||
|
var ability = abilities[i];
|
||||||
|
if (ability.CanTrigger(this, MonsterAbilityTrigger.SpecialAttack))
|
||||||
|
{
|
||||||
|
ability.Trigger(MonsterAbilityTrigger.SpecialAttack, this, target);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual WeaponAbility GetWeaponAbility() => null;
|
public virtual WeaponAbility GetWeaponAbility() => null;
|
||||||
|
|
||||||
public virtual bool IsEnemy(Mobile m)
|
public virtual bool IsEnemy(Mobile m)
|
||||||
|
|
|
||||||
|
|
@ -2,121 +2,100 @@ using ModernUO.Serialization;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class LadyJennifyr : SkeletalKnight
|
||||||
{
|
{
|
||||||
[SerializationGenerator(0, false)]
|
private static readonly Dictionary<Mobile, ExpireTimer> _table = new();
|
||||||
public partial class LadyJennifyr : SkeletalKnight
|
|
||||||
|
[Constructible]
|
||||||
|
public LadyJennifyr()
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<Mobile, ExpireTimer> m_Table = new();
|
IsParagon = true;
|
||||||
|
|
||||||
[Constructible]
|
Hue = 0x76D;
|
||||||
public LadyJennifyr()
|
|
||||||
|
SetStr(208, 309);
|
||||||
|
SetDex(91, 118);
|
||||||
|
SetInt(44, 101);
|
||||||
|
|
||||||
|
SetHits(1113, 1285);
|
||||||
|
|
||||||
|
SetDamage(15, 25);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly MonsterAbility[] _abilities =
|
||||||
|
[
|
||||||
|
new FanningFire(0.10, -10, 35, 45)
|
||||||
|
];
|
||||||
|
|
||||||
|
public override MonsterAbility[] GetMonsterAbilities() => _abilities;
|
||||||
|
|
||||||
|
private class ExpireTimer : Timer
|
||||||
|
{
|
||||||
|
private readonly Mobile _mobile;
|
||||||
|
private readonly ResistanceMod _mod;
|
||||||
|
|
||||||
|
public ExpireTimer(Mobile m, ResistanceMod mod) : base(TimeSpan.FromSeconds(10))
|
||||||
{
|
{
|
||||||
IsParagon = true;
|
_mobile = m;
|
||||||
|
_mod = mod;
|
||||||
Hue = 0x76D;
|
|
||||||
|
|
||||||
SetStr(208, 309);
|
|
||||||
SetDex(91, 118);
|
|
||||||
SetInt(44, 101);
|
|
||||||
|
|
||||||
SetHits(1113, 1285);
|
|
||||||
|
|
||||||
SetDamage(15, 25);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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 void DoExpire()
|
||||||
public override string DefaultName => "Lady Jennifyr";
|
|
||||||
|
|
||||||
/*
|
|
||||||
// TODO: Uncomment once added
|
|
||||||
public override void OnDeath( Container c )
|
|
||||||
{
|
{
|
||||||
base.OnDeath( c );
|
_mobile.RemoveResistanceMod(_mod);
|
||||||
|
|
||||||
if (Utility.RandomDouble() < 0.15)
|
Stop();
|
||||||
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)
|
protected override void OnTick()
|
||||||
{
|
{
|
||||||
base.OnGaveMeleeAttack(defender, damage);
|
_mobile.SendLocalizedMessage(1070834); // Your resistance to fire attacks has returned.
|
||||||
|
DoExpire();
|
||||||
if (Utility.RandomDouble() < 0.9)
|
_table.Remove(_mobile);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue