Fixes code according to modern code style. Fixes a few expression bugs.

This commit is contained in:
Kamron Batman 2018-09-15 09:58:51 -07:00
parent 89eea25e5f
commit 970fd563b2
3324 changed files with 441118 additions and 433755 deletions

View file

@ -5,82 +5,89 @@ using Server.Targeting;
namespace Server.SkillHandlers
{
public class Anatomy
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Anatomy].Callback = OnUse;
}
public class Anatomy
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Anatomy].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
m.Target = new InternalTarget();
public static TimeSpan OnUse(Mobile m)
{
m.Target = new InternalTarget();
m.SendLocalizedMessage( 500321 ); // Whom shall I examine?
m.SendLocalizedMessage(500321); // Whom shall I examine?
return TimeSpan.FromSeconds( 1.0 );
}
return TimeSpan.FromSeconds(1.0);
}
private class InternalTarget : Target
{
public InternalTarget() : base ( 8, false, TargetFlags.None )
{
}
private class InternalTarget : Target
{
public InternalTarget() : base(8, false, TargetFlags.None)
{
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( from == targeted )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500324 ); // You know yourself quite well enough already.
}
else if ( targeted is TownCrier )
{
((TownCrier)targeted).PrivateOverheadMessage( MessageType.Regular, 0x3B2, 500322, from.NetState ); // This person looks fine to me, though he may have some news...
}
else if ( targeted is BaseVendor && ((BaseVendor)targeted).IsInvulnerable )
{
((BaseVendor)targeted).PrivateOverheadMessage( MessageType.Regular, 0x3B2, 500326, from.NetState ); // That can not be inspected.
}
else if ( targeted is Mobile )
{
Mobile targ = (Mobile)targeted;
protected override void OnTarget(Mobile from, object targeted)
{
if (from == targeted)
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2,
500324); // You know yourself quite well enough already.
}
else if (targeted is TownCrier)
{
((TownCrier)targeted).PrivateOverheadMessage(MessageType.Regular, 0x3B2, 500322,
from.NetState); // This person looks fine to me, though he may have some news...
}
else if (targeted is BaseVendor && ((BaseVendor)targeted).IsInvulnerable)
{
((BaseVendor)targeted).PrivateOverheadMessage(MessageType.Regular, 0x3B2, 500326,
from.NetState); // That can not be inspected.
}
else if (targeted is Mobile)
{
Mobile targ = (Mobile)targeted;
int marginOfError = Math.Max( 0, 25 - (int)(from.Skills[SkillName.Anatomy].Value / 4) );
int marginOfError = Math.Max(0, 25 - (int)(from.Skills[SkillName.Anatomy].Value / 4));
int str = targ.Str + Utility.RandomMinMax( -marginOfError, +marginOfError );
int dex = targ.Dex + Utility.RandomMinMax( -marginOfError, +marginOfError );
int stm = ((targ.Stam * 100) / Math.Max( targ.StamMax, 1 )) + Utility.RandomMinMax( -marginOfError, +marginOfError );
int str = targ.Str + Utility.RandomMinMax(-marginOfError, +marginOfError);
int dex = targ.Dex + Utility.RandomMinMax(-marginOfError, +marginOfError);
int stm = targ.Stam * 100 / Math.Max(targ.StamMax, 1) +
Utility.RandomMinMax(-marginOfError, +marginOfError);
int strMod = str / 10;
int dexMod = dex / 10;
int stmMod = stm / 10;
int strMod = str / 10;
int dexMod = dex / 10;
int stmMod = stm / 10;
if ( strMod < 0 ) strMod = 0;
else if ( strMod > 10 ) strMod = 10;
if (strMod < 0) strMod = 0;
else if (strMod > 10) strMod = 10;
if ( dexMod < 0 ) dexMod = 0;
else if ( dexMod > 10 ) dexMod = 10;
if (dexMod < 0) dexMod = 0;
else if (dexMod > 10) dexMod = 10;
if ( stmMod > 10 ) stmMod = 10;
else if ( stmMod < 0 ) stmMod = 0;
if (stmMod > 10) stmMod = 10;
else if (stmMod < 0) stmMod = 0;
if ( from.CheckTargetSkill( SkillName.Anatomy, targ, 0, 100 ) )
{
targ.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1038045 + (strMod * 11) + dexMod, from.NetState ); // That looks [strong] and [dexterous].
if (from.CheckTargetSkill(SkillName.Anatomy, targ, 0, 100))
{
targ.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1038045 + strMod * 11 + dexMod,
from.NetState); // That looks [strong] and [dexterous].
if ( from.Skills[SkillName.Anatomy].Base >= 65.0 )
targ.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1038303 + stmMod, from.NetState ); // That being is at [10,20,...] percent endurance.
}
else
{
targ.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1042666, from.NetState ); // You can not quite get a sense of their physical characteristics.
}
}
else
{
(targeted as Item)?.SendLocalizedMessageTo( from, 500323, "" ); // Only living things have anatomies!
}
}
}
}
}
if (from.Skills[SkillName.Anatomy].Base >= 65.0)
targ.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1038303 + stmMod,
from.NetState); // That being is at [10,20,...] percent endurance.
}
else
{
targ.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1042666,
from.NetState); // You can not quite get a sense of their physical characteristics.
}
}
else
{
(targeted as Item)?.SendLocalizedMessageTo(from, 500323, ""); // Only living things have anatomies!
}
}
}
}
}

View file

@ -1,385 +1,406 @@
using System;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class AnimalLore
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.AnimalLore].Callback = OnUse;
}
public static TimeSpan OnUse(Mobile m)
{
m.Target = new InternalTarget();
m.SendLocalizedMessage( 500328 ); // What animal should I look at?
return TimeSpan.FromSeconds( 1.0 );
}
private class InternalTarget : Target
{
public InternalTarget() : base( 8, false, TargetFlags.None )
{
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( !from.Alive )
{
from.SendLocalizedMessage( 500331 ); // The spirits of the dead are not the province of animal lore.
}
else if ( targeted is BaseCreature )
{
BaseCreature c = (BaseCreature)targeted;
if ( !c.IsDeadPet )
{
if ( c.Body.IsAnimal || c.Body.IsMonster || c.Body.IsSea )
{
if ( !c.Controlled && from.Skills[SkillName.AnimalLore].Value < 100.0 )
{
from.SendLocalizedMessage( 1049674 ); // At your skill level, you can only lore tamed creatures.
}
else if ( !c.Controlled && !c.Tamable && from.Skills[SkillName.AnimalLore].Value < 110.0 )
{
from.SendLocalizedMessage( 1049675 ); // At your skill level, you can only lore tamed or tameable creatures.
}
else if ( !from.CheckTargetSkill( SkillName.AnimalLore, c, 0.0, 120.0 ) )
{
from.SendLocalizedMessage( 500334 ); // You can't think of anything you know offhand.
}
else
{
from.CloseGump( typeof( AnimalLoreGump ) );
from.SendGump( new AnimalLoreGump( c ) );
}
}
else
{
from.SendLocalizedMessage( 500329 ); // That's not an animal!
}
}
else
{
from.SendLocalizedMessage( 500331 ); // The spirits of the dead are not the province of animal lore.
}
}
else
{
from.SendLocalizedMessage( 500329 ); // That's not an animal!
}
}
}
}
public class AnimalLoreGump : Gump
{
private static string FormatSkill( BaseCreature c, SkillName name )
{
Skill skill = c.Skills[name];
if ( skill.Base < 10.0 )
return "<div align=right>---</div>";
return $"<div align=right>{skill.Value:F1}</div>";
}
private static string FormatAttributes( int cur, int max )
{
if ( max == 0 )
return "<div align=right>---</div>";
return $"<div align=right>{cur}/{max}</div>";
}
private static string FormatStat( int val )
{
if ( val == 0 )
return "<div align=right>---</div>";
return $"<div align=right>{val}</div>";
}
private static string FormatDouble( double val )
{
if ( val == 0 )
return "<div align=right>---</div>";
return $"<div align=right>{val:F1}</div>";
}
private static string FormatElement( int val )
{
if ( val <= 0 )
return "<div align=right>---</div>";
return $"<div align=right>{val}%</div>";
}
#region Mondain's Legacy
private static string FormatDamage( int min, int max )
{
if ( min <= 0 || max <= 0 )
return "<div align=right>---</div>";
return $"<div align=right>{min}-{max}</div>";
}
#endregion
private const int LabelColor = 0x24E5;
public AnimalLoreGump( BaseCreature c ) : base( 250, 50 )
{
AddPage( 0 );
AddImage( 100, 100, 2080 );
AddImage( 118, 137, 2081 );
AddImage( 118, 207, 2081 );
AddImage( 118, 277, 2081 );
AddImage( 118, 347, 2083 );
AddHtml( 147, 108, 210, 18, $"<center><i>{c.Name}</i></center>", false, false );
AddButton( 240, 77, 2093, 2093, 2, GumpButtonType.Reply, 0 );
AddImage( 140, 138, 2091 );
AddImage( 140, 335, 2091 );
int pages = ( Core.AOS ? 5 : 3 );
int page = 0;
#region Attributes
AddPage( ++page );
public class AnimalLore
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.AnimalLore].Callback = OnUse;
}
public static TimeSpan OnUse(Mobile m)
{
m.Target = new InternalTarget();
m.SendLocalizedMessage(500328); // What animal should I look at?
return TimeSpan.FromSeconds(1.0);
}
private class InternalTarget : Target
{
public InternalTarget() : base(8, false, TargetFlags.None)
{
}
protected override void OnTarget(Mobile from, object targeted)
{
if (!from.Alive)
{
from.SendLocalizedMessage(500331); // The spirits of the dead are not the province of animal lore.
}
else if (targeted is BaseCreature)
{
BaseCreature c = (BaseCreature)targeted;
if (!c.IsDeadPet)
{
if (c.Body.IsAnimal || c.Body.IsMonster || c.Body.IsSea)
{
if (!c.Controlled && from.Skills[SkillName.AnimalLore].Value < 100.0)
{
from.SendLocalizedMessage(
1049674); // At your skill level, you can only lore tamed creatures.
}
else if (!c.Controlled && !c.Tamable && from.Skills[SkillName.AnimalLore].Value < 110.0)
{
from.SendLocalizedMessage(
1049675); // At your skill level, you can only lore tamed or tameable creatures.
}
else if (!from.CheckTargetSkill(SkillName.AnimalLore, c, 0.0, 120.0))
{
from.SendLocalizedMessage(500334); // You can't think of anything you know offhand.
}
else
{
from.CloseGump(typeof(AnimalLoreGump));
from.SendGump(new AnimalLoreGump(c));
}
}
else
{
from.SendLocalizedMessage(500329); // That's not an animal!
}
}
else
{
from.SendLocalizedMessage(500331); // The spirits of the dead are not the province of animal lore.
}
}
else
{
from.SendLocalizedMessage(500329); // That's not an animal!
}
}
}
}
public class AnimalLoreGump : Gump
{
private const int LabelColor = 0x24E5;
public AnimalLoreGump(BaseCreature c) : base(250, 50)
{
AddPage(0);
AddImage(100, 100, 2080);
AddImage(118, 137, 2081);
AddImage(118, 207, 2081);
AddImage(118, 277, 2081);
AddImage(118, 347, 2083);
AddHtml(147, 108, 210, 18, $"<center><i>{c.Name}</i></center>", false, false);
AddButton(240, 77, 2093, 2093, 2, GumpButtonType.Reply, 0);
AddImage(140, 138, 2091);
AddImage(140, 335, 2091);
int pages = Core.AOS ? 5 : 3;
int page = 0;
#region Attributes
AddPage(++page);
AddImage(128, 152, 2086);
AddHtmlLocalized(147, 150, 160, 18, 1049593, 200, false, false); // Attributes
AddHtmlLocalized(153, 168, 160, 18, 1049578, LabelColor, false, false); // Hits
AddHtml(280, 168, 75, 18, FormatAttributes(c.Hits, c.HitsMax), false, false);
AddHtmlLocalized(153, 186, 160, 18, 1049579, LabelColor, false, false); // Stamina
AddHtml(280, 186, 75, 18, FormatAttributes(c.Stam, c.StamMax), false, false);
AddHtmlLocalized(153, 204, 160, 18, 1049580, LabelColor, false, false); // Mana
AddHtml(280, 204, 75, 18, FormatAttributes(c.Mana, c.ManaMax), false, false);
AddHtmlLocalized(153, 222, 160, 18, 1028335, LabelColor, false, false); // Strength
AddHtml(320, 222, 35, 18, FormatStat(c.Str), false, false);
AddHtmlLocalized(153, 240, 160, 18, 3000113, LabelColor, false, false); // Dexterity
AddHtml(320, 240, 35, 18, FormatStat(c.Dex), false, false);
AddHtmlLocalized(153, 258, 160, 18, 3000112, LabelColor, false, false); // Intelligence
AddHtml(320, 258, 35, 18, FormatStat(c.Int), false, false);
if (Core.AOS)
{
int y = 276;
if (Core.SE)
{
double bd = BaseInstrument.GetBaseDifficulty(c);
if (c.Uncalmable)
bd = 0;
AddImage( 128, 152, 2086 );
AddHtmlLocalized( 147, 150, 160, 18, 1049593, 200, false, false ); // Attributes
AddHtmlLocalized(153, 276, 160, 18, 1070793, LabelColor, false, false); // Barding Difficulty
AddHtml(320, y, 35, 18, FormatDouble(bd), false, false);
AddHtmlLocalized( 153, 168, 160, 18, 1049578, LabelColor, false, false ); // Hits
AddHtml( 280, 168, 75, 18, FormatAttributes( c.Hits, c.HitsMax ), false, false );
y += 18;
}
AddHtmlLocalized( 153, 186, 160, 18, 1049579, LabelColor, false, false ); // Stamina
AddHtml( 280, 186, 75, 18, FormatAttributes( c.Stam, c.StamMax ), false, false );
AddImage(128, y + 2, 2086);
AddHtmlLocalized(147, y, 160, 18, 1049594, 200, false, false); // Loyalty Rating
y += 18;
AddHtmlLocalized( 153, 204, 160, 18, 1049580, LabelColor, false, false ); // Mana
AddHtml( 280, 204, 75, 18, FormatAttributes( c.Mana, c.ManaMax ), false, false );
AddHtmlLocalized(153, y, 160, 18, !c.Controlled || c.Loyalty == 0 ? 1061643 : 1049595 + c.Loyalty / 10,
LabelColor, false, false);
}
else
{
AddImage(128, 278, 2086);
AddHtmlLocalized(147, 276, 160, 18, 3001016, 200, false, false); // Miscellaneous
AddHtmlLocalized( 153, 222, 160, 18, 1028335, LabelColor, false, false ); // Strength
AddHtml( 320, 222, 35, 18, FormatStat( c.Str ), false, false );
AddHtmlLocalized(153, 294, 160, 18, 1049581, LabelColor, false, false); // Armor Rating
AddHtml(320, 294, 35, 18, FormatStat(c.VirtualArmor), false, false);
}
AddHtmlLocalized( 153, 240, 160, 18, 3000113, LabelColor, false, false ); // Dexterity
AddHtml( 320, 240, 35, 18, FormatStat( c.Dex ), false, false );
AddButton(340, 358, 5601, 5605, 0, GumpButtonType.Page, page + 1);
AddButton(317, 358, 5603, 5607, 0, GumpButtonType.Page, pages);
AddHtmlLocalized( 153, 258, 160, 18, 3000112, LabelColor, false, false ); // Intelligence
AddHtml( 320, 258, 35, 18, FormatStat( c.Int ), false, false );
#endregion
if ( Core.AOS )
{
int y = 276;
#region Resistances
if ( Core.SE )
{
double bd = Items.BaseInstrument.GetBaseDifficulty( c );
if ( c.Uncalmable )
bd = 0;
if (Core.AOS)
{
AddPage(++page);
AddHtmlLocalized( 153, 276, 160, 18, 1070793, LabelColor, false, false ); // Barding Difficulty
AddHtml( 320, y, 35, 18, FormatDouble( bd ), false, false );
AddImage(128, 152, 2086);
AddHtmlLocalized(147, 150, 160, 18, 1061645, 200, false, false); // Resistances
y += 18;
}
AddHtmlLocalized(153, 168, 160, 18, 1061646, LabelColor, false, false); // Physical
AddHtml(320, 168, 35, 18, FormatElement(c.PhysicalResistance), false, false);
AddImage( 128, y + 2, 2086 );
AddHtmlLocalized( 147, y, 160, 18, 1049594, 200, false, false ); // Loyalty Rating
y += 18;
AddHtmlLocalized(153, 186, 160, 18, 1061647, LabelColor, false, false); // Fire
AddHtml(320, 186, 35, 18, FormatElement(c.FireResistance), false, false);
AddHtmlLocalized( 153, y, 160, 18, (!c.Controlled || c.Loyalty == 0) ? 1061643 : 1049595 + (c.Loyalty / 10), LabelColor, false, false );
}
else
{
AddImage( 128, 278, 2086 );
AddHtmlLocalized( 147, 276, 160, 18, 3001016, 200, false, false ); // Miscellaneous
AddHtmlLocalized(153, 204, 160, 18, 1061648, LabelColor, false, false); // Cold
AddHtml(320, 204, 35, 18, FormatElement(c.ColdResistance), false, false);
AddHtmlLocalized( 153, 294, 160, 18, 1049581, LabelColor, false, false ); // Armor Rating
AddHtml( 320, 294, 35, 18, FormatStat( c.VirtualArmor ), false, false );
}
AddHtmlLocalized(153, 222, 160, 18, 1061649, LabelColor, false, false); // Poison
AddHtml(320, 222, 35, 18, FormatElement(c.PoisonResistance), false, false);
AddButton( 340, 358, 5601, 5605, 0, GumpButtonType.Page, page + 1 );
AddButton( 317, 358, 5603, 5607, 0, GumpButtonType.Page, pages );
#endregion
AddHtmlLocalized(153, 240, 160, 18, 1061650, LabelColor, false, false); // Energy
AddHtml(320, 240, 35, 18, FormatElement(c.EnergyResistance), false, false);
#region Resistances
if ( Core.AOS )
{
AddPage( ++page );
AddButton(340, 358, 5601, 5605, 0, GumpButtonType.Page, page + 1);
AddButton(317, 358, 5603, 5607, 0, GumpButtonType.Page, page - 1);
}
AddImage( 128, 152, 2086 );
AddHtmlLocalized( 147, 150, 160, 18, 1061645, 200, false, false ); // Resistances
#endregion
AddHtmlLocalized( 153, 168, 160, 18, 1061646, LabelColor, false, false ); // Physical
AddHtml( 320, 168, 35, 18, FormatElement( c.PhysicalResistance ), false, false );
#region Damage
AddHtmlLocalized( 153, 186, 160, 18, 1061647, LabelColor, false, false ); // Fire
AddHtml( 320, 186, 35, 18, FormatElement( c.FireResistance ), false, false );
if (Core.AOS)
{
AddPage(++page);
AddHtmlLocalized( 153, 204, 160, 18, 1061648, LabelColor, false, false ); // Cold
AddHtml( 320, 204, 35, 18, FormatElement( c.ColdResistance ), false, false );
AddImage(128, 152, 2086);
AddHtmlLocalized(147, 150, 160, 18, 1017319, 200, false, false); // Damage
AddHtmlLocalized( 153, 222, 160, 18, 1061649, LabelColor, false, false ); // Poison
AddHtml( 320, 222, 35, 18, FormatElement( c.PoisonResistance ), false, false );
AddHtmlLocalized(153, 168, 160, 18, 1061646, LabelColor, false, false); // Physical
AddHtml(320, 168, 35, 18, FormatElement(c.PhysicalDamage), false, false);
AddHtmlLocalized( 153, 240, 160, 18, 1061650, LabelColor, false, false ); // Energy
AddHtml( 320, 240, 35, 18, FormatElement( c.EnergyResistance ), false, false );
AddHtmlLocalized(153, 186, 160, 18, 1061647, LabelColor, false, false); // Fire
AddHtml(320, 186, 35, 18, FormatElement(c.FireDamage), false, false);
AddButton( 340, 358, 5601, 5605, 0, GumpButtonType.Page, page + 1 );
AddButton( 317, 358, 5603, 5607, 0, GumpButtonType.Page, page - 1 );
}
#endregion
AddHtmlLocalized(153, 204, 160, 18, 1061648, LabelColor, false, false); // Cold
AddHtml(320, 204, 35, 18, FormatElement(c.ColdDamage), false, false);
#region Damage
if ( Core.AOS )
{
AddPage( ++page );
AddHtmlLocalized(153, 222, 160, 18, 1061649, LabelColor, false, false); // Poison
AddHtml(320, 222, 35, 18, FormatElement(c.PoisonDamage), false, false);
AddImage( 128, 152, 2086 );
AddHtmlLocalized( 147, 150, 160, 18, 1017319, 200, false, false ); // Damage
AddHtmlLocalized(153, 240, 160, 18, 1061650, LabelColor, false, false); // Energy
AddHtml(320, 240, 35, 18, FormatElement(c.EnergyDamage), false, false);
AddHtmlLocalized( 153, 168, 160, 18, 1061646, LabelColor, false, false ); // Physical
AddHtml( 320, 168, 35, 18, FormatElement( c.PhysicalDamage ), false, false );
#region Mondain's Legacy
AddHtmlLocalized( 153, 186, 160, 18, 1061647, LabelColor, false, false ); // Fire
AddHtml( 320, 186, 35, 18, FormatElement( c.FireDamage ), false, false );
if (Core.ML)
{
AddHtmlLocalized(153, 258, 160, 18, 1076750, LabelColor, false, false); // Base Damage
AddHtml(300, 258, 55, 18, FormatDamage(c.DamageMin, c.DamageMax), false, false);
}
AddHtmlLocalized( 153, 204, 160, 18, 1061648, LabelColor, false, false ); // Cold
AddHtml( 320, 204, 35, 18, FormatElement( c.ColdDamage ), false, false );
#endregion
AddHtmlLocalized( 153, 222, 160, 18, 1061649, LabelColor, false, false ); // Poison
AddHtml( 320, 222, 35, 18, FormatElement( c.PoisonDamage ), false, false );
AddButton(340, 358, 5601, 5605, 0, GumpButtonType.Page, page + 1);
AddButton(317, 358, 5603, 5607, 0, GumpButtonType.Page, page - 1);
}
AddHtmlLocalized( 153, 240, 160, 18, 1061650, LabelColor, false, false ); // Energy
AddHtml( 320, 240, 35, 18, FormatElement( c.EnergyDamage ), false, false );
#region Mondain's Legacy
if ( Core.ML )
{
AddHtmlLocalized( 153, 258, 160, 18, 1076750, LabelColor, false, false ); // Base Damage
AddHtml( 300, 258, 55, 18, FormatDamage( c.DamageMin, c.DamageMax ), false, false );
}
#endregion
AddButton( 340, 358, 5601, 5605, 0, GumpButtonType.Page, page + 1 );
AddButton( 317, 358, 5603, 5607, 0, GumpButtonType.Page, page - 1 );
}
#endregion
#region Skills
AddPage( ++page );
AddImage( 128, 152, 2086 );
AddHtmlLocalized( 147, 150, 160, 18, 3001030, 200, false, false ); // Combat Ratings
AddHtmlLocalized( 153, 168, 160, 18, 1044103, LabelColor, false, false ); // Wrestling
AddHtml( 320, 168, 35, 18, FormatSkill( c, SkillName.Wrestling ), false, false );
AddHtmlLocalized( 153, 186, 160, 18, 1044087, LabelColor, false, false ); // Tactics
AddHtml( 320, 186, 35, 18, FormatSkill( c, SkillName.Tactics ), false, false );
AddHtmlLocalized( 153, 204, 160, 18, 1044086, LabelColor, false, false ); // Magic Resistance
AddHtml( 320, 204, 35, 18, FormatSkill( c, SkillName.MagicResist ), false, false );
AddHtmlLocalized( 153, 222, 160, 18, 1044061, LabelColor, false, false ); // Anatomy
AddHtml( 320, 222, 35, 18, FormatSkill( c, SkillName.Anatomy ), false, false );
#region Mondain's Legacy
if ( c is CuSidhe )
{
AddHtmlLocalized( 153, 240, 160, 18, 1044077, LabelColor, false, false ); // Healing
AddHtml( 320, 240, 35, 18, FormatSkill( c, SkillName.Healing ), false, false );
}
else
{
AddHtmlLocalized( 153, 240, 160, 18, 1044090, LabelColor, false, false ); // Poisoning
AddHtml( 320, 240, 35, 18, FormatSkill( c, SkillName.Poisoning ), false, false );
}
#endregion
AddImage( 128, 260, 2086 );
AddHtmlLocalized( 147, 258, 160, 18, 3001032, 200, false, false ); // Lore & Knowledge
AddHtmlLocalized( 153, 276, 160, 18, 1044085, LabelColor, false, false ); // Magery
AddHtml( 320, 276, 35, 18, FormatSkill( c, SkillName.Magery ), false, false );
AddHtmlLocalized( 153, 294, 160, 18, 1044076, LabelColor, false, false ); // Evaluating Intelligence
AddHtml( 320, 294, 35, 18,FormatSkill( c, SkillName.EvalInt ), false, false );
AddHtmlLocalized( 153, 312, 160, 18, 1044106, LabelColor, false, false ); // Meditation
AddHtml( 320, 312, 35, 18, FormatSkill( c, SkillName.Meditation ), false, false );
AddButton( 340, 358, 5601, 5605, 0, GumpButtonType.Page, page + 1 );
AddButton( 317, 358, 5603, 5607, 0, GumpButtonType.Page, page - 1 );
#endregion
#region Misc
AddPage( ++page );
AddImage( 128, 152, 2086 );
AddHtmlLocalized( 147, 150, 160, 18, 1049563, 200, false, false ); // Preferred Foods
int foodPref = 3000340;
if ( (c.FavoriteFood & FoodType.FruitsAndVegies) != 0 )
foodPref = 1049565; // Fruits and Vegetables
else if ( (c.FavoriteFood & FoodType.GrainsAndHay) != 0 )
foodPref = 1049566; // Grains and Hay
else if ( (c.FavoriteFood & FoodType.Fish) != 0 )
foodPref = 1049568; // Fish
else if ( (c.FavoriteFood & FoodType.Meat) != 0 )
foodPref = 1049564; // Meat
else if ( (c.FavoriteFood & FoodType.Eggs) != 0 )
foodPref = 1044477; // Eggs
AddHtmlLocalized( 153, 168, 160, 18, foodPref, LabelColor, false, false );
AddImage( 128, 188, 2086 );
AddHtmlLocalized( 147, 186, 160, 18, 1049569, 200, false, false ); // Pack Instincts
int packInstinct = 3000340;
if ( (c.PackInstinct & PackInstinct.Canine) != 0 )
packInstinct = 1049570; // Canine
else if ( (c.PackInstinct & PackInstinct.Ostard) != 0 )
packInstinct = 1049571; // Ostard
else if ( (c.PackInstinct & PackInstinct.Feline) != 0 )
packInstinct = 1049572; // Feline
else if ( (c.PackInstinct & PackInstinct.Arachnid) != 0 )
packInstinct = 1049573; // Arachnid
else if ( (c.PackInstinct & PackInstinct.Daemon) != 0 )
packInstinct = 1049574; // Daemon
else if ( (c.PackInstinct & PackInstinct.Bear) != 0 )
packInstinct = 1049575; // Bear
else if ( (c.PackInstinct & PackInstinct.Equine) != 0 )
packInstinct = 1049576; // Equine
else if ( (c.PackInstinct & PackInstinct.Bull) != 0 )
packInstinct = 1049577; // Bull
AddHtmlLocalized( 153, 204, 160, 18, packInstinct, LabelColor, false, false );
if ( !Core.AOS )
{
AddImage( 128, 224, 2086 );
AddHtmlLocalized( 147, 222, 160, 18, 1049594, 200, false, false ); // Loyalty Rating
AddHtmlLocalized( 153, 240, 160, 18, (!c.Controlled || c.Loyalty == 0) ? 1061643 : 1049595 + (c.Loyalty / 10), LabelColor, false, false );
}
AddButton( 340, 358, 5601, 5605, 0, GumpButtonType.Page, 1 );
AddButton( 317, 358, 5603, 5607, 0, GumpButtonType.Page, page - 1 );
#endregion
}
}
#endregion
#region Skills
AddPage(++page);
AddImage(128, 152, 2086);
AddHtmlLocalized(147, 150, 160, 18, 3001030, 200, false, false); // Combat Ratings
AddHtmlLocalized(153, 168, 160, 18, 1044103, LabelColor, false, false); // Wrestling
AddHtml(320, 168, 35, 18, FormatSkill(c, SkillName.Wrestling), false, false);
AddHtmlLocalized(153, 186, 160, 18, 1044087, LabelColor, false, false); // Tactics
AddHtml(320, 186, 35, 18, FormatSkill(c, SkillName.Tactics), false, false);
AddHtmlLocalized(153, 204, 160, 18, 1044086, LabelColor, false, false); // Magic Resistance
AddHtml(320, 204, 35, 18, FormatSkill(c, SkillName.MagicResist), false, false);
AddHtmlLocalized(153, 222, 160, 18, 1044061, LabelColor, false, false); // Anatomy
AddHtml(320, 222, 35, 18, FormatSkill(c, SkillName.Anatomy), false, false);
#region Mondain's Legacy
if (c is CuSidhe)
{
AddHtmlLocalized(153, 240, 160, 18, 1044077, LabelColor, false, false); // Healing
AddHtml(320, 240, 35, 18, FormatSkill(c, SkillName.Healing), false, false);
}
else
{
AddHtmlLocalized(153, 240, 160, 18, 1044090, LabelColor, false, false); // Poisoning
AddHtml(320, 240, 35, 18, FormatSkill(c, SkillName.Poisoning), false, false);
}
#endregion
AddImage(128, 260, 2086);
AddHtmlLocalized(147, 258, 160, 18, 3001032, 200, false, false); // Lore & Knowledge
AddHtmlLocalized(153, 276, 160, 18, 1044085, LabelColor, false, false); // Magery
AddHtml(320, 276, 35, 18, FormatSkill(c, SkillName.Magery), false, false);
AddHtmlLocalized(153, 294, 160, 18, 1044076, LabelColor, false, false); // Evaluating Intelligence
AddHtml(320, 294, 35, 18, FormatSkill(c, SkillName.EvalInt), false, false);
AddHtmlLocalized(153, 312, 160, 18, 1044106, LabelColor, false, false); // Meditation
AddHtml(320, 312, 35, 18, FormatSkill(c, SkillName.Meditation), false, false);
AddButton(340, 358, 5601, 5605, 0, GumpButtonType.Page, page + 1);
AddButton(317, 358, 5603, 5607, 0, GumpButtonType.Page, page - 1);
#endregion
#region Misc
AddPage(++page);
AddImage(128, 152, 2086);
AddHtmlLocalized(147, 150, 160, 18, 1049563, 200, false, false); // Preferred Foods
int foodPref = 3000340;
if ((c.FavoriteFood & FoodType.FruitsAndVegies) != 0)
foodPref = 1049565; // Fruits and Vegetables
else if ((c.FavoriteFood & FoodType.GrainsAndHay) != 0)
foodPref = 1049566; // Grains and Hay
else if ((c.FavoriteFood & FoodType.Fish) != 0)
foodPref = 1049568; // Fish
else if ((c.FavoriteFood & FoodType.Meat) != 0)
foodPref = 1049564; // Meat
else if ((c.FavoriteFood & FoodType.Eggs) != 0)
foodPref = 1044477; // Eggs
AddHtmlLocalized(153, 168, 160, 18, foodPref, LabelColor, false, false);
AddImage(128, 188, 2086);
AddHtmlLocalized(147, 186, 160, 18, 1049569, 200, false, false); // Pack Instincts
int packInstinct = 3000340;
if ((c.PackInstinct & PackInstinct.Canine) != 0)
packInstinct = 1049570; // Canine
else if ((c.PackInstinct & PackInstinct.Ostard) != 0)
packInstinct = 1049571; // Ostard
else if ((c.PackInstinct & PackInstinct.Feline) != 0)
packInstinct = 1049572; // Feline
else if ((c.PackInstinct & PackInstinct.Arachnid) != 0)
packInstinct = 1049573; // Arachnid
else if ((c.PackInstinct & PackInstinct.Daemon) != 0)
packInstinct = 1049574; // Daemon
else if ((c.PackInstinct & PackInstinct.Bear) != 0)
packInstinct = 1049575; // Bear
else if ((c.PackInstinct & PackInstinct.Equine) != 0)
packInstinct = 1049576; // Equine
else if ((c.PackInstinct & PackInstinct.Bull) != 0)
packInstinct = 1049577; // Bull
AddHtmlLocalized(153, 204, 160, 18, packInstinct, LabelColor, false, false);
if (!Core.AOS)
{
AddImage(128, 224, 2086);
AddHtmlLocalized(147, 222, 160, 18, 1049594, 200, false, false); // Loyalty Rating
AddHtmlLocalized(153, 240, 160, 18, !c.Controlled || c.Loyalty == 0 ? 1061643 : 1049595 + c.Loyalty / 10,
LabelColor, false, false);
}
AddButton(340, 358, 5601, 5605, 0, GumpButtonType.Page, 1);
AddButton(317, 358, 5603, 5607, 0, GumpButtonType.Page, page - 1);
#endregion
}
private static string FormatSkill(BaseCreature c, SkillName name)
{
Skill skill = c.Skills[name];
if (skill.Base < 10.0)
return "<div align=right>---</div>";
return $"<div align=right>{skill.Value:F1}</div>";
}
private static string FormatAttributes(int cur, int max)
{
if (max == 0)
return "<div align=right>---</div>";
return $"<div align=right>{cur}/{max}</div>";
}
private static string FormatStat(int val)
{
if (val == 0)
return "<div align=right>---</div>";
return $"<div align=right>{val}</div>";
}
private static string FormatDouble(double val)
{
if (val == 0)
return "<div align=right>---</div>";
return $"<div align=right>{val:F1}</div>";
}
private static string FormatElement(int val)
{
if (val <= 0)
return "<div align=right>---</div>";
return $"<div align=right>{val}%</div>";
}
#region Mondain's Legacy
private static string FormatDamage(int min, int max)
{
if (min <= 0 || max <= 0)
return "<div align=right>---</div>";
return $"<div align=right>{min}-{max}</div>";
}
#endregion
}
}

View file

@ -1,404 +1,437 @@
using System;
using System.Collections.Generic;
using Server.Targeting;
using Server.Network;
using Server.Mobiles;
using Server.Factions;
using Server.Mobiles;
using Server.Network;
using Server.Spells;
using Server.Spells.Necromancy;
using Server.Spells.Spellweaving;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class AnimalTaming
{
private static Dictionary<Mobile, Mobile> m_BeingTamed = new Dictionary<Mobile, Mobile>();
public class AnimalTaming
{
private static Dictionary<Mobile, Mobile> m_BeingTamed = new Dictionary<Mobile, Mobile>();
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.AnimalTaming].Callback = OnUse;
}
public static bool DisableMessage{ get; set; }
public static bool DisableMessage { get; set; }
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.AnimalTaming].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
m.RevealingAction();
public static TimeSpan OnUse(Mobile m)
{
m.RevealingAction();
m.Target = new InternalTarget();
m.RevealingAction();
m.Target = new InternalTarget();
m.RevealingAction();
if ( !DisableMessage )
m.SendLocalizedMessage( 502789 ); // Tame which animal?
if (!DisableMessage)
m.SendLocalizedMessage(502789); // Tame which animal?
return TimeSpan.FromHours( 6.0 );
}
return TimeSpan.FromHours(6.0);
}
public static bool CheckMastery( Mobile tamer, BaseCreature creature )
{
BaseCreature familiar = (BaseCreature)Spells.Necromancy.SummonFamiliarSpell.Table[tamer];
public static bool CheckMastery(Mobile tamer, BaseCreature creature)
{
BaseCreature familiar = (BaseCreature)SummonFamiliarSpell.Table[tamer];
if ( familiar != null && !familiar.Deleted && familiar is DarkWolfFamiliar )
{
if ( creature is DireWolf || creature is GreyWolf || creature is TimberWolf || creature is WhiteWolf || creature is BakeKitsune )
return true;
}
if (familiar != null && !familiar.Deleted && familiar is DarkWolfFamiliar)
if (creature is DireWolf || creature is GreyWolf || creature is TimberWolf || creature is WhiteWolf ||
creature is BakeKitsune)
return true;
return false;
}
return false;
}
public static bool MustBeSubdued( BaseCreature bc )
{
if (bc.Owners.Count > 0) { return false; } //Checks to see if the animal has been tamed before
return bc.SubdueBeforeTame && (bc.Hits > (bc.HitsMax / 10));
}
public static bool MustBeSubdued(BaseCreature bc)
{
if (bc.Owners.Count > 0) return false;
return bc.SubdueBeforeTame && bc.Hits > bc.HitsMax / 10;
}
public static void ScaleStats( BaseCreature bc, double scalar )
{
if ( bc.RawStr > 0 )
bc.RawStr = (int)Math.Max( 1, bc.RawStr * scalar );
public static void ScaleStats(BaseCreature bc, double scalar)
{
if (bc.RawStr > 0)
bc.RawStr = (int)Math.Max(1, bc.RawStr * scalar);
if ( bc.RawDex > 0 )
bc.RawDex = (int)Math.Max( 1, bc.RawDex * scalar );
if (bc.RawDex > 0)
bc.RawDex = (int)Math.Max(1, bc.RawDex * scalar);
if ( bc.RawInt > 0 )
bc.RawInt = (int)Math.Max( 1, bc.RawInt * scalar );
if (bc.RawInt > 0)
bc.RawInt = (int)Math.Max(1, bc.RawInt * scalar);
if ( bc.HitsMaxSeed > 0 )
{
bc.HitsMaxSeed = (int)Math.Max( 1, bc.HitsMaxSeed * scalar );
bc.Hits = bc.Hits;
}
if (bc.HitsMaxSeed > 0)
{
bc.HitsMaxSeed = (int)Math.Max(1, bc.HitsMaxSeed * scalar);
bc.Hits = bc.Hits;
}
if ( bc.StamMaxSeed > 0 )
{
bc.StamMaxSeed = (int)Math.Max( 1, bc.StamMaxSeed * scalar );
bc.Stam = bc.Stam;
}
}
if (bc.StamMaxSeed > 0)
{
bc.StamMaxSeed = (int)Math.Max(1, bc.StamMaxSeed * scalar);
bc.Stam = bc.Stam;
}
}
public static void ScaleSkills( BaseCreature bc, double scalar )
{
ScaleSkills( bc, scalar, scalar );
}
public static void ScaleSkills(BaseCreature bc, double scalar)
{
ScaleSkills(bc, scalar, scalar);
}
public static void ScaleSkills( BaseCreature bc, double scalar, double capScalar )
{
for ( int i = 0; i < bc.Skills.Length; ++i )
{
bc.Skills[i].Base *= scalar;
public static void ScaleSkills(BaseCreature bc, double scalar, double capScalar)
{
for (int i = 0; i < bc.Skills.Length; ++i)
{
bc.Skills[i].Base *= scalar;
bc.Skills[i].Cap = Math.Max( 100.0, bc.Skills[i].Cap * capScalar );
bc.Skills[i].Cap = Math.Max(100.0, bc.Skills[i].Cap * capScalar);
if ( bc.Skills[i].Base > bc.Skills[i].Cap )
{
bc.Skills[i].Cap = bc.Skills[i].Base;
}
}
}
if (bc.Skills[i].Base > bc.Skills[i].Cap) bc.Skills[i].Cap = bc.Skills[i].Base;
}
}
private class InternalTarget : Target
{
private bool m_SetSkillTime = true;
private class InternalTarget : Target
{
private bool m_SetSkillTime = true;
public InternalTarget() : base ( Core.AOS ? 3 : 2, false, TargetFlags.None )
{
}
public InternalTarget() : base(Core.AOS ? 3 : 2, false, TargetFlags.None)
{
}
protected override void OnTargetFinish( Mobile from )
{
if (m_SetSkillTime)
from.NextSkillTime = Core.TickCount;
}
protected override void OnTargetFinish(Mobile from)
{
if (m_SetSkillTime)
from.NextSkillTime = Core.TickCount;
}
public virtual void ResetPacify( object obj )
{
if ( obj is BaseCreature )
{
((BaseCreature)obj).BardPacified = true;
}
}
public virtual void ResetPacify(object obj)
{
if (obj is BaseCreature) ((BaseCreature)obj).BardPacified = true;
}
protected override void OnTarget( Mobile from, object targeted )
{
from.RevealingAction();
protected override void OnTarget(Mobile from, object targeted)
{
from.RevealingAction();
if ( targeted is Mobile )
{
if ( targeted is BaseCreature )
{
BaseCreature creature = (BaseCreature)targeted;
if (targeted is Mobile)
{
if (targeted is BaseCreature)
{
BaseCreature creature = (BaseCreature)targeted;
if ( !creature.Tamable )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1049655, from.NetState ); // That creature cannot be tamed.
}
else if ( creature.Controlled )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502804, from.NetState ); // That animal looks tame already.
}
else if ( from.Female && !creature.AllowFemaleTamer )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1049653, from.NetState ); // That creature can only be tamed by males.
}
else if ( !from.Female && !creature.AllowMaleTamer )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1049652, from.NetState ); // That creature can only be tamed by females.
}
else if ( creature is CuSidhe && from.Race != Race.Elf )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502801, from.NetState ); // You can't tame that!
}
else if ( from.Followers + creature.ControlSlots > from.FollowersMax )
{
from.SendLocalizedMessage( 1049611 ); // You have too many followers to tame that creature.
}
else if ( creature.Owners.Count >= BaseCreature.MaxOwners && !creature.Owners.Contains( from ) )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1005615, from.NetState ); // This animal has had too many owners and is too upset for you to tame.
}
else if ( MustBeSubdued( creature ) )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1054025, from.NetState ); // You must subdue this creature before you can tame it!
}
else if ( CheckMastery( from, creature ) || from.Skills[SkillName.AnimalTaming].Value >= creature.MinTameSkill )
{
FactionWarHorse warHorse = creature as FactionWarHorse;
if (!creature.Tamable)
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1049655,
from.NetState); // That creature cannot be tamed.
}
else if (creature.Controlled)
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502804,
from.NetState); // That animal looks tame already.
}
else if (from.Female && !creature.AllowFemaleTamer)
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1049653,
from.NetState); // That creature can only be tamed by males.
}
else if (!from.Female && !creature.AllowMaleTamer)
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1049652,
from.NetState); // That creature can only be tamed by females.
}
else if (creature is CuSidhe && from.Race != Race.Elf)
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502801,
from.NetState); // You can't tame that!
}
else if (from.Followers + creature.ControlSlots > from.FollowersMax)
{
from.SendLocalizedMessage(1049611); // You have too many followers to tame that creature.
}
else if (creature.Owners.Count >= BaseCreature.MaxOwners && !creature.Owners.Contains(from))
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1005615,
from.NetState); // This animal has had too many owners and is too upset for you to tame.
}
else if (MustBeSubdued(creature))
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1054025,
from.NetState); // You must subdue this creature before you can tame it!
}
else if (CheckMastery(from, creature) ||
from.Skills[SkillName.AnimalTaming].Value >= creature.MinTameSkill)
{
FactionWarHorse warHorse = creature as FactionWarHorse;
if ( warHorse != null )
{
Faction faction = Faction.Find( from );
if (warHorse != null)
{
Faction faction = Faction.Find(from);
if ( faction == null || faction != warHorse.Faction )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1042590, from.NetState ); // You cannot tame this creature.
return;
}
}
if (faction == null || faction != warHorse.Faction)
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1042590,
from.NetState); // You cannot tame this creature.
return;
}
}
if ( m_BeingTamed.ContainsKey( creature ) )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502802, from.NetState ); // Someone else is already taming this.
}
else if ( creature.CanAngerOnTame && 0.95 >= Utility.RandomDouble() )
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502805, from.NetState ); // You seem to anger the beast!
creature.PlaySound( creature.GetAngerSound() );
creature.Direction = creature.GetDirectionTo( from );
if (m_BeingTamed.ContainsKey(creature))
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502802,
from.NetState); // Someone else is already taming this.
}
else if (creature.CanAngerOnTame && 0.95 >= Utility.RandomDouble())
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502805,
from.NetState); // You seem to anger the beast!
creature.PlaySound(creature.GetAngerSound());
creature.Direction = creature.GetDirectionTo(from);
if ( creature.BardPacified && Utility.RandomDouble() > .24)
{
Timer.DelayCall( TimeSpan.FromSeconds( 2.0 ), new TimerStateCallback( ResetPacify ), creature );
}
else
{
creature.BardEndTime = DateTime.UtcNow;
}
if (creature.BardPacified && Utility.RandomDouble() > .24)
Timer.DelayCall(TimeSpan.FromSeconds(2.0), new TimerStateCallback(ResetPacify),
creature);
else
creature.BardEndTime = DateTime.UtcNow;
creature.BardPacified = false;
creature.BardPacified = false;
creature.AIObject?.DoMove( creature.Direction );
creature.AIObject?.DoMove(creature.Direction);
if ( from is PlayerMobile && !(( (PlayerMobile)from ).HonorActive || TransformationSpellHelper.UnderTransformation( from, typeof( EtherealVoyageSpell ))))
creature.Combatant = from;
}
else
{
m_BeingTamed[creature] = from;
if (from is PlayerMobile &&
!(((PlayerMobile)from).HonorActive ||
TransformationSpellHelper.UnderTransformation(from, typeof(EtherealVoyageSpell))))
creature.Combatant = from;
}
else
{
m_BeingTamed[creature] = from;
from.LocalOverheadMessage( MessageType.Emote, 0x59, 1010597 ); // You start to tame the creature.
from.NonlocalOverheadMessage( MessageType.Emote, 0x59, 1010598 ); // *begins taming a creature.*
from.LocalOverheadMessage(MessageType.Emote, 0x59,
1010597); // You start to tame the creature.
from.NonlocalOverheadMessage(MessageType.Emote, 0x59,
1010598); // *begins taming a creature.*
new InternalTimer( from, creature, Utility.Random( 3, 2 ) ).Start();
new InternalTimer(from, creature, Utility.Random(3, 2)).Start();
m_SetSkillTime = false;
}
}
else
{
creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502806, from.NetState ); // You have no chance of taming this creature.
}
}
else
{
((Mobile)targeted).PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502469, from.NetState ); // That being cannot be tamed.
}
}
else
{
from.SendLocalizedMessage( 502801 ); // You can't tame that!
}
}
m_SetSkillTime = false;
}
}
else
{
creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502806,
from.NetState); // You have no chance of taming this creature.
}
}
else
{
((Mobile)targeted).PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502469,
from.NetState); // That being cannot be tamed.
}
}
else
{
from.SendLocalizedMessage(502801); // You can't tame that!
}
}
private class InternalTimer : Timer
{
private Mobile m_Tamer;
private BaseCreature m_Creature;
private int m_MaxCount;
private int m_Count;
private bool m_Paralyzed;
private DateTime m_StartTime;
private class InternalTimer : Timer
{
private int m_Count;
private BaseCreature m_Creature;
private int m_MaxCount;
private bool m_Paralyzed;
private DateTime m_StartTime;
private Mobile m_Tamer;
public InternalTimer( Mobile tamer, BaseCreature creature, int count ) : base( TimeSpan.FromSeconds( 3.0 ), TimeSpan.FromSeconds( 3.0 ), count )
{
m_Tamer = tamer;
m_Creature = creature;
m_MaxCount = count;
m_Paralyzed = creature.Paralyzed;
m_StartTime = DateTime.UtcNow;
Priority = TimerPriority.TwoFiftyMS;
}
public InternalTimer(Mobile tamer, BaseCreature creature, int count) : base(TimeSpan.FromSeconds(3.0),
TimeSpan.FromSeconds(3.0), count)
{
m_Tamer = tamer;
m_Creature = creature;
m_MaxCount = count;
m_Paralyzed = creature.Paralyzed;
m_StartTime = DateTime.UtcNow;
Priority = TimerPriority.TwoFiftyMS;
}
protected override void OnTick()
{
m_Count++;
protected override void OnTick()
{
m_Count++;
DamageEntry de = m_Creature.FindMostRecentDamageEntry( false );
bool alreadyOwned = m_Creature.Owners.Contains( m_Tamer );
DamageEntry de = m_Creature.FindMostRecentDamageEntry(false);
bool alreadyOwned = m_Creature.Owners.Contains(m_Tamer);
if ( !m_Tamer.InRange( m_Creature, Core.AOS ? 7 : 6 ) )
{
m_BeingTamed.Remove( m_Creature );
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502795, m_Tamer.NetState ); // You are too far away to continue taming.
Stop();
}
else if ( !m_Tamer.CheckAlive() )
{
m_BeingTamed.Remove( m_Creature );
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502796, m_Tamer.NetState ); // You are dead, and cannot continue taming.
Stop();
}
else if ( !m_Tamer.CanSee( m_Creature ) || !m_Tamer.InLOS( m_Creature ) || !CanPath() )
{
m_BeingTamed.Remove( m_Creature );
m_Tamer.NextSkillTime = Core.TickCount;
m_Tamer.SendLocalizedMessage( 1049654 ); // You do not have a clear path to the animal you are taming, and must cease your attempt.
Stop();
}
else if ( !m_Creature.Tamable )
{
m_BeingTamed.Remove( m_Creature );
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1049655, m_Tamer.NetState ); // That creature cannot be tamed.
Stop();
}
else if ( m_Creature.Controlled )
{
m_BeingTamed.Remove( m_Creature );
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502804, m_Tamer.NetState ); // That animal looks tame already.
Stop();
}
else if ( m_Creature.Owners.Count >= BaseCreature.MaxOwners && !m_Creature.Owners.Contains( m_Tamer ) )
{
m_BeingTamed.Remove( m_Creature );
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1005615, m_Tamer.NetState ); // This animal has had too many owners and is too upset for you to tame.
Stop();
}
else if ( MustBeSubdued( m_Creature ) )
{
m_BeingTamed.Remove( m_Creature );
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1054025, m_Tamer.NetState ); // You must subdue this creature before you can tame it!
Stop();
}
else if ( de != null && de.LastDamage > m_StartTime )
{
m_BeingTamed.Remove( m_Creature );
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502794, m_Tamer.NetState ); // The animal is too angry to continue taming.
Stop();
}
else if ( m_Count < m_MaxCount )
{
m_Tamer.RevealingAction();
if (!m_Tamer.InRange(m_Creature, Core.AOS ? 7 : 6))
{
m_BeingTamed.Remove(m_Creature);
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502795,
m_Tamer.NetState); // You are too far away to continue taming.
Stop();
}
else if (!m_Tamer.CheckAlive())
{
m_BeingTamed.Remove(m_Creature);
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502796,
m_Tamer.NetState); // You are dead, and cannot continue taming.
Stop();
}
else if (!m_Tamer.CanSee(m_Creature) || !m_Tamer.InLOS(m_Creature) || !CanPath())
{
m_BeingTamed.Remove(m_Creature);
m_Tamer.NextSkillTime = Core.TickCount;
m_Tamer.SendLocalizedMessage(
1049654); // You do not have a clear path to the animal you are taming, and must cease your attempt.
Stop();
}
else if (!m_Creature.Tamable)
{
m_BeingTamed.Remove(m_Creature);
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1049655,
m_Tamer.NetState); // That creature cannot be tamed.
Stop();
}
else if (m_Creature.Controlled)
{
m_BeingTamed.Remove(m_Creature);
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502804,
m_Tamer.NetState); // That animal looks tame already.
Stop();
}
else if (m_Creature.Owners.Count >= BaseCreature.MaxOwners && !m_Creature.Owners.Contains(m_Tamer))
{
m_BeingTamed.Remove(m_Creature);
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1005615,
m_Tamer.NetState); // This animal has had too many owners and is too upset for you to tame.
Stop();
}
else if (MustBeSubdued(m_Creature))
{
m_BeingTamed.Remove(m_Creature);
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1054025,
m_Tamer.NetState); // You must subdue this creature before you can tame it!
Stop();
}
else if (de != null && de.LastDamage > m_StartTime)
{
m_BeingTamed.Remove(m_Creature);
m_Tamer.NextSkillTime = Core.TickCount;
m_Creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502794,
m_Tamer.NetState); // The animal is too angry to continue taming.
Stop();
}
else if (m_Count < m_MaxCount)
{
m_Tamer.RevealingAction();
switch ( Utility.Random( 3 ) )
{
case 0: m_Tamer.PublicOverheadMessage( MessageType.Regular, 0x3B2, Utility.Random( 502790, 4 ) ); break;
case 1: m_Tamer.PublicOverheadMessage( MessageType.Regular, 0x3B2, Utility.Random( 1005608, 6 ) ); break;
case 2: m_Tamer.PublicOverheadMessage( MessageType.Regular, 0x3B2, Utility.Random( 1010593, 4 ) ); break;
}
switch (Utility.Random(3))
{
case 0:
m_Tamer.PublicOverheadMessage(MessageType.Regular, 0x3B2, Utility.Random(502790, 4));
break;
case 1:
m_Tamer.PublicOverheadMessage(MessageType.Regular, 0x3B2, Utility.Random(1005608, 6));
break;
case 2:
m_Tamer.PublicOverheadMessage(MessageType.Regular, 0x3B2, Utility.Random(1010593, 4));
break;
}
if ( !alreadyOwned ) // Passively check animal lore for gain
m_Tamer.CheckTargetSkill( SkillName.AnimalLore, m_Creature, 0.0, 120.0 );
if (!alreadyOwned) // Passively check animal lore for gain
m_Tamer.CheckTargetSkill(SkillName.AnimalLore, m_Creature, 0.0, 120.0);
if ( m_Creature.Paralyzed )
m_Paralyzed = true;
}
else
{
m_Tamer.RevealingAction();
m_Tamer.NextSkillTime = Core.TickCount;
m_BeingTamed.Remove( m_Creature );
if (m_Creature.Paralyzed)
m_Paralyzed = true;
}
else
{
m_Tamer.RevealingAction();
m_Tamer.NextSkillTime = Core.TickCount;
m_BeingTamed.Remove(m_Creature);
if ( m_Creature.Paralyzed )
m_Paralyzed = true;
if (m_Creature.Paralyzed)
m_Paralyzed = true;
if ( !alreadyOwned ) // Passively check animal lore for gain
m_Tamer.CheckTargetSkill( SkillName.AnimalLore, m_Creature, 0.0, 120.0 );
if (!alreadyOwned) // Passively check animal lore for gain
m_Tamer.CheckTargetSkill(SkillName.AnimalLore, m_Creature, 0.0, 120.0);
double minSkill = m_Creature.MinTameSkill + (m_Creature.Owners.Count * 6.0);
double minSkill = m_Creature.MinTameSkill + m_Creature.Owners.Count * 6.0;
if ( minSkill > -24.9 && CheckMastery( m_Tamer, m_Creature ) )
minSkill = -24.9; // 50% at 0.0?
if (minSkill > -24.9 && CheckMastery(m_Tamer, m_Creature))
minSkill = -24.9; // 50% at 0.0?
minSkill += 24.9;
minSkill += 24.9;
if ( CheckMastery( m_Tamer, m_Creature ) || alreadyOwned || m_Tamer.CheckTargetSkill( SkillName.AnimalTaming, m_Creature, minSkill - 25.0, minSkill + 25.0 ) )
{
if ( m_Creature.Owners.Count == 0 ) // First tame
{
if ( m_Creature is GreaterDragon )
{
ScaleSkills( m_Creature, 0.72, 0.90 ); // 72% of original skills trainable to 90%
m_Creature.Skills[SkillName.Magery].Base = m_Creature.Skills[SkillName.Magery].Cap; // Greater dragons have a 90% cap reduction and 90% skill reduction on magery
}
else if ( m_Paralyzed )
ScaleSkills( m_Creature, 0.86 ); // 86% of original skills if they were paralyzed during the taming
else
ScaleSkills( m_Creature, 0.90 ); // 90% of original skills
if (CheckMastery(m_Tamer, m_Creature) || alreadyOwned ||
m_Tamer.CheckTargetSkill(SkillName.AnimalTaming, m_Creature, minSkill - 25.0, minSkill + 25.0))
{
if (m_Creature.Owners.Count == 0) // First tame
{
if (m_Creature is GreaterDragon)
{
ScaleSkills(m_Creature, 0.72, 0.90); // 72% of original skills trainable to 90%
m_Creature.Skills[SkillName.Magery].Base =
m_Creature.Skills[SkillName.Magery]
.Cap; // Greater dragons have a 90% cap reduction and 90% skill reduction on magery
}
else if (m_Paralyzed)
{
ScaleSkills(m_Creature,
0.86); // 86% of original skills if they were paralyzed during the taming
}
else
{
ScaleSkills(m_Creature, 0.90); // 90% of original skills
}
if ( m_Creature.StatLossAfterTame )
ScaleStats( m_Creature, 0.50 );
}
if (m_Creature.StatLossAfterTame)
ScaleStats(m_Creature, 0.50);
}
if ( alreadyOwned )
{
m_Tamer.SendLocalizedMessage( 502797 ); // That wasn't even challenging.
}
else
{
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502799, m_Tamer.NetState ); // It seems to accept you as master.
m_Creature.Owners.Add( m_Tamer );
}
if (alreadyOwned)
{
m_Tamer.SendLocalizedMessage(502797); // That wasn't even challenging.
}
else
{
m_Creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502799,
m_Tamer.NetState); // It seems to accept you as master.
m_Creature.Owners.Add(m_Tamer);
}
m_Creature.SetControlMaster( m_Tamer );
m_Creature.IsBonded = false;
}
else
{
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502798, m_Tamer.NetState ); // You fail to tame the creature.
}
}
}
m_Creature.SetControlMaster(m_Tamer);
m_Creature.IsBonded = false;
}
else
{
m_Creature.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 502798,
m_Tamer.NetState); // You fail to tame the creature.
}
}
}
private bool CanPath()
{
IPoint3D p = m_Tamer as IPoint3D;
private bool CanPath()
{
IPoint3D p = m_Tamer;
if ( p == null )
return false;
if (p == null)
return false;
if ( m_Creature.InRange( new Point3D( p ), 1 ) )
return true;
if (m_Creature.InRange(new Point3D(p), 1))
return true;
MovementPath path = new MovementPath( m_Creature, new Point3D( p ) );
return path.Success;
}
}
}
}
}
MovementPath path = new MovementPath(m_Creature, new Point3D(p));
return path.Success;
}
}
}
}
}

View file

@ -6,162 +6,162 @@ using Server.Targeting;
namespace Server.SkillHandlers
{
public class ArmsLore
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.ArmsLore].Callback = OnUse;
}
public class ArmsLore
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.ArmsLore].Callback = OnUse;
}
public static TimeSpan OnUse(Mobile m)
{
m.Target = new InternalTarget();
public static TimeSpan OnUse(Mobile m)
{
m.Target = new InternalTarget();
m.SendLocalizedMessage( 500349 ); // What item do you wish to get information about?
m.SendLocalizedMessage(500349); // What item do you wish to get information about?
return TimeSpan.FromSeconds( 1.0 );
}
return TimeSpan.FromSeconds(1.0);
}
[PlayerVendorTarget]
private class InternalTarget : Target
{
public InternalTarget() : base( 2, false, TargetFlags.None )
{
AllowNonlocal = true;
}
[PlayerVendorTarget]
private class InternalTarget : Target
{
public InternalTarget() : base(2, false, TargetFlags.None)
{
AllowNonlocal = true;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is BaseWeapon )
{
if ( from.CheckTargetSkill( SkillName.ArmsLore, targeted, 0, 100 ) )
{
BaseWeapon weap = (BaseWeapon)targeted;
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is BaseWeapon)
{
if (from.CheckTargetSkill(SkillName.ArmsLore, targeted, 0, 100))
{
BaseWeapon weap = (BaseWeapon)targeted;
if ( weap.MaxHitPoints != 0 )
{
int hp = (int)((weap.HitPoints / (double)weap.MaxHitPoints) * 10);
if (weap.MaxHitPoints != 0)
{
int hp = (int)(weap.HitPoints / (double)weap.MaxHitPoints * 10);
if ( hp < 0 )
hp = 0;
else if ( hp > 9 )
hp = 9;
if (hp < 0)
hp = 0;
else if (hp > 9)
hp = 9;
from.SendLocalizedMessage( 1038285 + hp );
}
from.SendLocalizedMessage(1038285 + hp);
}
int damage = (weap.MaxDamage + weap.MinDamage) / 2;
int hand = (weap.Layer == Layer.OneHanded ? 0 : 1);
int damage = (weap.MaxDamage + weap.MinDamage) / 2;
int hand = weap.Layer == Layer.OneHanded ? 0 : 1;
if ( damage < 3 )
damage = 0;
else
damage = (int)Math.Ceiling( Math.Min( damage, 30 ) / 5.0 );
/*
else if ( damage < 6 )
damage = 1;
else if ( damage < 11 )
damage = 2;
else if ( damage < 16 )
damage = 3;
else if ( damage < 21 )
damage = 4;
else if ( damage < 26 )
damage = 5;
else
damage = 6;
* */
if (damage < 3)
damage = 0;
else
damage = (int)Math.Ceiling(Math.Min(damage, 30) / 5.0);
/*
else if ( damage < 6 )
damage = 1;
else if ( damage < 11 )
damage = 2;
else if ( damage < 16 )
damage = 3;
else if ( damage < 21 )
damage = 4;
else if ( damage < 26 )
damage = 5;
else
damage = 6;
* */
WeaponType type = weap.Type;
WeaponType type = weap.Type;
if ( type == WeaponType.Ranged )
from.SendLocalizedMessage( 1038224 + (damage * 9) );
else if ( type == WeaponType.Piercing )
from.SendLocalizedMessage( 1038218 + hand + (damage * 9) );
else if ( type == WeaponType.Slashing )
from.SendLocalizedMessage( 1038220 + hand + (damage * 9) );
else if ( type == WeaponType.Bashing )
from.SendLocalizedMessage( 1038222 + hand + (damage * 9) );
else
from.SendLocalizedMessage( 1038216 + hand + (damage * 9) );
if (type == WeaponType.Ranged)
from.SendLocalizedMessage(1038224 + damage * 9);
else if (type == WeaponType.Piercing)
from.SendLocalizedMessage(1038218 + hand + damage * 9);
else if (type == WeaponType.Slashing)
from.SendLocalizedMessage(1038220 + hand + damage * 9);
else if (type == WeaponType.Bashing)
from.SendLocalizedMessage(1038222 + hand + damage * 9);
else
from.SendLocalizedMessage(1038216 + hand + damage * 9);
if ( weap.Poison != null && weap.PoisonCharges > 0 )
from.SendLocalizedMessage( 1038284 ); // It appears to have poison smeared on it.
}
else
{
from.SendLocalizedMessage( 500353 ); // You are not certain...
}
}
else if (targeted is BaseArmor)
{
if ( from.CheckTargetSkill(SkillName.ArmsLore, targeted, 0, 100) )
{
BaseArmor arm = (BaseArmor)targeted;
if (weap.Poison != null && weap.PoisonCharges > 0)
from.SendLocalizedMessage(1038284); // It appears to have poison smeared on it.
}
else
{
from.SendLocalizedMessage(500353); // You are not certain...
}
}
else if (targeted is BaseArmor)
{
if (from.CheckTargetSkill(SkillName.ArmsLore, targeted, 0, 100))
{
BaseArmor arm = (BaseArmor)targeted;
if ( arm.MaxHitPoints != 0 )
{
int hp = (int)((arm.HitPoints / (double)arm.MaxHitPoints) * 10);
if (arm.MaxHitPoints != 0)
{
int hp = (int)(arm.HitPoints / (double)arm.MaxHitPoints * 10);
if ( hp < 0 )
hp = 0;
else if ( hp > 9 )
hp = 9;
if (hp < 0)
hp = 0;
else if (hp > 9)
hp = 9;
from.SendLocalizedMessage( 1038285 + hp );
}
from.SendLocalizedMessage(1038285 + hp);
}
from.SendLocalizedMessage( 1038295 + (int)Math.Ceiling( Math.Min( arm.ArmorRating, 35 ) / 5.0 ) );
/*
if ( arm.ArmorRating < 1 )
from.SendLocalizedMessage( 1038295 ); // This armor offers no defense against attackers.
else if ( arm.ArmorRating < 6 )
from.SendLocalizedMessage( 1038296 ); // This armor provides almost no protection.
else if ( arm.ArmorRating < 11 )
from.SendLocalizedMessage( 1038297 ); // This armor provides very little protection.
else if ( arm.ArmorRating < 16 )
from.SendLocalizedMessage( 1038298 ); // This armor offers some protection against blows.
else if ( arm.ArmorRating < 21 )
from.SendLocalizedMessage( 1038299 ); // This armor serves as sturdy protection.
else if ( arm.ArmorRating < 26 )
from.SendLocalizedMessage( 1038300 ); // This armor is a superior defense against attack.
else if ( arm.ArmorRating < 31 )
from.SendLocalizedMessage( 1038301 ); // This armor offers excellent protection.
else
from.SendLocalizedMessage( 1038302 ); // This armor is superbly crafted to provide maximum protection.
* */
}
else
{
from.SendLocalizedMessage( 500353 ); // You are not certain...
}
}
else if ( targeted is SwampDragon && ((SwampDragon)targeted).HasBarding )
{
SwampDragon pet = (SwampDragon)targeted;
from.SendLocalizedMessage(1038295 + (int)Math.Ceiling(Math.Min(arm.ArmorRating, 35) / 5.0));
/*
if ( arm.ArmorRating < 1 )
from.SendLocalizedMessage( 1038295 ); // This armor offers no defense against attackers.
else if ( arm.ArmorRating < 6 )
from.SendLocalizedMessage( 1038296 ); // This armor provides almost no protection.
else if ( arm.ArmorRating < 11 )
from.SendLocalizedMessage( 1038297 ); // This armor provides very little protection.
else if ( arm.ArmorRating < 16 )
from.SendLocalizedMessage( 1038298 ); // This armor offers some protection against blows.
else if ( arm.ArmorRating < 21 )
from.SendLocalizedMessage( 1038299 ); // This armor serves as sturdy protection.
else if ( arm.ArmorRating < 26 )
from.SendLocalizedMessage( 1038300 ); // This armor is a superior defense against attack.
else if ( arm.ArmorRating < 31 )
from.SendLocalizedMessage( 1038301 ); // This armor offers excellent protection.
else
from.SendLocalizedMessage( 1038302 ); // This armor is superbly crafted to provide maximum protection.
* */
}
else
{
from.SendLocalizedMessage(500353); // You are not certain...
}
}
else if (targeted is SwampDragon && ((SwampDragon)targeted).HasBarding)
{
SwampDragon pet = (SwampDragon)targeted;
if ( from.CheckTargetSkill( SkillName.ArmsLore, targeted, 0, 100 ) )
{
int perc = (4 * pet.BardingHP) / pet.BardingMaxHP;
if (from.CheckTargetSkill(SkillName.ArmsLore, targeted, 0, 100))
{
int perc = 4 * pet.BardingHP / pet.BardingMaxHP;
if ( perc < 0 )
perc = 0;
else if ( perc > 4 )
perc = 4;
if (perc < 0)
perc = 0;
else if (perc > 4)
perc = 4;
pet.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1053021 - perc, from.NetState );
}
else
{
from.SendLocalizedMessage( 500353 ); // You are not certain...
}
}
else
{
from.SendLocalizedMessage( 500352 ); // This is neither weapon nor armor.
}
}
}
}
}
pet.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1053021 - perc, from.NetState);
}
else
{
from.SendLocalizedMessage(500353); // You are not certain...
}
}
else
{
from.SendLocalizedMessage(500352); // This is neither weapon nor armor.
}
}
}
}
}

View file

@ -1,174 +1,179 @@
using System;
using Server.Misc;
using Server.Targeting;
using Server.Items;
using Server.Misc;
using Server.Network;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class Begging
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Begging].Callback = OnUse;
}
public class Begging
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Begging].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
m.RevealingAction();
public static TimeSpan OnUse(Mobile m)
{
m.RevealingAction();
m.Target = new InternalTarget();
m.RevealingAction();
m.Target = new InternalTarget();
m.RevealingAction();
m.SendLocalizedMessage( 500397 ); // To whom do you wish to grovel?
m.SendLocalizedMessage(500397); // To whom do you wish to grovel?
return TimeSpan.FromHours( 6.0 );
}
return TimeSpan.FromHours(6.0);
}
private class InternalTarget : Target
{
private bool m_SetSkillTime = true;
private class InternalTarget : Target
{
private bool m_SetSkillTime = true;
public InternalTarget() : base ( 12, false, TargetFlags.None )
{
}
public InternalTarget() : base(12, false, TargetFlags.None)
{
}
protected override void OnTargetFinish( Mobile from )
{
if ( m_SetSkillTime )
from.NextSkillTime = Core.TickCount;
}
protected override void OnTargetFinish(Mobile from)
{
if (m_SetSkillTime)
from.NextSkillTime = Core.TickCount;
}
protected override void OnTarget( Mobile from, object targeted )
{
from.RevealingAction();
protected override void OnTarget(Mobile from, object targeted)
{
from.RevealingAction();
int number = -1;
int number = -1;
if ( targeted is Mobile )
{
Mobile targ = (Mobile)targeted;
if (targeted is Mobile)
{
Mobile targ = (Mobile)targeted;
if ( targ.Player ) // We can't beg from players
{
number = 500398; // Perhaps just asking would work better.
}
else if ( !targ.Body.IsHuman ) // Make sure the NPC is human
{
number = 500399; // There is little chance of getting money from that!
}
else if ( !from.InRange( targ, 2 ) )
{
if ( !targ.Female )
number = 500401; // You are too far away to beg from him.
else
number = 500402; // You are too far away to beg from her.
}
else if ( !Core.ML && from.Mounted ) // If we're on a mount, who would give us money? TODO: guessed it's removed since ML
{
number = 500404; // They seem unwilling to give you any money.
}
else
{
// Face eachother
from.Direction = from.GetDirectionTo( targ );
targ.Direction = targ.GetDirectionTo( from );
if (targ.Player) // We can't beg from players
{
number = 500398; // Perhaps just asking would work better.
}
else if (!targ.Body.IsHuman) // Make sure the NPC is human
{
number = 500399; // There is little chance of getting money from that!
}
else if (!from.InRange(targ, 2))
{
if (!targ.Female)
number = 500401; // You are too far away to beg from him.
else
number = 500402; // You are too far away to beg from her.
}
else if (!Core.ML && from.Mounted
) // If we're on a mount, who would give us money? TODO: guessed it's removed since ML
{
number = 500404; // They seem unwilling to give you any money.
}
else
{
// Face eachother
from.Direction = from.GetDirectionTo(targ);
targ.Direction = targ.GetDirectionTo(from);
from.Animate( 32, 5, 1, true, false, 0 ); // Bow
from.Animate(32, 5, 1, true, false, 0); // Bow
new InternalTimer( from, targ ).Start();
new InternalTimer(from, targ).Start();
m_SetSkillTime = false;
}
}
else // Not a Mobile
{
number = 500399; // There is little chance of getting money from that!
}
m_SetSkillTime = false;
}
}
else // Not a Mobile
{
number = 500399; // There is little chance of getting money from that!
}
if ( number != -1 )
from.SendLocalizedMessage( number );
}
if (number != -1)
from.SendLocalizedMessage(number);
}
private class InternalTimer : Timer
{
private Mobile m_From, m_Target;
private class InternalTimer : Timer
{
private Mobile m_From, m_Target;
public InternalTimer( Mobile from, Mobile target ) : base( TimeSpan.FromSeconds( 2.0 ) )
{
m_From = from;
m_Target = target;
Priority = TimerPriority.TwoFiftyMS;
}
public InternalTimer(Mobile from, Mobile target) : base(TimeSpan.FromSeconds(2.0))
{
m_From = from;
m_Target = target;
Priority = TimerPriority.TwoFiftyMS;
}
protected override void OnTick()
{
Container theirPack = m_Target.Backpack;
protected override void OnTick()
{
Container theirPack = m_Target.Backpack;
double badKarmaChance = 0.5 - ((double)m_From.Karma / 8570);
double badKarmaChance = 0.5 - (double)m_From.Karma / 8570;
if ( theirPack == null )
{
m_From.SendLocalizedMessage( 500404 ); // They seem unwilling to give you any money.
}
else if ( m_From.Karma < 0 && badKarmaChance > Utility.RandomDouble() )
{
m_Target.PublicOverheadMessage( MessageType.Regular, m_Target.SpeechHue, 500406 ); // Thou dost not look trustworthy... no gold for thee today!
}
else if ( m_From.CheckTargetSkill( SkillName.Begging, m_Target, 0.0, 100.0 ) )
{
int toConsume = theirPack.GetAmount( typeof( Gold ) ) / 10;
int max = 10 + (m_From.Fame / 2500);
if (theirPack == null)
{
m_From.SendLocalizedMessage(500404); // They seem unwilling to give you any money.
}
else if (m_From.Karma < 0 && badKarmaChance > Utility.RandomDouble())
{
m_Target.PublicOverheadMessage(MessageType.Regular, m_Target.SpeechHue,
500406); // Thou dost not look trustworthy... no gold for thee today!
}
else if (m_From.CheckTargetSkill(SkillName.Begging, m_Target, 0.0, 100.0))
{
int toConsume = theirPack.GetAmount(typeof(Gold)) / 10;
int max = 10 + m_From.Fame / 2500;
if ( max > 14 )
max = 14;
else if ( max < 10 )
max = 10;
if (max > 14)
max = 14;
else if (max < 10)
max = 10;
if ( toConsume > max )
toConsume = max;
if (toConsume > max)
toConsume = max;
if ( toConsume > 0 )
{
int consumed = theirPack.ConsumeUpTo( typeof( Gold ), toConsume );
if (toConsume > 0)
{
int consumed = theirPack.ConsumeUpTo(typeof(Gold), toConsume);
if ( consumed > 0 )
{
m_Target.PublicOverheadMessage( MessageType.Regular, m_Target.SpeechHue, 500405 ); // I feel sorry for thee...
if (consumed > 0)
{
m_Target.PublicOverheadMessage(MessageType.Regular, m_Target.SpeechHue,
500405); // I feel sorry for thee...
Gold gold = new Gold( consumed );
Gold gold = new Gold(consumed);
m_From.AddToBackpack( gold );
m_From.PlaySound( gold.GetDropSound() );
m_From.AddToBackpack(gold);
m_From.PlaySound(gold.GetDropSound());
if ( m_From.Karma > -3000 )
{
int toLose = m_From.Karma + 3000;
if (m_From.Karma > -3000)
{
int toLose = m_From.Karma + 3000;
if ( toLose > 40 )
toLose = 40;
if (toLose > 40)
toLose = 40;
Titles.AwardKarma( m_From, -toLose, true );
}
}
else
{
m_Target.PublicOverheadMessage( MessageType.Regular, m_Target.SpeechHue, 500407 ); // I have not enough money to give thee any!
}
}
else
{
m_Target.PublicOverheadMessage( MessageType.Regular, m_Target.SpeechHue, 500407 ); // I have not enough money to give thee any!
}
}
else
{
m_Target.SendLocalizedMessage( 500404 ); // They seem unwilling to give you any money.
}
Titles.AwardKarma(m_From, -toLose, true);
}
}
else
{
m_Target.PublicOverheadMessage(MessageType.Regular, m_Target.SpeechHue,
500407); // I have not enough money to give thee any!
}
}
else
{
m_Target.PublicOverheadMessage(MessageType.Regular, m_Target.SpeechHue,
500407); // I have not enough money to give thee any!
}
}
else
{
m_Target.SendLocalizedMessage(500404); // They seem unwilling to give you any money.
}
m_From.NextSkillTime = Core.TickCount + 10000;
}
}
}
}
m_From.NextSkillTime = Core.TickCount + 10000;
}
}
}
}
}

View file

@ -6,105 +6,101 @@ using Server.Targeting;
namespace Server.SkillHandlers
{
public class DetectHidden
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.DetectHidden].Callback = OnUse;
}
public class DetectHidden
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.DetectHidden].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile src )
{
src.SendLocalizedMessage( 500819 );//Where will you search?
src.Target = new InternalTarget();
public static TimeSpan OnUse(Mobile src)
{
src.SendLocalizedMessage(500819); //Where will you search?
src.Target = new InternalTarget();
return TimeSpan.FromSeconds( 6.0 );
}
return TimeSpan.FromSeconds(6.0);
}
private class InternalTarget : Target
{
public InternalTarget() : base( 12, true, TargetFlags.None )
{
}
private class InternalTarget : Target
{
public InternalTarget() : base(12, true, TargetFlags.None)
{
}
protected override void OnTarget( Mobile src, object targ )
{
bool foundAnyone = false;
protected override void OnTarget(Mobile src, object targ)
{
bool foundAnyone = false;
Point3D p;
if ( targ is Mobile )
p = ((Mobile)targ).Location;
else if ( targ is Item )
p = ((Item)targ).Location;
else if ( targ is IPoint3D )
p = new Point3D( (IPoint3D)targ );
else
p = src.Location;
Point3D p;
if (targ is Mobile)
p = ((Mobile)targ).Location;
else if (targ is Item)
p = ((Item)targ).Location;
else if (targ is IPoint3D)
p = new Point3D((IPoint3D)targ);
else
p = src.Location;
double srcSkill = src.Skills[SkillName.DetectHidden].Value;
int range = (int)(srcSkill / 10.0);
double srcSkill = src.Skills[SkillName.DetectHidden].Value;
int range = (int)(srcSkill / 10.0);
if ( !src.CheckSkill( SkillName.DetectHidden, 0.0, 100.0 ) )
range /= 2;
if (!src.CheckSkill(SkillName.DetectHidden, 0.0, 100.0))
range /= 2;
BaseHouse house = BaseHouse.FindHouseAt( p, src.Map, 16 );
BaseHouse house = BaseHouse.FindHouseAt(p, src.Map, 16);
bool inHouse = ( house != null && house.IsFriend( src ) );
bool inHouse = house != null && house.IsFriend(src);
if ( inHouse )
range = 22;
if (inHouse)
range = 22;
if ( range > 0 )
{
IPooledEnumerable<Mobile> inRange = src.Map.GetMobilesInRange( p, range );
if (range > 0)
{
IPooledEnumerable<Mobile> inRange = src.Map.GetMobilesInRange(p, range);
foreach ( Mobile trg in inRange )
{
if ( trg.Hidden && src != trg )
{
double ss = srcSkill + Utility.Random( 21 ) - 10;
double ts = trg.Skills[SkillName.Hiding].Value + Utility.Random( 21 ) - 10;
foreach (Mobile trg in inRange)
if (trg.Hidden && src != trg)
{
double ss = srcSkill + Utility.Random(21) - 10;
double ts = trg.Skills[SkillName.Hiding].Value + Utility.Random(21) - 10;
if ( src.AccessLevel >= trg.AccessLevel && ( ss >= ts || ( inHouse && house.IsInside( trg ) ) ) )
{
if ( trg is ShadowKnight && (trg.X != p.X || trg.Y != p.Y) )
continue;
if (src.AccessLevel >= trg.AccessLevel && (ss >= ts || inHouse && house.IsInside(trg)))
{
if (trg is ShadowKnight && (trg.X != p.X || trg.Y != p.Y))
continue;
trg.RevealingAction();
trg.SendLocalizedMessage( 500814 ); // You have been revealed!
foundAnyone = true;
}
}
}
trg.RevealingAction();
trg.SendLocalizedMessage(500814); // You have been revealed!
foundAnyone = true;
}
}
inRange.Free();
inRange.Free();
if ( Faction.Find( src ) != null )
{
IPooledEnumerable<BaseFactionTrap> itemsInRange = src.Map.GetItemsInRange<BaseFactionTrap>( p, range );
if (Faction.Find(src) != null)
{
IPooledEnumerable<BaseFactionTrap> itemsInRange = src.Map.GetItemsInRange<BaseFactionTrap>(p, range);
foreach ( BaseFactionTrap trap in itemsInRange )
{
if ( src.CheckTargetSkill( SkillName.DetectHidden, trap, 80.0, 100.0 ) )
{
src.SendLocalizedMessage( 1042712, true, " " + (trap.Faction == null ? "" : trap.Faction.Definition.FriendlyName) ); // You reveal a trap placed by a faction:
foreach (BaseFactionTrap trap in itemsInRange)
if (src.CheckTargetSkill(SkillName.DetectHidden, trap, 80.0, 100.0))
{
src.SendLocalizedMessage(1042712, true,
" " + (trap.Faction == null
? ""
: trap.Faction.Definition.FriendlyName)); // You reveal a trap placed by a faction:
trap.Visible = true;
trap.BeginConceal();
trap.Visible = true;
trap.BeginConceal();
foundAnyone = true;
}
}
foundAnyone = true;
}
itemsInRange.Free();
}
}
itemsInRange.Free();
}
}
if ( !foundAnyone )
{
src.SendLocalizedMessage( 500817 ); // You can see nothing hidden there.
}
}
}
}
}
if (!foundAnyone) src.SendLocalizedMessage(500817); // You can see nothing hidden there.
}
}
}
}

View file

@ -1,264 +1,270 @@
using System;
using System.Collections;
using Server.Items;
using Server.Targeting;
using Server.Mobiles;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class Discordance
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Discordance].Callback = OnUse;
}
public class Discordance
{
private static Hashtable m_Table = new Hashtable();
public static TimeSpan OnUse( Mobile m )
{
m.RevealingAction();
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Discordance].Callback = OnUse;
}
BaseInstrument.PickInstrument( m, OnPickedInstrument );
public static TimeSpan OnUse(Mobile m)
{
m.RevealingAction();
return TimeSpan.FromSeconds( 1.0 ); // Cannot use another skill for 1 second
}
BaseInstrument.PickInstrument(m, OnPickedInstrument);
public static void OnPickedInstrument( Mobile from, BaseInstrument instrument )
{
from.RevealingAction();
from.SendLocalizedMessage( 1049541 ); // Choose the target for your song of discordance.
from.Target = new DiscordanceTarget( from, instrument );
from.NextSkillTime = Core.TickCount + 6000;
}
return TimeSpan.FromSeconds(1.0); // Cannot use another skill for 1 second
}
private class DiscordanceInfo
{
public Mobile m_From;
public Mobile m_Creature;
public DateTime m_EndTime;
public bool m_Ending;
public Timer m_Timer;
public int m_Effect;
public ArrayList m_Mods;
public static void OnPickedInstrument(Mobile from, BaseInstrument instrument)
{
from.RevealingAction();
from.SendLocalizedMessage(1049541); // Choose the target for your song of discordance.
from.Target = new DiscordanceTarget(from, instrument);
from.NextSkillTime = Core.TickCount + 6000;
}
public DiscordanceInfo( Mobile from, Mobile creature, int effect, ArrayList mods )
{
m_From = from;
m_Creature = creature;
m_EndTime = DateTime.UtcNow;
m_Ending = false;
m_Effect = effect;
m_Mods = mods;
public static bool GetEffect(Mobile targ, ref int effect)
{
DiscordanceInfo info = m_Table[targ] as DiscordanceInfo;
Apply();
}
if (info == null)
return false;
public void Apply()
{
for ( int i = 0; i < m_Mods.Count; ++i )
{
object mod = m_Mods[i];
effect = info.m_Effect;
return true;
}
if ( mod is ResistanceMod )
m_Creature.AddResistanceMod( (ResistanceMod) mod );
else if ( mod is StatMod )
m_Creature.AddStatMod( (StatMod) mod );
else if ( mod is SkillMod )
m_Creature.AddSkillMod( (SkillMod) mod );
}
}
private static void ProcessDiscordance(DiscordanceInfo info)
{
Mobile from = info.m_From;
Mobile targ = info.m_Creature;
bool ends = false;
public void Clear()
{
for ( int i = 0; i < m_Mods.Count; ++i )
{
object mod = m_Mods[i];
// According to uoherald bard must remain alive, visible, and
// within range of the target or the effect ends in 15 seconds.
if (!targ.Alive || targ.Deleted || !from.Alive || from.Hidden)
{
ends = true;
}
else
{
int range = (int)targ.GetDistanceToSqrt(from);
int maxRange = BaseInstrument.GetBardRange(from, SkillName.Discordance);
if ( mod is ResistanceMod )
m_Creature.RemoveResistanceMod( (ResistanceMod) mod );
else if ( mod is StatMod )
m_Creature.RemoveStatMod( ((StatMod) mod).Name );
else if ( mod is SkillMod )
m_Creature.RemoveSkillMod( (SkillMod) mod );
}
}
}
if (from.Map != targ.Map || range > maxRange)
ends = true;
}
private static Hashtable m_Table = new Hashtable();
if (ends && info.m_Ending && info.m_EndTime < DateTime.UtcNow)
{
info.m_Timer?.Stop();
public static bool GetEffect( Mobile targ, ref int effect )
{
DiscordanceInfo info = m_Table[targ] as DiscordanceInfo;
info.Clear();
m_Table.Remove(targ);
}
else
{
if (ends && !info.m_Ending)
{
info.m_Ending = true;
info.m_EndTime = DateTime.UtcNow + TimeSpan.FromSeconds(15);
}
else if (!ends)
{
info.m_Ending = false;
info.m_EndTime = DateTime.UtcNow;
}
if ( info == null )
return false;
targ.FixedEffect(0x376A, 1, 32);
}
}
effect = info.m_Effect;
return true;
}
private class DiscordanceInfo
{
public Mobile m_Creature;
public int m_Effect;
public bool m_Ending;
public DateTime m_EndTime;
public Mobile m_From;
public ArrayList m_Mods;
public Timer m_Timer;
private static void ProcessDiscordance( DiscordanceInfo info )
{
Mobile from = info.m_From;
Mobile targ = info.m_Creature;
bool ends = false;
public DiscordanceInfo(Mobile from, Mobile creature, int effect, ArrayList mods)
{
m_From = from;
m_Creature = creature;
m_EndTime = DateTime.UtcNow;
m_Ending = false;
m_Effect = effect;
m_Mods = mods;
// According to uoherald bard must remain alive, visible, and
// within range of the target or the effect ends in 15 seconds.
if ( !targ.Alive || targ.Deleted || !from.Alive || from.Hidden )
ends = true;
else
{
int range = (int) targ.GetDistanceToSqrt( from );
int maxRange = BaseInstrument.GetBardRange( from, SkillName.Discordance );
Apply();
}
if ( from.Map != targ.Map || range > maxRange )
ends = true;
}
public void Apply()
{
for (int i = 0; i < m_Mods.Count; ++i)
{
object mod = m_Mods[i];
if ( ends && info.m_Ending && info.m_EndTime < DateTime.UtcNow )
{
info.m_Timer?.Stop();
if (mod is ResistanceMod)
m_Creature.AddResistanceMod((ResistanceMod)mod);
else if (mod is StatMod)
m_Creature.AddStatMod((StatMod)mod);
else if (mod is SkillMod)
m_Creature.AddSkillMod((SkillMod)mod);
}
}
info.Clear();
m_Table.Remove( targ );
}
else
{
if ( ends && !info.m_Ending )
{
info.m_Ending = true;
info.m_EndTime = DateTime.UtcNow + TimeSpan.FromSeconds( 15 );
}
else if ( !ends )
{
info.m_Ending = false;
info.m_EndTime = DateTime.UtcNow;
}
public void Clear()
{
for (int i = 0; i < m_Mods.Count; ++i)
{
object mod = m_Mods[i];
targ.FixedEffect( 0x376A, 1, 32 );
}
}
if (mod is ResistanceMod)
m_Creature.RemoveResistanceMod((ResistanceMod)mod);
else if (mod is StatMod)
m_Creature.RemoveStatMod(((StatMod)mod).Name);
else if (mod is SkillMod)
m_Creature.RemoveSkillMod((SkillMod)mod);
}
}
}
public class DiscordanceTarget : Target
{
private BaseInstrument m_Instrument;
public class DiscordanceTarget : Target
{
private BaseInstrument m_Instrument;
public DiscordanceTarget( Mobile from, BaseInstrument inst ) : base( BaseInstrument.GetBardRange( from, SkillName.Discordance ), false, TargetFlags.None )
{
m_Instrument = inst;
}
public DiscordanceTarget(Mobile from, BaseInstrument inst) : base(
BaseInstrument.GetBardRange(from, SkillName.Discordance), false, TargetFlags.None)
{
m_Instrument = inst;
}
protected override void OnTarget( Mobile from, object target )
{
from.RevealingAction();
from.NextSkillTime = Core.TickCount + 1000;
protected override void OnTarget(Mobile from, object target)
{
from.RevealingAction();
from.NextSkillTime = Core.TickCount + 1000;
if ( !m_Instrument.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1062488 ); // The instrument you are trying to play is no longer in your backpack!
}
else if ( target is Mobile )
{
Mobile targ = (Mobile)target;
if (!m_Instrument.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(
1062488); // The instrument you are trying to play is no longer in your backpack!
}
else if (target is Mobile)
{
Mobile targ = (Mobile)target;
if ( targ == from || (targ is BaseCreature && ( ((BaseCreature)targ).BardImmune || !from.CanBeHarmful( targ, false ) ) && ((BaseCreature)targ).ControlMaster != from) )
{
from.SendLocalizedMessage( 1049535 ); // A song of discord would have no effect on that.
}
else if ( m_Table.Contains( targ ) ) //Already discorded
{
from.SendLocalizedMessage( 1049537 );// Your target is already in discord.
}
else if ( !targ.Player )
{
double diff = m_Instrument.GetDifficultyFor( targ ) - 10.0;
double music = from.Skills[SkillName.Musicianship].Value;
if (targ == from || targ is BaseCreature &&
(((BaseCreature)targ).BardImmune || !from.CanBeHarmful(targ, false)) &&
((BaseCreature)targ).ControlMaster != from)
{
from.SendLocalizedMessage(1049535); // A song of discord would have no effect on that.
}
else if (m_Table.Contains(targ)) //Already discorded
{
from.SendLocalizedMessage(1049537); // Your target is already in discord.
}
else if (!targ.Player)
{
double diff = m_Instrument.GetDifficultyFor(targ) - 10.0;
double music = from.Skills[SkillName.Musicianship].Value;
if ( music > 100.0 )
diff -= (music - 100.0) * 0.5;
if (music > 100.0)
diff -= (music - 100.0) * 0.5;
if ( !BaseInstrument.CheckMusicianship( from ) )
{
from.SendLocalizedMessage( 500612 ); // You play poorly, and there is no effect.
m_Instrument.PlayInstrumentBadly( from );
m_Instrument.ConsumeUse( from );
}
else if ( from.CheckTargetSkill( SkillName.Discordance, target, diff-25.0, diff+25.0 ) )
{
from.SendLocalizedMessage( 1049539 ); // You play the song surpressing your targets strength
m_Instrument.PlayInstrumentWell( from );
m_Instrument.ConsumeUse( from );
if (!BaseInstrument.CheckMusicianship(from))
{
from.SendLocalizedMessage(500612); // You play poorly, and there is no effect.
m_Instrument.PlayInstrumentBadly(from);
m_Instrument.ConsumeUse(from);
}
else if (from.CheckTargetSkill(SkillName.Discordance, target, diff - 25.0, diff + 25.0))
{
from.SendLocalizedMessage(1049539); // You play the song surpressing your targets strength
m_Instrument.PlayInstrumentWell(from);
m_Instrument.ConsumeUse(from);
ArrayList mods = new ArrayList();
int effect;
double scalar;
ArrayList mods = new ArrayList();
int effect;
double scalar;
if ( Core.AOS )
{
double discord = from.Skills[SkillName.Discordance].Value;
if (Core.AOS)
{
double discord = from.Skills[SkillName.Discordance].Value;
if ( discord > 100.0 )
effect = -20 + (int)((discord - 100.0) / -2.5);
else
effect = (int)(discord / -5.0);
if (discord > 100.0)
effect = -20 + (int)((discord - 100.0) / -2.5);
else
effect = (int)(discord / -5.0);
if ( Core.SE && BaseInstrument.GetBaseDifficulty( targ ) >= 160.0 )
effect /= 2;
if (Core.SE && BaseInstrument.GetBaseDifficulty(targ) >= 160.0)
effect /= 2;
scalar = effect * 0.01;
scalar = effect * 0.01;
mods.Add( new ResistanceMod( ResistanceType.Physical, effect ) );
mods.Add( new ResistanceMod( ResistanceType.Fire, effect ) );
mods.Add( new ResistanceMod( ResistanceType.Cold, effect ) );
mods.Add( new ResistanceMod( ResistanceType.Poison, effect ) );
mods.Add( new ResistanceMod( ResistanceType.Energy, effect ) );
mods.Add(new ResistanceMod(ResistanceType.Physical, effect));
mods.Add(new ResistanceMod(ResistanceType.Fire, effect));
mods.Add(new ResistanceMod(ResistanceType.Cold, effect));
mods.Add(new ResistanceMod(ResistanceType.Poison, effect));
mods.Add(new ResistanceMod(ResistanceType.Energy, effect));
for ( int i = 0; i < targ.Skills.Length; ++i )
{
if ( targ.Skills[i].Value > 0 )
mods.Add( new DefaultSkillMod( (SkillName)i, true, targ.Skills[i].Value * scalar ) );
}
}
else
{
effect = (int)( from.Skills[SkillName.Discordance].Value / -5.0 );
scalar = effect * 0.01;
for (int i = 0; i < targ.Skills.Length; ++i)
if (targ.Skills[i].Value > 0)
mods.Add(new DefaultSkillMod((SkillName)i, true, targ.Skills[i].Value * scalar));
}
else
{
effect = (int)(from.Skills[SkillName.Discordance].Value / -5.0);
scalar = effect * 0.01;
mods.Add( new StatMod( StatType.Str, "DiscordanceStr", (int)(targ.RawStr * scalar), TimeSpan.Zero ) );
mods.Add( new StatMod( StatType.Int, "DiscordanceInt", (int)(targ.RawInt * scalar), TimeSpan.Zero ) );
mods.Add( new StatMod( StatType.Dex, "DiscordanceDex", (int)(targ.RawDex * scalar), TimeSpan.Zero ) );
mods.Add(new StatMod(StatType.Str, "DiscordanceStr", (int)(targ.RawStr * scalar),
TimeSpan.Zero));
mods.Add(new StatMod(StatType.Int, "DiscordanceInt", (int)(targ.RawInt * scalar),
TimeSpan.Zero));
mods.Add(new StatMod(StatType.Dex, "DiscordanceDex", (int)(targ.RawDex * scalar),
TimeSpan.Zero));
for ( int i = 0; i < targ.Skills.Length; ++i )
{
if ( targ.Skills[i].Value > 0 )
mods.Add( new DefaultSkillMod( (SkillName)i, true, targ.Skills[i].Value * scalar ) );
}
}
for (int i = 0; i < targ.Skills.Length; ++i)
if (targ.Skills[i].Value > 0)
mods.Add(new DefaultSkillMod((SkillName)i, true, targ.Skills[i].Value * scalar));
}
DiscordanceInfo info = new DiscordanceInfo( from, targ, Math.Abs( effect ), mods );
info.m_Timer = Timer.DelayCall<DiscordanceInfo>( TimeSpan.Zero, TimeSpan.FromSeconds( 1.25 ), ProcessDiscordance, info );
DiscordanceInfo info = new DiscordanceInfo(from, targ, Math.Abs(effect), mods);
info.m_Timer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromSeconds(1.25), ProcessDiscordance,
info);
m_Table[targ] = info;
}
else
{
from.SendLocalizedMessage( 1049540 );// You fail to disrupt your target
m_Instrument.PlayInstrumentBadly( from );
m_Instrument.ConsumeUse( from );
}
m_Table[targ] = info;
}
else
{
from.SendLocalizedMessage(1049540); // You fail to disrupt your target
m_Instrument.PlayInstrumentBadly(from);
m_Instrument.ConsumeUse(from);
}
from.NextSkillTime = Core.TickCount + 12000;
}
else
{
m_Instrument.PlayInstrumentBadly( from );
}
}
else
{
from.SendLocalizedMessage( 1049535 ); // A song of discord would have no effect on that.
}
}
}
}
from.NextSkillTime = Core.TickCount + 12000;
}
else
{
m_Instrument.PlayInstrumentBadly(from);
}
}
else
{
from.SendLocalizedMessage(1049535); // A song of discord would have no effect on that.
}
}
}
}
}

View file

@ -5,84 +5,91 @@ using Server.Targeting;
namespace Server.SkillHandlers
{
public class EvalInt
{
public static void Initialize()
{
SkillInfo.Table[16].Callback = OnUse;
}
public class EvalInt
{
public static void Initialize()
{
SkillInfo.Table[16].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
m.Target = new InternalTarget();
public static TimeSpan OnUse(Mobile m)
{
m.Target = new InternalTarget();
m.SendLocalizedMessage( 500906 ); // What do you wish to evaluate?
m.SendLocalizedMessage(500906); // What do you wish to evaluate?
return TimeSpan.FromSeconds( 1.0 );
}
return TimeSpan.FromSeconds(1.0);
}
private class InternalTarget : Target
{
public InternalTarget() : base ( 8, false, TargetFlags.None )
{
}
private class InternalTarget : Target
{
public InternalTarget() : base(8, false, TargetFlags.None)
{
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( from == targeted )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500910 ); // Hmm, that person looks really silly.
}
else if ( targeted is TownCrier )
{
((TownCrier)targeted).PrivateOverheadMessage( MessageType.Regular, 0x3B2, 500907, from.NetState ); // He looks smart enough to remember the news. Ask him about it.
}
else if ( targeted is BaseVendor && ((BaseVendor)targeted).IsInvulnerable )
{
((BaseVendor)targeted).PrivateOverheadMessage( MessageType.Regular, 0x3B2, 500909, from.NetState ); // That person could probably calculate the cost of what you buy from them.
}
else if ( targeted is Mobile )
{
Mobile targ = (Mobile)targeted;
protected override void OnTarget(Mobile from, object targeted)
{
if (from == targeted)
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 500910); // Hmm, that person looks really silly.
}
else if (targeted is TownCrier)
{
((TownCrier)targeted).PrivateOverheadMessage(MessageType.Regular, 0x3B2, 500907,
from.NetState); // He looks smart enough to remember the news. Ask him about it.
}
else if (targeted is BaseVendor && ((BaseVendor)targeted).IsInvulnerable)
{
((BaseVendor)targeted).PrivateOverheadMessage(MessageType.Regular, 0x3B2, 500909,
from.NetState); // That person could probably calculate the cost of what you buy from them.
}
else if (targeted is Mobile)
{
Mobile targ = (Mobile)targeted;
int marginOfError = Math.Max( 0, 20 - (int)(from.Skills[SkillName.EvalInt].Value / 5) );
int marginOfError = Math.Max(0, 20 - (int)(from.Skills[SkillName.EvalInt].Value / 5));
int intel = targ.Int + Utility.RandomMinMax( -marginOfError, +marginOfError );
int mana = ((targ.Mana * 100) / Math.Max( targ.ManaMax, 1 )) + Utility.RandomMinMax( -marginOfError, +marginOfError );
int intel = targ.Int + Utility.RandomMinMax(-marginOfError, +marginOfError);
int mana = targ.Mana * 100 / Math.Max(targ.ManaMax, 1) +
Utility.RandomMinMax(-marginOfError, +marginOfError);
int intMod = intel / 10;
int mnMod = mana / 10;
int intMod = intel / 10;
int mnMod = mana / 10;
if ( intMod > 10 ) intMod = 10;
else if ( intMod < 0 ) intMod = 0;
if (intMod > 10) intMod = 10;
else if (intMod < 0) intMod = 0;
if ( mnMod > 10 ) mnMod = 10;
else if ( mnMod < 0 ) mnMod = 0;
if (mnMod > 10) mnMod = 10;
else if (mnMod < 0) mnMod = 0;
int body;
int body;
if ( targ.Body.IsHuman )
body = targ.Female ? 11 : 0;
else
body = 22;
if (targ.Body.IsHuman)
body = targ.Female ? 11 : 0;
else
body = 22;
if ( from.CheckTargetSkill( SkillName.EvalInt, targ, 0.0, 120.0 ) )
{
targ.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1038169 + intMod + body, from.NetState ); // He/She/It looks [slighly less intelligent than a rock.] [Of Average intellect] [etc...]
if (from.CheckTargetSkill(SkillName.EvalInt, targ, 0.0, 120.0))
{
targ.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1038169 + intMod + body,
from.NetState); // He/She/It looks [slighly less intelligent than a rock.] [Of Average intellect] [etc...]
if ( from.Skills[SkillName.EvalInt].Base >= 76.0 )
targ.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1038202 + mnMod, from.NetState ); // That being is at [10,20,...] percent mental strength.
}
else
{
targ.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1038166 + (body / 11), from.NetState ); // You cannot judge his/her/its mental abilities.
}
}
else
{
(targeted as Item)?.SendLocalizedMessageTo( from, 500908, "" ); // It looks smarter than a rock, but dumber than a piece of wood.
}
}
}
}
}
if (from.Skills[SkillName.EvalInt].Base >= 76.0)
targ.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1038202 + mnMod,
from.NetState); // That being is at [10,20,...] percent mental strength.
}
else
{
targ.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1038166 + body / 11,
from.NetState); // You cannot judge his/her/its mental abilities.
}
}
else
{
(targeted as Item)?.SendLocalizedMessageTo(from, 500908,
""); // It looks smarter than a rock, but dumber than a piece of wood.
}
}
}
}
}

View file

@ -1,95 +1,98 @@
using System;
using System.Text;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
using Server.Items;
namespace Server.SkillHandlers
{
public class ForensicEvaluation
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Forensics].Callback = OnUse;
}
public class ForensicEvaluation
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Forensics].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
m.Target = new ForensicTarget();
m.RevealingAction();
public static TimeSpan OnUse(Mobile m)
{
m.Target = new ForensicTarget();
m.RevealingAction();
m.SendLocalizedMessage( 501000 ); // Show me the crime.
m.SendLocalizedMessage(501000); // Show me the crime.
return TimeSpan.FromSeconds( 1.0 );
}
return TimeSpan.FromSeconds(1.0);
}
public class ForensicTarget : Target
{
public ForensicTarget() : base( 10, false, TargetFlags.None )
{
}
public class ForensicTarget : Target
{
public ForensicTarget() : base(10, false, TargetFlags.None)
{
}
protected override void OnTarget( Mobile from, object target )
{
if ( target is Mobile )
{
if ( from.CheckTargetSkill( SkillName.Forensics, target, 40.0, 100.0 ) )
{
if ( target is PlayerMobile && ((PlayerMobile)target).NpcGuild == NpcGuild.ThievesGuild )
from.SendLocalizedMessage( 501004 );//That individual is a thief!
else
from.SendLocalizedMessage( 501003 );//You notice nothing unusual.
}
else
{
from.SendLocalizedMessage( 501001 );//You cannot determain anything useful.
}
}
else if ( target is Corpse )
{
if ( from.CheckTargetSkill( SkillName.Forensics, target, 0.0, 100.0 ) )
{
Corpse c = (Corpse)target;
protected override void OnTarget(Mobile from, object target)
{
if (target is Mobile)
{
if (from.CheckTargetSkill(SkillName.Forensics, target, 40.0, 100.0))
{
if (target is PlayerMobile && ((PlayerMobile)target).NpcGuild == NpcGuild.ThievesGuild)
from.SendLocalizedMessage(501004); //That individual is a thief!
else
from.SendLocalizedMessage(501003); //You notice nothing unusual.
}
else
{
from.SendLocalizedMessage(501001); //You cannot determain anything useful.
}
}
else if (target is Corpse)
{
if (from.CheckTargetSkill(SkillName.Forensics, target, 0.0, 100.0))
{
Corpse c = (Corpse)target;
if ( c.m_Forensicist != null )
from.SendLocalizedMessage( 1042750, c.m_Forensicist ) ; // The forensicist ~1_NAME~ has already discovered that:
else
c.m_Forensicist = from.Name;
if (c.m_Forensicist != null)
from.SendLocalizedMessage(1042750,
c.m_Forensicist); // The forensicist ~1_NAME~ has already discovered that:
else
c.m_Forensicist = from.Name;
if ( ((Body)c.Amount).IsHuman )
from.SendLocalizedMessage( 1042751, ( c.Killer == null ? "no one" : c.Killer.Name ) );//This person was killed by ~1_KILLER_NAME~
if (((Body)c.Amount).IsHuman)
from.SendLocalizedMessage(1042751,
c.Killer == null ? "no one" : c.Killer.Name); //This person was killed by ~1_KILLER_NAME~
if ( c.Looters.Count > 0 )
{
StringBuilder sb = new StringBuilder();
for (int i=0;i<c.Looters.Count;i++)
{
if ( i>0 )
sb.Append( ", " );
sb.Append( ((Mobile)c.Looters[i]).Name );
}
if (c.Looters.Count > 0)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < c.Looters.Count; i++)
{
if (i > 0)
sb.Append(", ");
sb.Append(c.Looters[i].Name);
}
from.SendLocalizedMessage( 1042752, sb.ToString() );//This body has been distrubed by ~1_PLAYER_NAMES~
}
else
{
from.SendLocalizedMessage( 501002 );//The corpse has not be desecrated.
}
}
else
{
from.SendLocalizedMessage( 501001 );//You cannot determain anything useful.
}
}
else if ( target is ILockpickable )
{
ILockpickable p = (ILockpickable)target;
if ( p.Picker != null )
from.SendLocalizedMessage( 1042749, p.Picker.Name );//This lock was opened by ~1_PICKER_NAME~
else
from.SendLocalizedMessage( 501003 );//You notice nothing unusual.
}
}
}
}
}
from.SendLocalizedMessage(1042752,
sb.ToString()); //This body has been distrubed by ~1_PLAYER_NAMES~
}
else
{
from.SendLocalizedMessage(501002); //The corpse has not be desecrated.
}
}
else
{
from.SendLocalizedMessage(501001); //You cannot determain anything useful.
}
}
else if (target is ILockpickable)
{
ILockpickable p = (ILockpickable)target;
if (p.Picker != null)
from.SendLocalizedMessage(1042749, p.Picker.Name); //This lock was opened by ~1_PICKER_NAME~
else
from.SendLocalizedMessage(501003); //You notice nothing unusual.
}
}
}
}
}

View file

@ -1,104 +1,100 @@
using System;
using Server.Network;
using Server.Multis;
using Server.Network;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class Hiding
{
public static bool CombatOverride { get; set; }
public class Hiding
{
public static bool CombatOverride{ get; set; }
public static void Initialize()
{
SkillInfo.Table[21].Callback = OnUse;
}
public static void Initialize()
{
SkillInfo.Table[21].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
if ( m.Spell != null )
{
m.SendLocalizedMessage( 501238 ); // You are busy doing something else and cannot hide.
return TimeSpan.FromSeconds( 1.0 );
}
public static TimeSpan OnUse(Mobile m)
{
if (m.Spell != null)
{
m.SendLocalizedMessage(501238); // You are busy doing something else and cannot hide.
return TimeSpan.FromSeconds(1.0);
}
if ( Core.ML && m.Target != null )
{
Targeting.Target.Cancel( m );
}
if (Core.ML && m.Target != null) Target.Cancel(m);
double bonus = 0.0;
double bonus = 0.0;
BaseHouse house = BaseHouse.FindHouseAt( m );
BaseHouse house = BaseHouse.FindHouseAt(m);
if ( house != null && house.IsFriend( m ) )
{
bonus = 100.0;
}
else if ( !Core.AOS )
{
if ( house == null )
house = BaseHouse.FindHouseAt( new Point3D( m.X - 1, m.Y, 127 ), m.Map, 16 );
if (house != null && house.IsFriend(m))
{
bonus = 100.0;
}
else if (!Core.AOS)
{
if (house == null)
house = BaseHouse.FindHouseAt(new Point3D(m.X - 1, m.Y, 127), m.Map, 16);
if ( house == null )
house = BaseHouse.FindHouseAt( new Point3D( m.X + 1, m.Y, 127 ), m.Map, 16 );
if (house == null)
house = BaseHouse.FindHouseAt(new Point3D(m.X + 1, m.Y, 127), m.Map, 16);
if ( house == null )
house = BaseHouse.FindHouseAt( new Point3D( m.X, m.Y - 1, 127 ), m.Map, 16 );
if (house == null)
house = BaseHouse.FindHouseAt(new Point3D(m.X, m.Y - 1, 127), m.Map, 16);
if ( house == null )
house = BaseHouse.FindHouseAt( new Point3D( m.X, m.Y + 1, 127 ), m.Map, 16 );
if (house == null)
house = BaseHouse.FindHouseAt(new Point3D(m.X, m.Y + 1, 127), m.Map, 16);
if ( house != null )
bonus = 50.0;
}
if (house != null)
bonus = 50.0;
}
//int range = 18 - (int)(m.Skills[SkillName.Hiding].Value / 10);
int range = Math.Min( (int)((100 - m.Skills[SkillName.Hiding].Value)/2) + 8, 18 ); //Cap of 18 not OSI-exact, intentional difference
//int range = 18 - (int)(m.Skills[SkillName.Hiding].Value / 10);
int range = Math.Min((int)((100 - m.Skills[SkillName.Hiding].Value) / 2) + 8,
18); //Cap of 18 not OSI-exact, intentional difference
bool badCombat = ( !CombatOverride && m.Combatant != null && m.InRange( m.Combatant.Location, range ) && m.Combatant.InLOS( m ) );
bool ok = ( !badCombat /*&& m.CheckSkill( SkillName.Hiding, 0.0 - bonus, 100.0 - bonus )*/ );
bool badCombat = !CombatOverride && m.Combatant != null && m.InRange(m.Combatant.Location, range) &&
m.Combatant.InLOS(m);
bool ok = !badCombat;
if ( ok )
{
if ( !CombatOverride )
{
foreach ( Mobile check in m.GetMobilesInRange( range ) )
{
if ( check.InLOS( m ) && check.Combatant == m )
{
badCombat = true;
ok = false;
break;
}
}
}
if (ok)
{
if (!CombatOverride)
foreach (Mobile check in m.GetMobilesInRange(range))
if (check.InLOS(m) && check.Combatant == m)
{
badCombat = true;
ok = false;
break;
}
ok = ( !badCombat && m.CheckSkill( SkillName.Hiding, 0.0 - bonus, 100.0 - bonus ) );
}
ok = !badCombat && m.CheckSkill(SkillName.Hiding, 0.0 - bonus, 100.0 - bonus);
}
if ( badCombat )
{
m.RevealingAction();
if (badCombat)
{
m.RevealingAction();
m.LocalOverheadMessage( MessageType.Regular, 0x22, 501237 ); // You can't seem to hide right now.
m.LocalOverheadMessage(MessageType.Regular, 0x22, 501237); // You can't seem to hide right now.
return TimeSpan.FromSeconds( 1.0 );
}
return TimeSpan.FromSeconds(1.0);
}
if ( ok )
{
m.Hidden = true;
m.Warmode = false;
m.LocalOverheadMessage( MessageType.Regular, 0x1F4, 501240 ); // You have hidden yourself well.
}
else
{
m.RevealingAction();
if (ok)
{
m.Hidden = true;
m.Warmode = false;
m.LocalOverheadMessage(MessageType.Regular, 0x1F4, 501240); // You have hidden yourself well.
}
else
{
m.RevealingAction();
m.LocalOverheadMessage( MessageType.Regular, 0x22, 501241 ); // You can't seem to hide here.
}
m.LocalOverheadMessage(MessageType.Regular, 0x22, 501241); // You can't seem to hide here.
}
return TimeSpan.FromSeconds( 10.0 );
}
}
return TimeSpan.FromSeconds(10.0);
}
}
}

View file

@ -1,162 +1,176 @@
using System;
using System.Collections.Generic;
using Server.Targeting;
using Server.Items;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class Inscribe
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Inscribe].Callback = OnUse;
}
public class Inscribe
{
private static Dictionary<BaseBook, Mobile> m_UseTable = new Dictionary<BaseBook, Mobile>();
public static TimeSpan OnUse( Mobile m )
{
Target target = new InternalTargetSrc();
m.Target = target;
m.SendLocalizedMessage( 1046295 ); // Target the book you wish to copy.
target.BeginTimeout( m, TimeSpan.FromMinutes( 1.0 ) );
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Inscribe].Callback = OnUse;
}
return TimeSpan.FromSeconds( 1.0 );
}
public static TimeSpan OnUse(Mobile m)
{
Target target = new InternalTargetSrc();
m.Target = target;
m.SendLocalizedMessage(1046295); // Target the book you wish to copy.
target.BeginTimeout(m, TimeSpan.FromMinutes(1.0));
private static Dictionary<BaseBook, Mobile> m_UseTable = new Dictionary<BaseBook, Mobile>();
return TimeSpan.FromSeconds(1.0);
}
private static void SetUser( BaseBook book, Mobile mob )
{
m_UseTable[book] = mob;
}
private static void SetUser(BaseBook book, Mobile mob)
{
m_UseTable[book] = mob;
}
private static void CancelUser( BaseBook book )
{
m_UseTable.Remove( book );
}
private static void CancelUser(BaseBook book)
{
m_UseTable.Remove(book);
}
public static Mobile GetUser( BaseBook book )
{
m_UseTable.TryGetValue( book, out Mobile m );
return m;
}
public static Mobile GetUser(BaseBook book)
{
m_UseTable.TryGetValue(book, out Mobile m);
return m;
}
public static bool IsEmpty( BaseBook book )
{
foreach ( BookPageInfo page in book.Pages )
{
foreach ( string line in page.Lines )
{
if ( line.Trim().Length != 0 )
return false;
}
}
return true;
}
public static bool IsEmpty(BaseBook book)
{
foreach (BookPageInfo page in book.Pages)
foreach (string line in page.Lines)
if (line.Trim().Length != 0)
return false;
return true;
}
public static void Copy( BaseBook bookSrc, BaseBook bookDst )
{
bookDst.Title = bookSrc.Title;
bookDst.Author = bookSrc.Author;
public static void Copy(BaseBook bookSrc, BaseBook bookDst)
{
bookDst.Title = bookSrc.Title;
bookDst.Author = bookSrc.Author;
BookPageInfo[] pagesSrc = bookSrc.Pages;
BookPageInfo[] pagesDst = bookDst.Pages;
for ( int i = 0; i < pagesSrc.Length && i < pagesDst.Length; i++ )
{
BookPageInfo pageSrc = pagesSrc[i];
BookPageInfo pageDst = pagesDst[i];
BookPageInfo[] pagesSrc = bookSrc.Pages;
BookPageInfo[] pagesDst = bookDst.Pages;
for (int i = 0; i < pagesSrc.Length && i < pagesDst.Length; i++)
{
BookPageInfo pageSrc = pagesSrc[i];
BookPageInfo pageDst = pagesDst[i];
int length = pageSrc.Lines.Length;
pageDst.Lines = new string[length];
int length = pageSrc.Lines.Length;
pageDst.Lines = new string[length];
for ( int j = 0; j < length; j++ )
pageDst.Lines[j] = pageSrc.Lines[j];
}
}
for (int j = 0; j < length; j++)
pageDst.Lines[j] = pageSrc.Lines[j];
}
}
private class InternalTargetSrc : Target
{
public InternalTargetSrc() : base ( 3, false, TargetFlags.None )
{
}
private class InternalTargetSrc : Target
{
public InternalTargetSrc() : base(3, false, TargetFlags.None)
{
}
protected override void OnTarget( Mobile from, object targeted )
{
BaseBook book = targeted as BaseBook;
if ( book == null )
from.SendLocalizedMessage( 1046296 ); // That is not a book
else if ( IsEmpty( book ) )
from.SendLocalizedMessage( 501611 ); // Can't copy an empty book.
else if ( GetUser( book ) != null )
from.SendLocalizedMessage( 501621 ); // Someone else is inscribing that item.
else
{
Target target = new InternalTargetDst( book );
from.Target = target;
from.SendLocalizedMessage( 501612 ); // Select a book to copy this to.
target.BeginTimeout( from, TimeSpan.FromMinutes( 1.0 ) );
SetUser( book, from );
}
}
protected override void OnTarget(Mobile from, object targeted)
{
BaseBook book = targeted as BaseBook;
if (book == null)
{
from.SendLocalizedMessage(1046296); // That is not a book
}
else if (IsEmpty(book))
{
from.SendLocalizedMessage(501611); // Can't copy an empty book.
}
else if (GetUser(book) != null)
{
from.SendLocalizedMessage(501621); // Someone else is inscribing that item.
}
else
{
Target target = new InternalTargetDst(book);
from.Target = target;
from.SendLocalizedMessage(501612); // Select a book to copy this to.
target.BeginTimeout(from, TimeSpan.FromMinutes(1.0));
SetUser(book, from);
}
}
protected override void OnTargetCancel( Mobile from, TargetCancelType cancelType )
{
if ( cancelType == TargetCancelType.Timeout )
from.SendLocalizedMessage( 501619 ); // You have waited too long to make your inscribe selection, your inscription attempt has timed out.
}
}
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{
if (cancelType == TargetCancelType.Timeout)
from.SendLocalizedMessage(
501619); // You have waited too long to make your inscribe selection, your inscription attempt has timed out.
}
}
private class InternalTargetDst : Target
{
private BaseBook m_BookSrc;
private class InternalTargetDst : Target
{
private BaseBook m_BookSrc;
public InternalTargetDst( BaseBook bookSrc ) : base ( 3, false, TargetFlags.None )
{
m_BookSrc = bookSrc;
}
public InternalTargetDst(BaseBook bookSrc) : base(3, false, TargetFlags.None)
{
m_BookSrc = bookSrc;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_BookSrc.Deleted )
return;
protected override void OnTarget(Mobile from, object targeted)
{
if (m_BookSrc.Deleted)
return;
BaseBook bookDst = targeted as BaseBook;
BaseBook bookDst = targeted as BaseBook;
if ( bookDst == null )
from.SendLocalizedMessage( 1046296 ); // That is not a book
else if ( IsEmpty( m_BookSrc ) )
from.SendLocalizedMessage( 501611 ); // Can't copy an empty book.
else if ( bookDst == m_BookSrc )
from.SendLocalizedMessage( 501616 ); // Cannot copy a book onto itself.
else if ( !bookDst.Writable )
from.SendLocalizedMessage( 501614 ); // Cannot write into that book.
else if ( GetUser( bookDst ) != null )
from.SendLocalizedMessage( 501621 ); // Someone else is inscribing that item.
else
{
if ( from.CheckTargetSkill( SkillName.Inscribe, bookDst, 0, 50 ) )
{
Copy( m_BookSrc, bookDst );
if (bookDst == null)
{
from.SendLocalizedMessage(1046296); // That is not a book
}
else if (IsEmpty(m_BookSrc))
{
from.SendLocalizedMessage(501611); // Can't copy an empty book.
}
else if (bookDst == m_BookSrc)
{
from.SendLocalizedMessage(501616); // Cannot copy a book onto itself.
}
else if (!bookDst.Writable)
{
from.SendLocalizedMessage(501614); // Cannot write into that book.
}
else if (GetUser(bookDst) != null)
{
from.SendLocalizedMessage(501621); // Someone else is inscribing that item.
}
else
{
if (from.CheckTargetSkill(SkillName.Inscribe, bookDst, 0, 50))
{
Copy(m_BookSrc, bookDst);
from.SendLocalizedMessage( 501618 ); // You make a copy of the book.
from.PlaySound( 0x249 );
}
else
{
from.SendLocalizedMessage( 501617 ); // You fail to make a copy of the book.
}
}
}
from.SendLocalizedMessage(501618); // You make a copy of the book.
from.PlaySound(0x249);
}
else
{
from.SendLocalizedMessage(501617); // You fail to make a copy of the book.
}
}
}
protected override void OnTargetCancel( Mobile from, TargetCancelType cancelType )
{
if ( cancelType == TargetCancelType.Timeout )
from.SendLocalizedMessage( 501619 ); // You have waited too long to make your inscribe selection, your inscription attempt has timed out.
}
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{
if (cancelType == TargetCancelType.Timeout)
from.SendLocalizedMessage(
501619); // You have waited too long to make your inscribe selection, your inscription attempt has timed out.
}
protected override void OnTargetFinish( Mobile from )
{
CancelUser( m_BookSrc );
}
}
}
}
protected override void OnTargetFinish(Mobile from)
{
CancelUser(m_BookSrc);
}
}
}
}

View file

@ -1,60 +1,60 @@
using System;
using Server.Targeting;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Items
{
public class ItemIdentification
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.ItemID].Callback = OnUse;
}
public class ItemIdentification
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.ItemID].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile from )
{
from.SendLocalizedMessage( 500343 ); // What do you wish to appraise and identify?
from.Target = new InternalTarget();
public static TimeSpan OnUse(Mobile from)
{
from.SendLocalizedMessage(500343); // What do you wish to appraise and identify?
from.Target = new InternalTarget();
return TimeSpan.FromSeconds( 1.0 );
}
return TimeSpan.FromSeconds(1.0);
}
[PlayerVendorTarget]
private class InternalTarget : Target
{
public InternalTarget() : base ( 8, false, TargetFlags.None )
{
AllowNonlocal = true;
}
[PlayerVendorTarget]
private class InternalTarget : Target
{
public InternalTarget() : base(8, false, TargetFlags.None)
{
AllowNonlocal = true;
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is Item )
{
if ( from.CheckTargetSkill( SkillName.ItemID, o, 0, 100 ) )
{
if ( o is BaseWeapon )
((BaseWeapon)o).Identified = true;
else if ( o is BaseArmor )
((BaseArmor)o).Identified = true;
protected override void OnTarget(Mobile from, object o)
{
if (o is Item)
{
if (from.CheckTargetSkill(SkillName.ItemID, o, 0, 100))
{
if (o is BaseWeapon)
((BaseWeapon)o).Identified = true;
else if (o is BaseArmor)
((BaseArmor)o).Identified = true;
if ( !Core.AOS )
((Item)o).OnSingleClick( from );
}
else
{
from.SendLocalizedMessage( 500353 ); // You are not certain...
}
}
else if ( o is Mobile )
{
((Mobile)o).OnSingleClick( from );
}
else
{
from.SendLocalizedMessage( 500353 ); // You are not certain...
}
}
}
}
if (!Core.AOS)
((Item)o).OnSingleClick(from);
}
else
{
from.SendLocalizedMessage(500353); // You are not certain...
}
}
else if (o is Mobile)
{
((Mobile)o).OnSingleClick(from);
}
else
{
from.SendLocalizedMessage(500353); // You are not certain...
}
}
}
}
}

View file

@ -1,99 +1,103 @@
using System;
using Server.Items;
using Server.Misc;
namespace Server.SkillHandlers
{
class Meditation
{
public static void Initialize()
{
SkillInfo.Table[46].Callback = OnUse;
}
internal class Meditation
{
public static void Initialize()
{
SkillInfo.Table[46].Callback = OnUse;
}
public static bool CheckOkayHolding( Item item )
{
if ( item == null )
return true;
public static bool CheckOkayHolding(Item item)
{
if (item == null)
return true;
if ( item is Spellbook || item is Runebook )
return true;
if (item is Spellbook || item is Runebook)
return true;
if ( Core.AOS && item is BaseWeapon && ((BaseWeapon)item).Attributes.SpellChanneling != 0 )
return true;
if (Core.AOS && item is BaseWeapon && ((BaseWeapon)item).Attributes.SpellChanneling != 0)
return true;
if ( Core.AOS && item is BaseArmor && ((BaseArmor)item).Attributes.SpellChanneling != 0 )
return true;
if (Core.AOS && item is BaseArmor && ((BaseArmor)item).Attributes.SpellChanneling != 0)
return true;
return false;
}
return false;
}
public static TimeSpan OnUse( Mobile m )
{
m.RevealingAction();
public static TimeSpan OnUse(Mobile m)
{
m.RevealingAction();
if ( m.Target != null )
{
m.SendLocalizedMessage( 501845 ); // You are busy doing something else and cannot focus.
if (m.Target != null)
{
m.SendLocalizedMessage(501845); // You are busy doing something else and cannot focus.
return TimeSpan.FromSeconds( 5.0 );
}
return TimeSpan.FromSeconds(5.0);
}
if ( !Core.AOS && m.Hits < (m.HitsMax / 10) ) // Less than 10% health
{
m.SendLocalizedMessage( 501849 ); // The mind is strong but the body is weak.
if (!Core.AOS && m.Hits < m.HitsMax / 10) // Less than 10% health
{
m.SendLocalizedMessage(501849); // The mind is strong but the body is weak.
return TimeSpan.FromSeconds( 5.0 );
}
if ( m.Mana >= m.ManaMax )
{
m.SendLocalizedMessage( 501846 ); // You are at peace.
return TimeSpan.FromSeconds(5.0);
}
return TimeSpan.FromSeconds( Core.AOS ? 10.0 : 5.0 );
}
if ( Core.AOS && Misc.RegenRates.GetArmorOffset( m ) > 0 )
{
m.SendLocalizedMessage( 500135 ); // Regenerative forces cannot penetrate your armor!
if (m.Mana >= m.ManaMax)
{
m.SendLocalizedMessage(501846); // You are at peace.
return TimeSpan.FromSeconds( 10.0 );
}
Item oneHanded = m.FindItemOnLayer( Layer.OneHanded );
Item twoHanded = m.FindItemOnLayer( Layer.TwoHanded );
return TimeSpan.FromSeconds(Core.AOS ? 10.0 : 5.0);
}
if ( Core.AOS && m.Player )
{
if ( !CheckOkayHolding( oneHanded ) )
m.AddToBackpack( oneHanded );
if (Core.AOS && RegenRates.GetArmorOffset(m) > 0)
{
m.SendLocalizedMessage(500135); // Regenerative forces cannot penetrate your armor!
if ( !CheckOkayHolding( twoHanded ) )
m.AddToBackpack( twoHanded );
}
else if ( !CheckOkayHolding( oneHanded ) || !CheckOkayHolding( twoHanded ) )
{
m.SendLocalizedMessage( 502626 ); // Your hands must be free to cast spells or meditate.
return TimeSpan.FromSeconds(10.0);
}
return TimeSpan.FromSeconds( 2.5 );
}
Item oneHanded = m.FindItemOnLayer(Layer.OneHanded);
Item twoHanded = m.FindItemOnLayer(Layer.TwoHanded);
double skillVal = m.Skills[SkillName.Meditation].Value;
double chance = (50.0 + (( skillVal - ( m.ManaMax - m.Mana ) ) * 2)) / 100;
if (Core.AOS && m.Player)
{
if (!CheckOkayHolding(oneHanded))
m.AddToBackpack(oneHanded);
if ( chance > Utility.RandomDouble() )
{
m.CheckSkill( SkillName.Meditation, 0.0, 100.0 );
if (!CheckOkayHolding(twoHanded))
m.AddToBackpack(twoHanded);
}
else if (!CheckOkayHolding(oneHanded) || !CheckOkayHolding(twoHanded))
{
m.SendLocalizedMessage(502626); // Your hands must be free to cast spells or meditate.
m.SendLocalizedMessage( 501851 ); // You enter a meditative trance.
m.Meditating = true;
BuffInfo.AddBuff( m, new BuffInfo( BuffIcon.ActiveMeditation, 1075657 ) );
return TimeSpan.FromSeconds(2.5);
}
if ( m.Player || m.Body.IsHuman )
m.PlaySound( 0xF9 );
}
else
{
m.SendLocalizedMessage( 501850 ); // You cannot focus your concentration.
}
double skillVal = m.Skills[SkillName.Meditation].Value;
double chance = (50.0 + (skillVal - (m.ManaMax - m.Mana)) * 2) / 100;
return TimeSpan.FromSeconds( 10.0 );
}
}
}
if (chance > Utility.RandomDouble())
{
m.CheckSkill(SkillName.Meditation, 0.0, 100.0);
m.SendLocalizedMessage(501851); // You enter a meditative trance.
m.Meditating = true;
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.ActiveMeditation, 1075657));
if (m.Player || m.Body.IsHuman)
m.PlaySound(0xF9);
}
else
{
m.SendLocalizedMessage(501850); // You cannot focus your concentration.
}
return TimeSpan.FromSeconds(10.0);
}
}
}

View file

@ -1,206 +1,214 @@
using System;
using Server.Targeting;
using Server.Mobiles;
using Server.Engines.ConPVP;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class Peacemaking
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Peacemaking].Callback = OnUse;
}
public class Peacemaking
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Peacemaking].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
m.RevealingAction();
public static TimeSpan OnUse(Mobile m)
{
m.RevealingAction();
BaseInstrument.PickInstrument( m, OnPickedInstrument );
BaseInstrument.PickInstrument(m, OnPickedInstrument);
return TimeSpan.FromSeconds( 1.0 ); // Cannot use another skill for 1 second
}
return TimeSpan.FromSeconds(1.0); // Cannot use another skill for 1 second
}
public static void OnPickedInstrument( Mobile from, BaseInstrument instrument )
{
from.RevealingAction();
from.SendLocalizedMessage( 1049525 ); // Whom do you wish to calm?
from.Target = new InternalTarget( from, instrument );
from.NextSkillTime = Core.TickCount + 21600000;
}
public static void OnPickedInstrument(Mobile from, BaseInstrument instrument)
{
from.RevealingAction();
from.SendLocalizedMessage(1049525); // Whom do you wish to calm?
from.Target = new InternalTarget(from, instrument);
from.NextSkillTime = Core.TickCount + 21600000;
}
private class InternalTarget : Target
{
private BaseInstrument m_Instrument;
private bool m_SetSkillTime = true;
private class InternalTarget : Target
{
private BaseInstrument m_Instrument;
private bool m_SetSkillTime = true;
public InternalTarget( Mobile from, BaseInstrument instrument ) : base( BaseInstrument.GetBardRange( from, SkillName.Peacemaking ), false, TargetFlags.None )
{
m_Instrument = instrument;
}
public InternalTarget(Mobile from, BaseInstrument instrument) : base(
BaseInstrument.GetBardRange(from, SkillName.Peacemaking), false, TargetFlags.None)
{
m_Instrument = instrument;
}
protected override void OnTargetFinish( Mobile from )
{
if ( m_SetSkillTime )
from.NextSkillTime = Core.TickCount;
}
protected override void OnTargetFinish(Mobile from)
{
if (m_SetSkillTime)
from.NextSkillTime = Core.TickCount;
}
protected override void OnTarget( Mobile from, object targeted )
{
from.RevealingAction();
protected override void OnTarget(Mobile from, object targeted)
{
from.RevealingAction();
if ( !(targeted is Mobile) )
{
from.SendLocalizedMessage( 1049528 ); // You cannot calm that!
}
else if ( from.Region.IsPartOf( typeof( Engines.ConPVP.SafeZone ) ) )
{
from.SendMessage( "You may not peacemake in this area." );
}
else if ( ((Mobile)targeted).Region.IsPartOf( typeof( Engines.ConPVP.SafeZone ) ) )
{
from.SendMessage( "You may not peacemake there." );
}
else if ( !m_Instrument.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1062488 ); // The instrument you are trying to play is no longer in your backpack!
}
else
{
m_SetSkillTime = false;
from.NextSkillTime = Core.TickCount + 10000;
if (!(targeted is Mobile))
{
from.SendLocalizedMessage(1049528); // You cannot calm that!
}
else if (from.Region.IsPartOf(typeof(SafeZone)))
{
from.SendMessage("You may not peacemake in this area.");
}
else if (((Mobile)targeted).Region.IsPartOf(typeof(SafeZone)))
{
from.SendMessage("You may not peacemake there.");
}
else if (!m_Instrument.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(
1062488); // The instrument you are trying to play is no longer in your backpack!
}
else
{
m_SetSkillTime = false;
from.NextSkillTime = Core.TickCount + 10000;
if ( targeted == from )
{
// Standard mode : reset combatants for everyone in the area
if (targeted == from)
{
// Standard mode : reset combatants for everyone in the area
if ( !BaseInstrument.CheckMusicianship( from ) )
{
from.SendLocalizedMessage( 500612 ); // You play poorly, and there is no effect.
m_Instrument.PlayInstrumentBadly( from );
m_Instrument.ConsumeUse( from );
}
else if ( !from.CheckSkill( SkillName.Peacemaking, 0.0, 120.0 ) )
{
from.SendLocalizedMessage( 500613 ); // You attempt to calm everyone, but fail.
m_Instrument.PlayInstrumentBadly( from );
m_Instrument.ConsumeUse( from );
}
else
{
from.NextSkillTime = Core.TickCount + 5000;
m_Instrument.PlayInstrumentWell( from );
m_Instrument.ConsumeUse( from );
if (!BaseInstrument.CheckMusicianship(from))
{
from.SendLocalizedMessage(500612); // You play poorly, and there is no effect.
m_Instrument.PlayInstrumentBadly(from);
m_Instrument.ConsumeUse(from);
}
else if (!from.CheckSkill(SkillName.Peacemaking, 0.0, 120.0))
{
from.SendLocalizedMessage(500613); // You attempt to calm everyone, but fail.
m_Instrument.PlayInstrumentBadly(from);
m_Instrument.ConsumeUse(from);
}
else
{
from.NextSkillTime = Core.TickCount + 5000;
m_Instrument.PlayInstrumentWell(from);
m_Instrument.ConsumeUse(from);
Map map = from.Map;
Map map = from.Map;
if ( map != null )
{
int range = BaseInstrument.GetBardRange( from, SkillName.Peacemaking );
if (map != null)
{
int range = BaseInstrument.GetBardRange(from, SkillName.Peacemaking);
bool calmed = false;
bool calmed = false;
foreach ( Mobile m in from.GetMobilesInRange( range ) )
{
if ((m is BaseCreature && ((BaseCreature)m).Uncalmable) || (m is BaseCreature && ((BaseCreature)m).AreaPeaceImmune) || m == from || !from.CanBeHarmful ( m, false ))
continue;
foreach (Mobile m in from.GetMobilesInRange(range))
{
if (m is BaseCreature && ((BaseCreature)m).Uncalmable ||
m is BaseCreature && ((BaseCreature)m).AreaPeaceImmune || m == from ||
!from.CanBeHarmful(m, false))
continue;
calmed = true;
calmed = true;
m.SendLocalizedMessage( 500616 ); // You hear lovely music, and forget to continue battling!
m.Combatant = null;
m.Warmode = false;
m.SendLocalizedMessage(
500616); // You hear lovely music, and forget to continue battling!
m.Combatant = null;
m.Warmode = false;
if ( m is BaseCreature && !((BaseCreature)m).BardPacified )
((BaseCreature)m).Pacify( from, DateTime.UtcNow + TimeSpan.FromSeconds( 1.0 ) );
}
if (m is BaseCreature && !((BaseCreature)m).BardPacified)
((BaseCreature)m).Pacify(from, DateTime.UtcNow + TimeSpan.FromSeconds(1.0));
}
if ( !calmed )
from.SendLocalizedMessage( 1049648 ); // You play hypnotic music, but there is nothing in range for you to calm.
else
from.SendLocalizedMessage( 500615 ); // You play your hypnotic music, stopping the battle.
}
}
}
else
{
// Target mode : pacify a single target for a longer duration
if (!calmed)
from.SendLocalizedMessage(
1049648); // You play hypnotic music, but there is nothing in range for you to calm.
else
from.SendLocalizedMessage(500615); // You play your hypnotic music, stopping the battle.
}
}
}
else
{
// Target mode : pacify a single target for a longer duration
Mobile targ = (Mobile)targeted;
Mobile targ = (Mobile)targeted;
if ( !from.CanBeHarmful( targ, false ) )
{
from.SendLocalizedMessage( 1049528 );
m_SetSkillTime = true;
}
else if ( targ is BaseCreature && ((BaseCreature)targ).Uncalmable )
{
from.SendLocalizedMessage( 1049526 ); // You have no chance of calming that creature.
m_SetSkillTime = true;
}
else if ( targ is BaseCreature && ((BaseCreature)targ).BardPacified )
{
from.SendLocalizedMessage( 1049527 ); // That creature is already being calmed.
m_SetSkillTime = true;
}
else if ( !BaseInstrument.CheckMusicianship( from ) )
{
from.SendLocalizedMessage( 500612 ); // You play poorly, and there is no effect.
from.NextSkillTime = Core.TickCount + 5000;
m_Instrument.PlayInstrumentBadly( from );
m_Instrument.ConsumeUse( from );
}
else
{
double diff = m_Instrument.GetDifficultyFor( targ ) - 10.0;
double music = from.Skills[SkillName.Musicianship].Value;
if (!from.CanBeHarmful(targ, false))
{
from.SendLocalizedMessage(1049528);
m_SetSkillTime = true;
}
else if (targ is BaseCreature && ((BaseCreature)targ).Uncalmable)
{
from.SendLocalizedMessage(1049526); // You have no chance of calming that creature.
m_SetSkillTime = true;
}
else if (targ is BaseCreature && ((BaseCreature)targ).BardPacified)
{
from.SendLocalizedMessage(1049527); // That creature is already being calmed.
m_SetSkillTime = true;
}
else if (!BaseInstrument.CheckMusicianship(from))
{
from.SendLocalizedMessage(500612); // You play poorly, and there is no effect.
from.NextSkillTime = Core.TickCount + 5000;
m_Instrument.PlayInstrumentBadly(from);
m_Instrument.ConsumeUse(from);
}
else
{
double diff = m_Instrument.GetDifficultyFor(targ) - 10.0;
double music = from.Skills[SkillName.Musicianship].Value;
if ( music > 100.0 )
diff -= (music - 100.0) * 0.5;
if (music > 100.0)
diff -= (music - 100.0) * 0.5;
if ( !from.CheckTargetSkill( SkillName.Peacemaking, targ, diff - 25.0, diff + 25.0 ) )
{
from.SendLocalizedMessage( 1049531 ); // You attempt to calm your target, but fail.
m_Instrument.PlayInstrumentBadly( from );
m_Instrument.ConsumeUse( from );
}
else
{
m_Instrument.PlayInstrumentWell( from );
m_Instrument.ConsumeUse( from );
if (!from.CheckTargetSkill(SkillName.Peacemaking, targ, diff - 25.0, diff + 25.0))
{
from.SendLocalizedMessage(1049531); // You attempt to calm your target, but fail.
m_Instrument.PlayInstrumentBadly(from);
m_Instrument.ConsumeUse(from);
}
else
{
m_Instrument.PlayInstrumentWell(from);
m_Instrument.ConsumeUse(from);
from.NextSkillTime = Core.TickCount + 5000;
if ( targ is BaseCreature )
{
BaseCreature bc = (BaseCreature)targ;
from.NextSkillTime = Core.TickCount + 5000;
if (targ is BaseCreature)
{
BaseCreature bc = (BaseCreature)targ;
from.SendLocalizedMessage( 1049532 ); // You play hypnotic music, calming your target.
from.SendLocalizedMessage(1049532); // You play hypnotic music, calming your target.
targ.Combatant = null;
targ.Warmode = false;
targ.Combatant = null;
targ.Warmode = false;
double seconds = 100 - (diff / 1.5);
double seconds = 100 - diff / 1.5;
if ( seconds > 120 )
seconds = 120;
else if ( seconds < 10 )
seconds = 10;
if (seconds > 120)
seconds = 120;
else if (seconds < 10)
seconds = 10;
bc.Pacify( from, DateTime.UtcNow + TimeSpan.FromSeconds( seconds ) );
}
else
{
from.SendLocalizedMessage( 1049532 ); // You play hypnotic music, calming your target.
bc.Pacify(from, DateTime.UtcNow + TimeSpan.FromSeconds(seconds));
}
else
{
from.SendLocalizedMessage(1049532); // You play hypnotic music, calming your target.
targ.SendLocalizedMessage( 500616 ); // You hear lovely music, and forget to continue battling!
targ.Combatant = null;
targ.Warmode = false;
}
}
}
}
}
}
}
}
targ.SendLocalizedMessage(
500616); // You hear lovely music, and forget to continue battling!
targ.Combatant = null;
targ.Warmode = false;
}
}
}
}
}
}
}
}
}

View file

@ -1,173 +1,177 @@
using System;
using Server.Targeting;
using Server.Engines.ConPVP;
using Server.Items;
using Server.Misc;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class Poisoning
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Poisoning].Callback = OnUse;
}
public class Poisoning
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Poisoning].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
m.Target = new InternalTargetPoison();
public static TimeSpan OnUse(Mobile m)
{
m.Target = new InternalTargetPoison();
m.SendLocalizedMessage( 502137 ); // Select the poison you wish to use
m.SendLocalizedMessage(502137); // Select the poison you wish to use
return TimeSpan.FromSeconds( 10.0 ); // 10 second delay before beign able to re-use a skill
}
return TimeSpan.FromSeconds(10.0); // 10 second delay before beign able to re-use a skill
}
private class InternalTargetPoison : Target
{
public InternalTargetPoison() : base ( 2, false, TargetFlags.None )
{
}
private class InternalTargetPoison : Target
{
public InternalTargetPoison() : base(2, false, TargetFlags.None)
{
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is BasePoisonPotion )
{
from.SendLocalizedMessage( 502142 ); // To what do you wish to apply the poison?
from.Target = new InternalTarget( (BasePoisonPotion)targeted );
}
else // Not a Poison Potion
{
from.SendLocalizedMessage( 502139 ); // That is not a poison potion.
}
}
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is BasePoisonPotion)
{
from.SendLocalizedMessage(502142); // To what do you wish to apply the poison?
from.Target = new InternalTarget((BasePoisonPotion)targeted);
}
else // Not a Poison Potion
{
from.SendLocalizedMessage(502139); // That is not a poison potion.
}
}
private class InternalTarget : Target
{
private BasePoisonPotion m_Potion;
private class InternalTarget : Target
{
private BasePoisonPotion m_Potion;
public InternalTarget( BasePoisonPotion potion ) : base ( 2, false, TargetFlags.None )
{
m_Potion = potion;
}
public InternalTarget(BasePoisonPotion potion) : base(2, false, TargetFlags.None)
{
m_Potion = potion;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Potion.Deleted )
return;
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Potion.Deleted)
return;
bool startTimer = false;
bool startTimer = false;
if ( targeted is Food || targeted is FukiyaDarts || targeted is Shuriken )
{
startTimer = true;
}
else if ( targeted is BaseWeapon )
{
BaseWeapon weapon = (BaseWeapon)targeted;
if (targeted is Food || targeted is FukiyaDarts || targeted is Shuriken)
{
startTimer = true;
}
else if (targeted is BaseWeapon)
{
BaseWeapon weapon = (BaseWeapon)targeted;
if ( Core.AOS )
{
startTimer = ( weapon.PrimaryAbility == WeaponAbility.InfectiousStrike || weapon.SecondaryAbility == WeaponAbility.InfectiousStrike );
}
else if ( weapon.Layer == Layer.OneHanded )
{
// Only Bladed or Piercing weapon can be poisoned
startTimer = ( weapon.Type == WeaponType.Slashing || weapon.Type == WeaponType.Piercing );
}
}
if (Core.AOS)
startTimer = weapon.PrimaryAbility == WeaponAbility.InfectiousStrike ||
weapon.SecondaryAbility == WeaponAbility.InfectiousStrike;
else if (weapon.Layer == Layer.OneHanded)
startTimer = weapon.Type == WeaponType.Slashing || weapon.Type == WeaponType.Piercing;
}
if ( startTimer )
{
new InternalTimer( from, (Item)targeted, m_Potion ).Start();
if (startTimer)
{
new InternalTimer(from, (Item)targeted, m_Potion).Start();
from.PlaySound( 0x4F );
from.PlaySound(0x4F);
if ( !Engines.ConPVP.DuelContext.IsFreeConsume( from ) )
{
m_Potion.Consume();
from.AddToBackpack( new Bottle() );
}
}
else // Target can't be poisoned
{
if ( Core.AOS )
from.SendLocalizedMessage( 1060204 ); // You cannot poison that! You can only poison infectious weapons, food or drink.
else
from.SendLocalizedMessage( 502145 ); // You cannot poison that! You can only poison bladed or piercing weapons, food or drink.
}
}
if (!DuelContext.IsFreeConsume(from))
{
m_Potion.Consume();
from.AddToBackpack(new Bottle());
}
}
else // Target can't be poisoned
{
if (Core.AOS)
from.SendLocalizedMessage(
1060204); // You cannot poison that! You can only poison infectious weapons, food or drink.
else
from.SendLocalizedMessage(
502145); // You cannot poison that! You can only poison bladed or piercing weapons, food or drink.
}
}
private class InternalTimer : Timer
{
private Mobile m_From;
private Item m_Target;
private Poison m_Poison;
private double m_MinSkill, m_MaxSkill;
private class InternalTimer : Timer
{
private Mobile m_From;
private double m_MinSkill, m_MaxSkill;
private Poison m_Poison;
private Item m_Target;
public InternalTimer( Mobile from, Item target, BasePoisonPotion potion ) : base( TimeSpan.FromSeconds( 2.0 ) )
{
m_From = from;
m_Target = target;
m_Poison = potion.Poison;
m_MinSkill = potion.MinPoisoningSkill;
m_MaxSkill = potion.MaxPoisoningSkill;
Priority = TimerPriority.TwoFiftyMS;
}
public InternalTimer(Mobile from, Item target, BasePoisonPotion potion) : base(TimeSpan.FromSeconds(2.0))
{
m_From = from;
m_Target = target;
m_Poison = potion.Poison;
m_MinSkill = potion.MinPoisoningSkill;
m_MaxSkill = potion.MaxPoisoningSkill;
Priority = TimerPriority.TwoFiftyMS;
}
protected override void OnTick()
{
if ( m_From.CheckTargetSkill( SkillName.Poisoning, m_Target, m_MinSkill, m_MaxSkill ) )
{
if ( m_Target is Food )
{
((Food)m_Target).Poison = m_Poison;
}
else if ( m_Target is BaseWeapon )
{
((BaseWeapon)m_Target).Poison = m_Poison;
((BaseWeapon)m_Target).PoisonCharges = 18 - (m_Poison.Level * 2);
}
else if ( m_Target is FukiyaDarts )
{
((FukiyaDarts)m_Target).Poison = m_Poison;
((FukiyaDarts)m_Target).PoisonCharges = Math.Min( 18 - (m_Poison.Level * 2), ((FukiyaDarts)m_Target).UsesRemaining );
}
else if ( m_Target is Shuriken )
{
((Shuriken)m_Target).Poison = m_Poison;
((Shuriken)m_Target).PoisonCharges = Math.Min( 18 - (m_Poison.Level * 2), ((Shuriken)m_Target).UsesRemaining );
}
protected override void OnTick()
{
if (m_From.CheckTargetSkill(SkillName.Poisoning, m_Target, m_MinSkill, m_MaxSkill))
{
if (m_Target is Food)
{
((Food)m_Target).Poison = m_Poison;
}
else if (m_Target is BaseWeapon)
{
((BaseWeapon)m_Target).Poison = m_Poison;
((BaseWeapon)m_Target).PoisonCharges = 18 - m_Poison.Level * 2;
}
else if (m_Target is FukiyaDarts)
{
((FukiyaDarts)m_Target).Poison = m_Poison;
((FukiyaDarts)m_Target).PoisonCharges = Math.Min(18 - m_Poison.Level * 2,
((FukiyaDarts)m_Target).UsesRemaining);
}
else if (m_Target is Shuriken)
{
((Shuriken)m_Target).Poison = m_Poison;
((Shuriken)m_Target).PoisonCharges = Math.Min(18 - m_Poison.Level * 2,
((Shuriken)m_Target).UsesRemaining);
}
m_From.SendLocalizedMessage( 1010517 ); // You apply the poison
m_From.SendLocalizedMessage(1010517); // You apply the poison
Misc.Titles.AwardKarma( m_From, -20, true );
}
else // Failed
{
// 5% of chance of getting poisoned if failed
if ( m_From.Skills[SkillName.Poisoning].Base < 80.0 && Utility.Random( 20 ) == 0 )
{
m_From.SendLocalizedMessage( 502148 ); // You make a grave mistake while applying the poison.
m_From.ApplyPoison( m_From, m_Poison );
}
else
{
if ( m_Target is BaseWeapon )
{
BaseWeapon weapon = (BaseWeapon)m_Target;
Titles.AwardKarma(m_From, -20, true);
}
else // Failed
{
// 5% of chance of getting poisoned if failed
if (m_From.Skills[SkillName.Poisoning].Base < 80.0 && Utility.Random(20) == 0)
{
m_From.SendLocalizedMessage(502148); // You make a grave mistake while applying the poison.
m_From.ApplyPoison(m_From, m_Poison);
}
else
{
if (m_Target is BaseWeapon)
{
BaseWeapon weapon = (BaseWeapon)m_Target;
if ( weapon.Type == WeaponType.Slashing )
m_From.SendLocalizedMessage( 1010516 ); // You fail to apply a sufficient dose of poison on the blade
else
m_From.SendLocalizedMessage( 1010518 ); // You fail to apply a sufficient dose of poison
}
else
{
m_From.SendLocalizedMessage( 1010518 ); // You fail to apply a sufficient dose of poison
}
}
}
}
}
}
}
}
if (weapon.Type == WeaponType.Slashing)
m_From.SendLocalizedMessage(
1010516); // You fail to apply a sufficient dose of poison on the blade
else
m_From.SendLocalizedMessage(
1010518); // You fail to apply a sufficient dose of poison
}
else
{
m_From.SendLocalizedMessage(1010518); // You fail to apply a sufficient dose of poison
}
}
}
}
}
}
}
}
}

View file

@ -1,163 +1,171 @@
using System;
using Server.Targeting;
using Server.Mobiles;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class Provocation
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Provocation].Callback = OnUse;
}
public class Provocation
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Provocation].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
m.RevealingAction();
public static TimeSpan OnUse(Mobile m)
{
m.RevealingAction();
BaseInstrument.PickInstrument( m, OnPickedInstrument );
BaseInstrument.PickInstrument(m, OnPickedInstrument);
return TimeSpan.FromSeconds( 1.0 ); // Cannot use another skill for 1 second
}
return TimeSpan.FromSeconds(1.0); // Cannot use another skill for 1 second
}
public static void OnPickedInstrument( Mobile from, BaseInstrument instrument )
{
from.RevealingAction();
from.SendLocalizedMessage( 501587 ); // Whom do you wish to incite?
from.Target = new InternalFirstTarget( from, instrument );
}
public static void OnPickedInstrument(Mobile from, BaseInstrument instrument)
{
from.RevealingAction();
from.SendLocalizedMessage(501587); // Whom do you wish to incite?
from.Target = new InternalFirstTarget(from, instrument);
}
private class InternalFirstTarget : Target
{
private BaseInstrument m_Instrument;
private class InternalFirstTarget : Target
{
private BaseInstrument m_Instrument;
public InternalFirstTarget( Mobile from, BaseInstrument instrument ) : base( BaseInstrument.GetBardRange( from, SkillName.Provocation ), false, TargetFlags.None )
{
m_Instrument = instrument;
}
public InternalFirstTarget(Mobile from, BaseInstrument instrument) : base(
BaseInstrument.GetBardRange(from, SkillName.Provocation), false, TargetFlags.None)
{
m_Instrument = instrument;
}
protected override void OnTarget( Mobile from, object targeted )
{
from.RevealingAction();
protected override void OnTarget(Mobile from, object targeted)
{
from.RevealingAction();
if ( targeted is BaseCreature && from.CanBeHarmful( (Mobile)targeted, true ) )
{
BaseCreature creature = (BaseCreature)targeted;
if (targeted is BaseCreature && from.CanBeHarmful((Mobile)targeted, true))
{
BaseCreature creature = (BaseCreature)targeted;
if ( !m_Instrument.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1062488 ); // The instrument you are trying to play is no longer in your backpack!
}
else if ( creature.Controlled )
{
from.SendLocalizedMessage( 501590 ); // They are too loyal to their master to be provoked.
}
else if ( creature.IsParagon && BaseInstrument.GetBaseDifficulty( creature ) >= 160.0 )
{
from.SendLocalizedMessage( 1049446 ); // You have no chance of provoking those creatures.
}
else
{
from.RevealingAction();
m_Instrument.PlayInstrumentWell( from );
from.SendLocalizedMessage( 1008085 ); // You play your music and your target becomes angered. Whom do you wish them to attack?
from.Target = new InternalSecondTarget( from, m_Instrument, creature );
}
}
else
{
from.SendLocalizedMessage( 501589 ); // You can't incite that!
}
}
}
if (!m_Instrument.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(
1062488); // The instrument you are trying to play is no longer in your backpack!
}
else if (creature.Controlled)
{
from.SendLocalizedMessage(501590); // They are too loyal to their master to be provoked.
}
else if (creature.IsParagon && BaseInstrument.GetBaseDifficulty(creature) >= 160.0)
{
from.SendLocalizedMessage(1049446); // You have no chance of provoking those creatures.
}
else
{
from.RevealingAction();
m_Instrument.PlayInstrumentWell(from);
from.SendLocalizedMessage(
1008085); // You play your music and your target becomes angered. Whom do you wish them to attack?
from.Target = new InternalSecondTarget(from, m_Instrument, creature);
}
}
else
{
from.SendLocalizedMessage(501589); // You can't incite that!
}
}
}
private class InternalSecondTarget : Target
{
private BaseCreature m_Creature;
private BaseInstrument m_Instrument;
private class InternalSecondTarget : Target
{
private BaseCreature m_Creature;
private BaseInstrument m_Instrument;
public InternalSecondTarget( Mobile from, BaseInstrument instrument, BaseCreature creature ) : base( BaseInstrument.GetBardRange( from, SkillName.Provocation ), false, TargetFlags.None )
{
m_Instrument = instrument;
m_Creature = creature;
}
public InternalSecondTarget(Mobile from, BaseInstrument instrument, BaseCreature creature) : base(
BaseInstrument.GetBardRange(from, SkillName.Provocation), false, TargetFlags.None)
{
m_Instrument = instrument;
m_Creature = creature;
}
protected override void OnTarget( Mobile from, object targeted )
{
from.RevealingAction();
protected override void OnTarget(Mobile from, object targeted)
{
from.RevealingAction();
if ( targeted is BaseCreature )
{
BaseCreature creature = (BaseCreature)targeted;
if (targeted is BaseCreature)
{
BaseCreature creature = (BaseCreature)targeted;
if ( !m_Instrument.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1062488 ); // The instrument you are trying to play is no longer in your backpack!
}
else if ( m_Creature.Unprovokable )
{
from.SendLocalizedMessage( 1049446 ); // You have no chance of provoking those creatures.
}
else if ( creature.Unprovokable && !( creature is DemonKnight ) )
{
from.SendLocalizedMessage( 1049446 ); // You have no chance of provoking those creatures.
}
else if ( m_Creature.Map != creature.Map || !m_Creature.InRange( creature, BaseInstrument.GetBardRange( from, SkillName.Provocation ) ) )
{
from.SendLocalizedMessage( 1049450 ); // The creatures you are trying to provoke are too far away from each other for your music to have an effect.
}
else if ( m_Creature != creature )
{
from.NextSkillTime = Core.TickCount + 10000;
if (!m_Instrument.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(
1062488); // The instrument you are trying to play is no longer in your backpack!
}
else if (m_Creature.Unprovokable)
{
from.SendLocalizedMessage(1049446); // You have no chance of provoking those creatures.
}
else if (creature.Unprovokable && !(creature is DemonKnight))
{
from.SendLocalizedMessage(1049446); // You have no chance of provoking those creatures.
}
else if (m_Creature.Map != creature.Map || !m_Creature.InRange(creature,
BaseInstrument.GetBardRange(from, SkillName.Provocation)))
{
from.SendLocalizedMessage(
1049450); // The creatures you are trying to provoke are too far away from each other for your music to have an effect.
}
else if (m_Creature != creature)
{
from.NextSkillTime = Core.TickCount + 10000;
double diff = ((m_Instrument.GetDifficultyFor( m_Creature ) + m_Instrument.GetDifficultyFor( creature )) * 0.5) - 5.0;
double music = from.Skills[SkillName.Musicianship].Value;
double diff = (m_Instrument.GetDifficultyFor(m_Creature) + m_Instrument.GetDifficultyFor(creature)) *
0.5 - 5.0;
double music = from.Skills[SkillName.Musicianship].Value;
if ( music > 100.0 )
diff -= (music - 100.0) * 0.5;
if (music > 100.0)
diff -= (music - 100.0) * 0.5;
if ( from.CanBeHarmful( m_Creature, true ) && from.CanBeHarmful( creature, true ) )
{
if ( !BaseInstrument.CheckMusicianship( from ) )
{
from.NextSkillTime = Core.TickCount + 5000;
from.SendLocalizedMessage( 500612 ); // You play poorly, and there is no effect.
m_Instrument.PlayInstrumentBadly( from );
m_Instrument.ConsumeUse( from );
}
else
{
//from.DoHarmful( m_Creature );
//from.DoHarmful( creature );
if (from.CanBeHarmful(m_Creature, true) && from.CanBeHarmful(creature, true))
{
if (!BaseInstrument.CheckMusicianship(from))
{
from.NextSkillTime = Core.TickCount + 5000;
from.SendLocalizedMessage(500612); // You play poorly, and there is no effect.
m_Instrument.PlayInstrumentBadly(from);
m_Instrument.ConsumeUse(from);
}
else
{
//from.DoHarmful( m_Creature );
//from.DoHarmful( creature );
if ( !from.CheckTargetSkill( SkillName.Provocation, creature, diff-25.0, diff+25.0 ) )
{
from.NextSkillTime = Core.TickCount + 5000;
from.SendLocalizedMessage( 501599 ); // Your music fails to incite enough anger.
m_Instrument.PlayInstrumentBadly( from );
m_Instrument.ConsumeUse( from );
}
else
{
from.SendLocalizedMessage( 501602 ); // Your music succeeds, as you start a fight.
m_Instrument.PlayInstrumentWell( from );
m_Instrument.ConsumeUse( from );
m_Creature.Provoke( from, creature, true );
}
}
}
}
else
{
from.SendLocalizedMessage( 501593 ); // You can't tell someone to attack themselves!
}
}
else
{
from.SendLocalizedMessage( 501589 ); // You can't incite that!
}
}
}
}
if (!from.CheckTargetSkill(SkillName.Provocation, creature, diff - 25.0, diff + 25.0))
{
from.NextSkillTime = Core.TickCount + 5000;
from.SendLocalizedMessage(501599); // Your music fails to incite enough anger.
m_Instrument.PlayInstrumentBadly(from);
m_Instrument.ConsumeUse(from);
}
else
{
from.SendLocalizedMessage(501602); // Your music succeeds, as you start a fight.
m_Instrument.PlayInstrumentWell(from);
m_Instrument.ConsumeUse(from);
m_Creature.Provoke(from, creature, true);
}
}
}
}
else
{
from.SendLocalizedMessage(501593); // You can't tell someone to attack themselves!
}
}
else
{
from.SendLocalizedMessage(501589); // You can't incite that!
}
}
}
}
}

View file

@ -1,127 +1,134 @@
using System;
using Server.Targeting;
using Server.Factions;
using Server.Items;
using Server.Network;
using Server.Factions;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class RemoveTrap
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.RemoveTrap].Callback = OnUse;
}
public class RemoveTrap
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.RemoveTrap].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
if ( m.Skills[SkillName.Lockpicking].Value < 50 )
{
m.SendLocalizedMessage( 502366 ); // You do not know enough about locks. Become better at picking locks.
}
else if ( m.Skills[SkillName.DetectHidden].Value < 50 )
{
m.SendLocalizedMessage( 502367 ); // You are not perceptive enough. Become better at detect hidden.
}
else
{
m.Target = new InternalTarget();
public static TimeSpan OnUse(Mobile m)
{
if (m.Skills[SkillName.Lockpicking].Value < 50)
{
m.SendLocalizedMessage(502366); // You do not know enough about locks. Become better at picking locks.
}
else if (m.Skills[SkillName.DetectHidden].Value < 50)
{
m.SendLocalizedMessage(502367); // You are not perceptive enough. Become better at detect hidden.
}
else
{
m.Target = new InternalTarget();
m.SendLocalizedMessage( 502368 ); // Wich trap will you attempt to disarm?
}
m.SendLocalizedMessage(502368); // Wich trap will you attempt to disarm?
}
return TimeSpan.FromSeconds( 10.0 ); // 10 second delay before beign able to re-use a skill
}
return TimeSpan.FromSeconds(10.0); // 10 second delay before beign able to re-use a skill
}
private class InternalTarget : Target
{
public InternalTarget() : base ( 2, false, TargetFlags.None )
{
}
private class InternalTarget : Target
{
public InternalTarget() : base(2, false, TargetFlags.None)
{
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Mobile )
{
from.SendLocalizedMessage( 502816 ); // You feel that such an action would be inappropriate
}
else if ( targeted is TrappableContainer )
{
TrappableContainer targ = (TrappableContainer)targeted;
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is Mobile)
{
from.SendLocalizedMessage(502816); // You feel that such an action would be inappropriate
}
else if (targeted is TrappableContainer)
{
TrappableContainer targ = (TrappableContainer)targeted;
from.Direction = from.GetDirectionTo( targ );
from.Direction = from.GetDirectionTo(targ);
if ( targ.TrapType == TrapType.None )
{
from.SendLocalizedMessage( 502373 ); // That doesn't appear to be trapped
return;
}
if (targ.TrapType == TrapType.None)
{
from.SendLocalizedMessage(502373); // That doesn't appear to be trapped
return;
}
from.PlaySound( 0x241 );
from.PlaySound(0x241);
if ( from.CheckTargetSkill( SkillName.RemoveTrap, targ, targ.TrapPower, targ.TrapPower + 30 ) )
{
targ.TrapPower = 0;
targ.TrapLevel = 0;
targ.TrapType = TrapType.None;
from.SendLocalizedMessage( 502377 ); // You successfully render the trap harmless
}
else
{
from.SendLocalizedMessage( 502372 ); // You fail to disarm the trap... but you don't set it off
}
}
else if ( targeted is BaseFactionTrap )
{
BaseFactionTrap trap = (BaseFactionTrap) targeted;
Faction faction = Faction.Find( from );
if (from.CheckTargetSkill(SkillName.RemoveTrap, targ, targ.TrapPower, targ.TrapPower + 30))
{
targ.TrapPower = 0;
targ.TrapLevel = 0;
targ.TrapType = TrapType.None;
from.SendLocalizedMessage(502377); // You successfully render the trap harmless
}
else
{
from.SendLocalizedMessage(502372); // You fail to disarm the trap... but you don't set it off
}
}
else if (targeted is BaseFactionTrap)
{
BaseFactionTrap trap = (BaseFactionTrap)targeted;
Faction faction = Faction.Find(from);
FactionTrapRemovalKit kit = @from.Backpack?.FindItemByType( typeof( FactionTrapRemovalKit ) ) as FactionTrapRemovalKit;
FactionTrapRemovalKit kit =
from.Backpack?.FindItemByType(typeof(FactionTrapRemovalKit)) as FactionTrapRemovalKit;
bool isOwner = ( trap.Placer == from || ( trap.Faction != null && trap.Faction.IsCommander( from ) ) );
bool isOwner = trap.Placer == from || trap.Faction != null && trap.Faction.IsCommander(from);
if ( faction == null )
{
from.SendLocalizedMessage( 1010538 ); // You may not disarm faction traps unless you are in an opposing faction
}
else if ( faction == trap.Faction && trap.Faction != null && !isOwner )
{
from.SendLocalizedMessage( 1010537 ); // You may not disarm traps set by your own faction!
}
else if ( !isOwner && kit == null )
{
from.SendLocalizedMessage( 1042530 ); // You must have a trap removal kit at the base level of your pack to disarm a faction trap.
}
else
{
if ( (Core.ML && isOwner) || (from.CheckTargetSkill( SkillName.RemoveTrap, trap, 80.0, 100.0 ) && from.CheckTargetSkill( SkillName.Tinkering, trap, 80.0, 100.0 )) )
{
from.PrivateOverheadMessage( MessageType.Regular, trap.MessageHue, trap.DisarmMessage, from.NetState );
if (faction == null)
{
from.SendLocalizedMessage(
1010538); // You may not disarm faction traps unless you are in an opposing faction
}
else if (faction == trap.Faction && trap.Faction != null && !isOwner)
{
from.SendLocalizedMessage(1010537); // You may not disarm traps set by your own faction!
}
else if (!isOwner && kit == null)
{
from.SendLocalizedMessage(
1042530); // You must have a trap removal kit at the base level of your pack to disarm a faction trap.
}
else
{
if (Core.ML && isOwner || from.CheckTargetSkill(SkillName.RemoveTrap, trap, 80.0, 100.0) &&
from.CheckTargetSkill(SkillName.Tinkering, trap, 80.0, 100.0))
{
from.PrivateOverheadMessage(MessageType.Regular, trap.MessageHue, trap.DisarmMessage,
from.NetState);
if ( !isOwner )
{
int silver = faction.AwardSilver( from, trap.SilverFromDisarm );
if (!isOwner)
{
int silver = faction.AwardSilver(from, trap.SilverFromDisarm);
if ( silver > 0 )
from.SendLocalizedMessage( 1008113, true, silver.ToString( "N0" ) ); // You have been granted faction silver for removing the enemy trap :
}
if (silver > 0)
from.SendLocalizedMessage(1008113, true,
silver.ToString(
"N0")); // You have been granted faction silver for removing the enemy trap :
}
trap.Delete();
}
else
{
from.SendLocalizedMessage( 502372 ); // You fail to disarm the trap... but you don't set it off
}
trap.Delete();
}
else
{
from.SendLocalizedMessage(502372); // You fail to disarm the trap... but you don't set it off
}
if ( !isOwner )
kit?.ConsumeCharge( from );
}
}
else
{
from.SendLocalizedMessage( 502373 ); // That does'nt appear to be trapped
}
}
}
}
}
if (!isOwner)
kit?.ConsumeCharge(from);
}
}
else
{
from.SendLocalizedMessage(502373); // That does'nt appear to be trapped
}
}
}
}
}

View file

@ -1,105 +1,103 @@
using System;
using Server.Misc;
using Server.Items;
using Server.Misc;
using Server.Mobiles;
using Server.Network;
using Server.Regions;
namespace Server.SkillHandlers
{
public class Snooping
{
public static void Configure()
{
Container.SnoopHandler = Container_Snoop;
}
public class Snooping
{
public static void Configure()
{
Container.SnoopHandler = Container_Snoop;
}
public static bool CheckSnoopAllowed( Mobile from, Mobile to )
{
Map map = from.Map;
public static bool CheckSnoopAllowed(Mobile from, Mobile to)
{
Map map = from.Map;
if ( to.Player )
return from.CanBeHarmful( to, false, true ); // normal restrictions
if (to.Player)
return from.CanBeHarmful(to, false, true); // normal restrictions
if ( map != null && (map.Rules & MapRules.HarmfulRestrictions) == 0 )
return true; // felucca you can snoop anybody
if (map != null && (map.Rules & MapRules.HarmfulRestrictions) == 0)
return true; // felucca you can snoop anybody
GuardedRegion reg = (GuardedRegion) to.Region.GetRegion( typeof( GuardedRegion ) );
GuardedRegion reg = (GuardedRegion)to.Region.GetRegion(typeof(GuardedRegion));
if ( reg == null || reg.IsDisabled() )
return true; // not in town? we can snoop any npc
if (reg == null || reg.IsDisabled())
return true; // not in town? we can snoop any npc
BaseCreature cret = to as BaseCreature;
BaseCreature cret = to as BaseCreature;
if ( to.Body.IsHuman && (cret == null || (!cret.AlwaysAttackable && !cret.AlwaysMurderer)) )
return false; // in town we cannot snoop blue human npcs
if (to.Body.IsHuman && (cret == null || !cret.AlwaysAttackable && !cret.AlwaysMurderer))
return false; // in town we cannot snoop blue human npcs
return true;
}
return true;
}
public static void Container_Snoop( Container cont, Mobile from )
{
if ( from.AccessLevel > AccessLevel.Player || from.InRange( cont.GetWorldLocation(), 1 ) )
{
Mobile root = cont.RootParent as Mobile;
public static void Container_Snoop(Container cont, Mobile from)
{
if (from.AccessLevel > AccessLevel.Player || from.InRange(cont.GetWorldLocation(), 1))
{
Mobile root = cont.RootParent as Mobile;
if ( root != null && !root.Alive )
return;
if (root != null && !root.Alive)
return;
if ( root != null && root.AccessLevel > AccessLevel.Player && from.AccessLevel == AccessLevel.Player )
{
from.SendLocalizedMessage( 500209 ); // You can not peek into the container.
return;
}
if (root != null && root.AccessLevel > AccessLevel.Player && from.AccessLevel == AccessLevel.Player)
{
from.SendLocalizedMessage(500209); // You can not peek into the container.
return;
}
if ( root != null && from.AccessLevel == AccessLevel.Player && !CheckSnoopAllowed( from, root ) )
{
from.SendLocalizedMessage( 1001018 ); // You cannot perform negative acts on your target.
return;
}
if (root != null && from.AccessLevel == AccessLevel.Player && !CheckSnoopAllowed(from, root))
{
from.SendLocalizedMessage(1001018); // You cannot perform negative acts on your target.
return;
}
if ( root != null && from.AccessLevel == AccessLevel.Player && from.Skills[SkillName.Snooping].Value < Utility.Random( 100 ) )
{
Map map = from.Map;
if (root != null && from.AccessLevel == AccessLevel.Player &&
from.Skills[SkillName.Snooping].Value < Utility.Random(100))
{
Map map = from.Map;
if ( map != null )
{
string message = $"You notice {from.Name} attempting to peek into {root.Name}'s belongings.";
if (map != null)
{
string message = $"You notice {from.Name} attempting to peek into {root.Name}'s belongings.";
IPooledEnumerable<NetState> eable = map.GetClientsInRange( from.Location, 8 );
IPooledEnumerable<NetState> eable = map.GetClientsInRange(from.Location, 8);
foreach ( NetState ns in eable )
{
if ( ns.Mobile != from )
ns.Mobile.SendMessage( message );
}
foreach (NetState ns in eable)
if (ns.Mobile != from)
ns.Mobile.SendMessage(message);
eable.Free();
}
}
eable.Free();
}
}
if ( from.AccessLevel == AccessLevel.Player )
Titles.AwardKarma( from, -4, true );
if (from.AccessLevel == AccessLevel.Player)
Titles.AwardKarma(from, -4, true);
if ( from.AccessLevel > AccessLevel.Player || from.CheckTargetSkill( SkillName.Snooping, cont, 0.0, 100.0 ) )
{
if ( cont is TrappableContainer && ((TrappableContainer)cont).ExecuteTrap( from ) )
return;
if (from.AccessLevel > AccessLevel.Player || from.CheckTargetSkill(SkillName.Snooping, cont, 0.0, 100.0))
{
if (cont is TrappableContainer && ((TrappableContainer)cont).ExecuteTrap(from))
return;
cont.DisplayTo( from );
}
else
{
from.SendLocalizedMessage( 500210 ); // You failed to peek into the container.
cont.DisplayTo(from);
}
else
{
from.SendLocalizedMessage(500210); // You failed to peek into the container.
if ( from.Skills[SkillName.Hiding].Value / 2 < Utility.Random( 100 ) )
from.RevealingAction();
}
}
else
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
}
}
}
if (from.Skills[SkillName.Hiding].Value / 2 < Utility.Random(100))
from.RevealingAction();
}
}
else
{
from.SendLocalizedMessage(500446); // That is too far away.
}
}
}
}

View file

@ -1,200 +1,199 @@
using System;
using Server.Items;
using Server.Spells;
using Server.Network;
using Server.Spells;
namespace Server.SkillHandlers
{
class SpiritSpeak
{
public static void Initialize()
{
SkillInfo.Table[32].Callback = OnUse;
}
internal class SpiritSpeak
{
public static void Initialize()
{
SkillInfo.Table[32].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
if ( Core.AOS )
{
Spell spell = new SpiritSpeakSpell( m );
public static TimeSpan OnUse(Mobile m)
{
if (Core.AOS)
{
Spell spell = new SpiritSpeakSpell(m);
spell.Cast();
spell.Cast();
if ( spell.IsCasting )
return TimeSpan.FromSeconds( 5.0 );
if (spell.IsCasting)
return TimeSpan.FromSeconds(5.0);
return TimeSpan.Zero;
}
return TimeSpan.Zero;
}
m.RevealingAction();
m.RevealingAction();
if ( m.CheckSkill( SkillName.SpiritSpeak, 0, 100 ) )
{
if ( !m.CanHearGhosts )
{
Timer t = new SpiritSpeakTimer( m );
double secs = m.Skills[SkillName.SpiritSpeak].Base / 50;
secs *= 90;
if ( secs < 15 )
secs = 15;
if (m.CheckSkill(SkillName.SpiritSpeak, 0, 100))
{
if (!m.CanHearGhosts)
{
Timer t = new SpiritSpeakTimer(m);
double secs = m.Skills[SkillName.SpiritSpeak].Base / 50;
secs *= 90;
if (secs < 15)
secs = 15;
t.Delay = TimeSpan.FromSeconds( secs );//15seconds to 3 minutes
t.Start();
m.CanHearGhosts = true;
}
t.Delay = TimeSpan.FromSeconds(secs); //15seconds to 3 minutes
t.Start();
m.CanHearGhosts = true;
}
m.PlaySound( 0x24A );
m.SendLocalizedMessage( 502444 );//You contact the neitherworld.
}
else
{
m.SendLocalizedMessage( 502443 );//You fail to contact the neitherworld.
m.CanHearGhosts = false;
}
m.PlaySound(0x24A);
m.SendLocalizedMessage(502444); //You contact the neitherworld.
}
else
{
m.SendLocalizedMessage(502443); //You fail to contact the neitherworld.
m.CanHearGhosts = false;
}
return TimeSpan.FromSeconds( 1.0 );
}
return TimeSpan.FromSeconds(1.0);
}
private class SpiritSpeakTimer : Timer
{
private Mobile m_Owner;
public SpiritSpeakTimer( Mobile m ) : base( TimeSpan.FromMinutes( 2.0 ) )
{
m_Owner = m;
Priority = TimerPriority.FiveSeconds;
}
private class SpiritSpeakTimer : Timer
{
private Mobile m_Owner;
protected override void OnTick()
{
m_Owner.CanHearGhosts = false;
m_Owner.SendLocalizedMessage( 502445 );//You feel your contact with the neitherworld fading.
}
}
public SpiritSpeakTimer(Mobile m) : base(TimeSpan.FromMinutes(2.0))
{
m_Owner = m;
Priority = TimerPriority.FiveSeconds;
}
private class SpiritSpeakSpell : Spell
{
private static SpellInfo m_Info = new SpellInfo( "Spirit Speak", "", 269 );
protected override void OnTick()
{
m_Owner.CanHearGhosts = false;
m_Owner.SendLocalizedMessage(502445); //You feel your contact with the neitherworld fading.
}
}
public override bool BlockedByHorrificBeast => false;
private class SpiritSpeakSpell : Spell
{
private static SpellInfo m_Info = new SpellInfo("Spirit Speak", "", 269);
public SpiritSpeakSpell( Mobile caster ) : base( caster, null, m_Info )
{
}
public SpiritSpeakSpell(Mobile caster) : base(caster, null, m_Info)
{
}
public override bool ClearHandsOnCast => false;
public override bool BlockedByHorrificBeast => false;
public override double CastDelayFastScalar => 0;
public override TimeSpan CastDelayBase => TimeSpan.FromSeconds( 1.0 );
public override bool ClearHandsOnCast => false;
public override int GetMana()
{
return 0;
}
public override double CastDelayFastScalar => 0;
public override TimeSpan CastDelayBase => TimeSpan.FromSeconds(1.0);
public override void OnCasterHurt()
{
if ( IsCasting )
Disturb( DisturbType.Hurt, false, true );
}
public override bool CheckNextSpellTime => false;
public override bool ConsumeReagents()
{
return true;
}
public override int GetMana()
{
return 0;
}
public override bool CheckFizzle()
{
return true;
}
public override void OnCasterHurt()
{
if (IsCasting)
Disturb(DisturbType.Hurt, false, true);
}
public override bool CheckNextSpellTime => false;
public override bool ConsumeReagents()
{
return true;
}
public override void OnDisturb( DisturbType type, bool message )
{
Caster.NextSkillTime = Core.TickCount;
public override bool CheckFizzle()
{
return true;
}
base.OnDisturb( type, message );
}
public override void OnDisturb(DisturbType type, bool message)
{
Caster.NextSkillTime = Core.TickCount;
public override bool CheckDisturb( DisturbType type, bool checkFirst, bool resistable )
{
if ( type == DisturbType.EquipRequest || type == DisturbType.UseRequest )
return false;
base.OnDisturb(type, message);
}
return true;
}
public override bool CheckDisturb(DisturbType type, bool checkFirst, bool resistable)
{
if (type == DisturbType.EquipRequest || type == DisturbType.UseRequest)
return false;
public override void SayMantra()
{
// Anh Mi Sah Ko
Caster.PublicOverheadMessage( MessageType.Regular, 0x3B2, 1062074, "", false );
Caster.PlaySound( 0x24A );
}
return true;
}
public override void OnCast()
{
Corpse toChannel = null;
public override void SayMantra()
{
// Anh Mi Sah Ko
Caster.PublicOverheadMessage(MessageType.Regular, 0x3B2, 1062074, "", false);
Caster.PlaySound(0x24A);
}
foreach ( Item item in Caster.GetItemsInRange( 3 ) )
{
if ( item is Corpse && !( (Corpse)item ).Channeled )
{
toChannel = (Corpse)item;
break;
}
}
public override void OnCast()
{
Corpse toChannel = null;
int max, min, mana, number;
foreach (Item item in Caster.GetItemsInRange(3))
if (item is Corpse && !((Corpse)item).Channeled)
{
toChannel = (Corpse)item;
break;
}
if ( toChannel != null )
{
min = 1 + (int)(Caster.Skills[SkillName.SpiritSpeak].Value * 0.25);
max = min + 4;
mana = 0;
number = 1061287; // You channel energy from a nearby corpse to heal your wounds.
}
else
{
min = 1 + (int)(Caster.Skills[SkillName.SpiritSpeak].Value * 0.25);
max = min + 4;
mana = 10;
number = 1061286; // You channel your own spiritual energy to heal your wounds.
}
int max, min, mana, number;
if ( Caster.Mana < mana )
{
Caster.SendLocalizedMessage( 1061285 ); // You lack the mana required to use this skill.
}
else
{
Caster.CheckSkill( SkillName.SpiritSpeak, 0.0, 120.0 );
if (toChannel != null)
{
min = 1 + (int)(Caster.Skills[SkillName.SpiritSpeak].Value * 0.25);
max = min + 4;
mana = 0;
number = 1061287; // You channel energy from a nearby corpse to heal your wounds.
}
else
{
min = 1 + (int)(Caster.Skills[SkillName.SpiritSpeak].Value * 0.25);
max = min + 4;
mana = 10;
number = 1061286; // You channel your own spiritual energy to heal your wounds.
}
if ( Utility.RandomDouble() > (Caster.Skills[SkillName.SpiritSpeak].Value / 100.0) )
{
Caster.SendLocalizedMessage( 502443 ); // You fail your attempt at contacting the netherworld.
}
else
{
if ( toChannel != null )
{
toChannel.Channeled = true;
toChannel.Hue = 0x835;
}
if (Caster.Mana < mana)
{
Caster.SendLocalizedMessage(1061285); // You lack the mana required to use this skill.
}
else
{
Caster.CheckSkill(SkillName.SpiritSpeak, 0.0, 120.0);
Caster.Mana -= mana;
Caster.SendLocalizedMessage( number );
if (Utility.RandomDouble() > Caster.Skills[SkillName.SpiritSpeak].Value / 100.0)
{
Caster.SendLocalizedMessage(502443); // You fail your attempt at contacting the netherworld.
}
else
{
if (toChannel != null)
{
toChannel.Channeled = true;
toChannel.Hue = 0x835;
}
if ( min > max )
min = max;
Caster.Mana -= mana;
Caster.SendLocalizedMessage(number);
Caster.Hits += Utility.RandomMinMax( min, max );
if (min > max)
min = max;
Caster.FixedParticles( 0x375A, 1, 15, 9501, 2100, 4, EffectLayer.Waist );
}
}
Caster.Hits += Utility.RandomMinMax(min, max);
FinishSequence();
}
}
}
}
Caster.FixedParticles(0x375A, 1, 15, 9501, 2100, 4, EffectLayer.Waist);
}
}
FinishSequence();
}
}
}
}

View file

@ -1,486 +1,492 @@
using System;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Targeting;
using Server.Items;
using Server.Network;
using Server.Engines.ConPVP;
using Server.Factions;
using Server.Spells.Seventh;
using Server.Spells.Fifth;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Spells;
using Server.Spells.Fifth;
using Server.Spells.Ninjitsu;
using Server.Spells.Seventh;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class Stealing
{
public static void Initialize()
{
SkillInfo.Table[33].Callback = OnUse;
}
public static readonly bool ClassicMode = false;
public static readonly bool SuspendOnMurder = false;
public static bool IsInGuild( Mobile m )
{
return ( m is PlayerMobile && ((PlayerMobile)m).NpcGuild == NpcGuild.ThievesGuild );
}
public static bool IsInnocentTo( Mobile from, Mobile to )
{
return ( Notoriety.Compute( from, (Mobile)to ) == Notoriety.Innocent );
}
private class StealingTarget : Target
{
private Mobile m_Thief;
public StealingTarget( Mobile thief ) : base ( 1, false, TargetFlags.None )
{
m_Thief = thief;
AllowNonlocal = true;
}
private Item TryStealItem( Item toSteal, ref bool caught )
{
Item stolen = null;
object root = toSteal.RootParent;
StealableArtifactsSpawner.StealableInstance si = null;
if ( toSteal.Parent == null || !toSteal.Movable )
si = StealableArtifactsSpawner.GetStealableInstance( toSteal );
if ( !IsEmptyHanded( m_Thief ) )
{
m_Thief.SendLocalizedMessage( 1005584 ); // Both hands must be free to steal.
}
else if ( m_Thief.Region.IsPartOf( typeof( Engines.ConPVP.SafeZone ) ) )
{
m_Thief.SendMessage( "You may not steal in this area." );
}
else if ( root is Mobile && ((Mobile)root).Player && !IsInGuild( m_Thief ) )
{
m_Thief.SendLocalizedMessage( 1005596 ); // You must be in the thieves guild to steal from other players.
}
else if ( SuspendOnMurder && root is Mobile && ((Mobile)root).Player && IsInGuild( m_Thief ) && m_Thief.Kills > 0 )
{
m_Thief.SendLocalizedMessage( 502706 ); // You are currently suspended from the thieves guild.
}
else if ( root is BaseVendor && ((BaseVendor)root).IsInvulnerable )
{
m_Thief.SendLocalizedMessage( 1005598 ); // You can't steal from shopkeepers.
}
else if ( root is PlayerVendor )
{
m_Thief.SendLocalizedMessage( 502709 ); // You can't steal from vendors.
}
else if ( !m_Thief.CanSee( toSteal ) )
{
m_Thief.SendLocalizedMessage( 500237 ); // Target can not be seen.
}
else if ( m_Thief.Backpack == null || !m_Thief.Backpack.CheckHold( m_Thief, toSteal, false, true ) )
{
m_Thief.SendLocalizedMessage( 1048147 ); // Your backpack can't hold anything else.
}
#region Sigils
else if ( toSteal is Sigil )
{
PlayerState pl = PlayerState.Find( m_Thief );
Faction faction = pl?.Faction;
Sigil sig = (Sigil) toSteal;
if ( !m_Thief.InRange( toSteal.GetWorldLocation(), 1 ) )
{
m_Thief.SendLocalizedMessage( 502703 ); // You must be standing next to an item to steal it.
}
else if ( root != null ) // not on the ground
{
m_Thief.SendLocalizedMessage( 502710 ); // You can't steal that!
}
else if ( faction != null )
{
if ( !m_Thief.CanBeginAction( typeof( IncognitoSpell ) ) )
{
m_Thief.SendLocalizedMessage( 1010581 ); // You cannot steal the sigil when you are incognito
}
else if ( DisguiseTimers.IsDisguised( m_Thief ) )
{
m_Thief.SendLocalizedMessage( 1010583 ); // You cannot steal the sigil while disguised
}
else if ( !m_Thief.CanBeginAction( typeof( PolymorphSpell ) ) )
{
m_Thief.SendLocalizedMessage( 1010582 ); // You cannot steal the sigil while polymorphed
}
else if ( TransformationSpellHelper.UnderTransformation( m_Thief ) )
{
m_Thief.SendLocalizedMessage( 1061622 ); // You cannot steal the sigil while in that form.
}
else if ( AnimalForm.UnderTransformation( m_Thief ) )
{
m_Thief.SendLocalizedMessage( 1063222 ); // You cannot steal the sigil while mimicking an animal.
}
else if ( pl.IsLeaving )
{
m_Thief.SendLocalizedMessage( 1005589 ); // You are currently quitting a faction and cannot steal the town sigil
}
else if ( sig.IsBeingCorrupted && sig.LastMonolith.Faction == faction )
{
m_Thief.SendLocalizedMessage( 1005590 ); // You cannot steal your own sigil
}
else if ( sig.IsPurifying )
{
m_Thief.SendLocalizedMessage( 1005592 ); // You cannot steal this sigil until it has been purified
}
else if ( m_Thief.CheckTargetSkill( SkillName.Stealing, toSteal, 80.0, 80.0 ) )
{
if ( Sigil.ExistsOn( m_Thief ) )
{
m_Thief.SendLocalizedMessage( 1010258 ); // The sigil has gone back to its home location because you already have a sigil.
}
else if ( m_Thief.Backpack == null || !m_Thief.Backpack.CheckHold( m_Thief, sig, false, true ) )
{
m_Thief.SendLocalizedMessage( 1010259 ); // The sigil has gone home because your backpack is full
}
else
{
if ( sig.IsBeingCorrupted )
sig.GraceStart = DateTime.UtcNow; // begin grace period
m_Thief.SendLocalizedMessage( 1010586 ); // YOU STOLE THE SIGIL!!! (woah, calm down now)
if ( sig.LastMonolith?.Sigil != null ) {
sig.LastMonolith.Sigil = null;
sig.LastStolen = DateTime.UtcNow;
}
return sig;
}
}
else
{
m_Thief.SendLocalizedMessage( 1005594 ); // You do not have enough skill to steal the sigil
}
}
else
{
m_Thief.SendLocalizedMessage( 1005588 ); // You must join a faction to do that
}
}
#endregion
else if ( si == null && ( toSteal.Parent == null || !toSteal.Movable ) )
{
m_Thief.SendLocalizedMessage( 502710 ); // You can't steal that!
}
else if ( toSteal.LootType == LootType.Newbied || toSteal.CheckBlessed( root ) )
{
m_Thief.SendLocalizedMessage( 502710 ); // You can't steal that!
}
else if ( Core.AOS && si == null && toSteal is Container )
{
m_Thief.SendLocalizedMessage( 502710 ); // You can't steal that!
}
else if ( !m_Thief.InRange( toSteal.GetWorldLocation(), 1 ) )
{
m_Thief.SendLocalizedMessage( 502703 ); // You must be standing next to an item to steal it.
}
else if ( si != null && m_Thief.Skills[SkillName.Stealing].Value < 100.0 )
{
m_Thief.SendLocalizedMessage( 1060025, "", 0x66D ); // You're not skilled enough to attempt the theft of this item.
}
else if ( toSteal.Parent is Mobile )
{
m_Thief.SendLocalizedMessage( 1005585 ); // You cannot steal items which are equipped.
}
else if ( root == m_Thief )
{
m_Thief.SendLocalizedMessage( 502704 ); // You catch yourself red-handed.
}
else if ( root is Mobile && ((Mobile)root).AccessLevel > AccessLevel.Player )
{
m_Thief.SendLocalizedMessage( 502710 ); // You can't steal that!
}
else if ( root is Mobile && !m_Thief.CanBeHarmful( (Mobile)root ) )
{
}
else if ( root is Corpse )
{
m_Thief.SendLocalizedMessage( 502710 ); // You can't steal that!
}
else
{
double w = toSteal.Weight + toSteal.TotalWeight;
if ( w > 10 )
{
m_Thief.SendMessage( "That is too heavy to steal." );
}
else
{
if ( toSteal.Stackable && toSteal.Amount > 1 )
{
int maxAmount = (int)((m_Thief.Skills[SkillName.Stealing].Value / 10.0) / toSteal.Weight);
if ( maxAmount < 1 )
maxAmount = 1;
else if ( maxAmount > toSteal.Amount )
maxAmount = toSteal.Amount;
int amount = Utility.RandomMinMax( 1, maxAmount );
if ( amount >= toSteal.Amount )
{
int pileWeight = (int)Math.Ceiling( toSteal.Weight * toSteal.Amount );
pileWeight *= 10;
if ( m_Thief.CheckTargetSkill( SkillName.Stealing, toSteal, pileWeight - 22.5, pileWeight + 27.5 ) )
stolen = toSteal;
}
else
{
int pileWeight = (int)Math.Ceiling( toSteal.Weight * amount );
pileWeight *= 10;
if ( m_Thief.CheckTargetSkill( SkillName.Stealing, toSteal, pileWeight - 22.5, pileWeight + 27.5 ) )
{
stolen = Mobile.LiftItemDupe( toSteal, toSteal.Amount - amount );
if ( stolen == null )
stolen = toSteal;
}
}
}
else
{
int iw = (int)Math.Ceiling( w );
iw *= 10;
if ( m_Thief.CheckTargetSkill( SkillName.Stealing, toSteal, iw - 22.5, iw + 27.5 ) )
stolen = toSteal;
}
if ( stolen != null )
{
m_Thief.SendLocalizedMessage( 502724 ); // You successfully steal the item.
if ( si != null )
{
toSteal.Movable = true;
si.Item = null;
}
}
else
{
m_Thief.SendLocalizedMessage( 502723 ); // You fail to steal the item.
}
caught = ( m_Thief.Skills[SkillName.Stealing].Value < Utility.Random( 150 ) );
}
}
return stolen;
}
protected override void OnTarget( Mobile from, object target )
{
from.RevealingAction();
Item stolen = null;
object root = null;
bool caught = false;
if ( target is Item )
{
root = ((Item)target).RootParent;
stolen = TryStealItem( (Item)target, ref caught );
}
else if ( target is Mobile )
{
Container pack = ((Mobile)target).Backpack;
if ( pack != null && pack.Items.Count > 0 )
{
int randomIndex = Utility.Random( pack.Items.Count );
root = target;
stolen = TryStealItem( pack.Items[randomIndex], ref caught );
}
}
else
{
m_Thief.SendLocalizedMessage( 502710 ); // You can't steal that!
}
if ( stolen != null )
{
from.AddToBackpack( stolen );
if ( !( stolen is Container || stolen.Stackable ) ) { // do not return stolen containers or stackable items
StolenItem.Add( stolen, m_Thief, root as Mobile );
}
}
if ( caught )
{
if ( root == null )
{
m_Thief.CriminalAction( false );
}
else if ( root is Corpse && ((Corpse)root).IsCriminalAction( m_Thief ) )
{
m_Thief.CriminalAction( false );
}
else if ( root is Mobile )
{
Mobile mobRoot = (Mobile)root;
if ( !IsInGuild( mobRoot ) && IsInnocentTo( m_Thief, mobRoot ) )
m_Thief.CriminalAction( false );
string message = $"You notice {m_Thief.Name} trying to steal from {mobRoot.Name}.";
foreach ( NetState ns in m_Thief.GetClientsInRange( 8 ) )
{
if ( ns.Mobile != m_Thief )
ns.Mobile.SendMessage( message );
}
}
}
else if ( root is Corpse && ((Corpse)root).IsCriminalAction( m_Thief ) )
{
m_Thief.CriminalAction( false );
}
if ( root is Mobile && ((Mobile)root).Player && m_Thief is PlayerMobile && IsInnocentTo( m_Thief, (Mobile)root ) && !IsInGuild( (Mobile)root ) )
{
PlayerMobile pm = (PlayerMobile)m_Thief;
pm.PermaFlags.Add( (Mobile)root );
pm.Delta( MobileDelta.Noto );
}
}
}
public static bool IsEmptyHanded( Mobile from )
{
if ( from.FindItemOnLayer( Layer.OneHanded ) != null )
return false;
if ( from.FindItemOnLayer( Layer.TwoHanded ) != null )
return false;
return true;
}
public static TimeSpan OnUse( Mobile m )
{
if ( !IsEmptyHanded( m ) )
{
m.SendLocalizedMessage( 1005584 ); // Both hands must be free to steal.
}
else if ( m.Region.IsPartOf( typeof( Engines.ConPVP.SafeZone ) ) )
{
m.SendMessage( "You may not steal in this area." );
}
else
{
m.Target = new StealingTarget( m );
m.RevealingAction();
m.SendLocalizedMessage( 502698 ); // Which item do you want to steal?
}
return TimeSpan.FromSeconds( 10.0 );
}
}
public class StolenItem
{
public static readonly TimeSpan StealTime = TimeSpan.FromMinutes( 2.0 );
public Item Stolen { get; }
public Mobile Thief { get; }
public Mobile Victim { get; }
public DateTime Expires { get; private set; }
public bool IsExpired => ( DateTime.UtcNow >= Expires );
public StolenItem( Item stolen, Mobile thief, Mobile victim )
{
Stolen = stolen;
Thief = thief;
Victim = victim;
Expires = DateTime.UtcNow + StealTime;
}
private static Queue<StolenItem> m_Queue = new Queue<StolenItem>();
public static void Add( Item item, Mobile thief, Mobile victim )
{
Clean();
m_Queue.Enqueue( new StolenItem( item, thief, victim ) );
}
public static bool IsStolen( Item item )
{
Mobile victim = null;
return IsStolen( item, ref victim );
}
public static bool IsStolen( Item item, ref Mobile victim )
{
Clean();
foreach ( StolenItem si in m_Queue )
{
if ( si.Stolen == item && !si.IsExpired )
{
victim = si.Victim;
return true;
}
}
return false;
}
public static void ReturnOnDeath( Mobile killed, Container corpse )
{
Clean();
foreach ( StolenItem si in m_Queue )
{
if ( si.Stolen.RootParent == corpse && si.Victim != null && !si.IsExpired )
{
if ( si.Victim.AddToBackpack( si.Stolen ) )
si.Victim.SendLocalizedMessage( 1010464 ); // the item that was stolen is returned to you.
else
si.Victim.SendLocalizedMessage( 1010463 ); // the item that was stolen from you falls to the ground.
si.Expires = DateTime.UtcNow; // such a hack
}
}
}
public static void Clean()
{
while ( m_Queue.Count > 0 )
{
StolenItem si = m_Queue.Peek();
if ( si.IsExpired )
m_Queue.Dequeue();
else
break;
}
}
}
}
public class Stealing
{
public static readonly bool ClassicMode = false;
public static readonly bool SuspendOnMurder = false;
public static void Initialize()
{
SkillInfo.Table[33].Callback = OnUse;
}
public static bool IsInGuild(Mobile m)
{
return m is PlayerMobile && ((PlayerMobile)m).NpcGuild == NpcGuild.ThievesGuild;
}
public static bool IsInnocentTo(Mobile from, Mobile to)
{
return Notoriety.Compute(from, to) == Notoriety.Innocent;
}
public static bool IsEmptyHanded(Mobile from)
{
if (from.FindItemOnLayer(Layer.OneHanded) != null)
return false;
if (from.FindItemOnLayer(Layer.TwoHanded) != null)
return false;
return true;
}
public static TimeSpan OnUse(Mobile m)
{
if (!IsEmptyHanded(m))
{
m.SendLocalizedMessage(1005584); // Both hands must be free to steal.
}
else if (m.Region.IsPartOf(typeof(SafeZone)))
{
m.SendMessage("You may not steal in this area.");
}
else
{
m.Target = new StealingTarget(m);
m.RevealingAction();
m.SendLocalizedMessage(502698); // Which item do you want to steal?
}
return TimeSpan.FromSeconds(10.0);
}
private class StealingTarget : Target
{
private Mobile m_Thief;
public StealingTarget(Mobile thief) : base(1, false, TargetFlags.None)
{
m_Thief = thief;
AllowNonlocal = true;
}
private Item TryStealItem(Item toSteal, ref bool caught)
{
Item stolen = null;
object root = toSteal.RootParent;
StealableArtifactsSpawner.StealableInstance si = null;
if (toSteal.Parent == null || !toSteal.Movable)
si = StealableArtifactsSpawner.GetStealableInstance(toSteal);
if (!IsEmptyHanded(m_Thief))
{
m_Thief.SendLocalizedMessage(1005584); // Both hands must be free to steal.
}
else if (m_Thief.Region.IsPartOf(typeof(SafeZone)))
{
m_Thief.SendMessage("You may not steal in this area.");
}
else if (root is Mobile && ((Mobile)root).Player && !IsInGuild(m_Thief))
{
m_Thief.SendLocalizedMessage(1005596); // You must be in the thieves guild to steal from other players.
}
else if (SuspendOnMurder && root is Mobile && ((Mobile)root).Player && IsInGuild(m_Thief) &&
m_Thief.Kills > 0)
{
m_Thief.SendLocalizedMessage(502706); // You are currently suspended from the thieves guild.
}
else if (root is BaseVendor && ((BaseVendor)root).IsInvulnerable)
{
m_Thief.SendLocalizedMessage(1005598); // You can't steal from shopkeepers.
}
else if (root is PlayerVendor)
{
m_Thief.SendLocalizedMessage(502709); // You can't steal from vendors.
}
else if (!m_Thief.CanSee(toSteal))
{
m_Thief.SendLocalizedMessage(500237); // Target can not be seen.
}
else if (m_Thief.Backpack == null || !m_Thief.Backpack.CheckHold(m_Thief, toSteal, false, true))
{
m_Thief.SendLocalizedMessage(1048147); // Your backpack can't hold anything else.
}
#region Sigils
else if (toSteal is Sigil)
{
PlayerState pl = PlayerState.Find(m_Thief);
Faction faction = pl?.Faction;
Sigil sig = (Sigil)toSteal;
if (!m_Thief.InRange(toSteal.GetWorldLocation(), 1))
{
m_Thief.SendLocalizedMessage(502703); // You must be standing next to an item to steal it.
}
else if (root != null) // not on the ground
{
m_Thief.SendLocalizedMessage(502710); // You can't steal that!
}
else if (faction != null)
{
if (!m_Thief.CanBeginAction(typeof(IncognitoSpell)))
{
m_Thief.SendLocalizedMessage(1010581); // You cannot steal the sigil when you are incognito
}
else if (DisguiseTimers.IsDisguised(m_Thief))
{
m_Thief.SendLocalizedMessage(1010583); // You cannot steal the sigil while disguised
}
else if (!m_Thief.CanBeginAction(typeof(PolymorphSpell)))
{
m_Thief.SendLocalizedMessage(1010582); // You cannot steal the sigil while polymorphed
}
else if (TransformationSpellHelper.UnderTransformation(m_Thief))
{
m_Thief.SendLocalizedMessage(1061622); // You cannot steal the sigil while in that form.
}
else if (AnimalForm.UnderTransformation(m_Thief))
{
m_Thief.SendLocalizedMessage(1063222); // You cannot steal the sigil while mimicking an animal.
}
else if (pl.IsLeaving)
{
m_Thief.SendLocalizedMessage(
1005589); // You are currently quitting a faction and cannot steal the town sigil
}
else if (sig.IsBeingCorrupted && sig.LastMonolith.Faction == faction)
{
m_Thief.SendLocalizedMessage(1005590); // You cannot steal your own sigil
}
else if (sig.IsPurifying)
{
m_Thief.SendLocalizedMessage(1005592); // You cannot steal this sigil until it has been purified
}
else if (m_Thief.CheckTargetSkill(SkillName.Stealing, toSteal, 80.0, 80.0))
{
if (Sigil.ExistsOn(m_Thief))
{
m_Thief.SendLocalizedMessage(
1010258); // The sigil has gone back to its home location because you already have a sigil.
}
else if (m_Thief.Backpack == null || !m_Thief.Backpack.CheckHold(m_Thief, sig, false, true))
{
m_Thief.SendLocalizedMessage(
1010259); // The sigil has gone home because your backpack is full
}
else
{
if (sig.IsBeingCorrupted)
sig.GraceStart = DateTime.UtcNow; // begin grace period
m_Thief.SendLocalizedMessage(1010586); // YOU STOLE THE SIGIL!!! (woah, calm down now)
if (sig.LastMonolith?.Sigil != null)
{
sig.LastMonolith.Sigil = null;
sig.LastStolen = DateTime.UtcNow;
}
return sig;
}
}
else
{
m_Thief.SendLocalizedMessage(1005594); // You do not have enough skill to steal the sigil
}
}
else
{
m_Thief.SendLocalizedMessage(1005588); // You must join a faction to do that
}
}
#endregion
else if (si == null && (toSteal.Parent == null || !toSteal.Movable))
{
m_Thief.SendLocalizedMessage(502710); // You can't steal that!
}
else if (toSteal.LootType == LootType.Newbied || toSteal.CheckBlessed(root))
{
m_Thief.SendLocalizedMessage(502710); // You can't steal that!
}
else if (Core.AOS && si == null && toSteal is Container)
{
m_Thief.SendLocalizedMessage(502710); // You can't steal that!
}
else if (!m_Thief.InRange(toSteal.GetWorldLocation(), 1))
{
m_Thief.SendLocalizedMessage(502703); // You must be standing next to an item to steal it.
}
else if (si != null && m_Thief.Skills[SkillName.Stealing].Value < 100.0)
{
m_Thief.SendLocalizedMessage(1060025, "",
0x66D); // You're not skilled enough to attempt the theft of this item.
}
else if (toSteal.Parent is Mobile)
{
m_Thief.SendLocalizedMessage(1005585); // You cannot steal items which are equipped.
}
else if (root == m_Thief)
{
m_Thief.SendLocalizedMessage(502704); // You catch yourself red-handed.
}
else if (root is Mobile && ((Mobile)root).AccessLevel > AccessLevel.Player)
{
m_Thief.SendLocalizedMessage(502710); // You can't steal that!
}
else if (root is Mobile && !m_Thief.CanBeHarmful((Mobile)root))
{
}
else if (root is Corpse)
{
m_Thief.SendLocalizedMessage(502710); // You can't steal that!
}
else
{
double w = toSteal.Weight + toSteal.TotalWeight;
if (w > 10)
{
m_Thief.SendMessage("That is too heavy to steal.");
}
else
{
if (toSteal.Stackable && toSteal.Amount > 1)
{
int maxAmount = (int)(m_Thief.Skills[SkillName.Stealing].Value / 10.0 / toSteal.Weight);
if (maxAmount < 1)
maxAmount = 1;
else if (maxAmount > toSteal.Amount)
maxAmount = toSteal.Amount;
int amount = Utility.RandomMinMax(1, maxAmount);
if (amount >= toSteal.Amount)
{
int pileWeight = (int)Math.Ceiling(toSteal.Weight * toSteal.Amount);
pileWeight *= 10;
if (m_Thief.CheckTargetSkill(SkillName.Stealing, toSteal, pileWeight - 22.5,
pileWeight + 27.5))
stolen = toSteal;
}
else
{
int pileWeight = (int)Math.Ceiling(toSteal.Weight * amount);
pileWeight *= 10;
if (m_Thief.CheckTargetSkill(SkillName.Stealing, toSteal, pileWeight - 22.5,
pileWeight + 27.5))
{
stolen = Mobile.LiftItemDupe(toSteal, toSteal.Amount - amount);
if (stolen == null)
stolen = toSteal;
}
}
}
else
{
int iw = (int)Math.Ceiling(w);
iw *= 10;
if (m_Thief.CheckTargetSkill(SkillName.Stealing, toSteal, iw - 22.5, iw + 27.5))
stolen = toSteal;
}
if (stolen != null)
{
m_Thief.SendLocalizedMessage(502724); // You successfully steal the item.
if (si != null)
{
toSteal.Movable = true;
si.Item = null;
}
}
else
{
m_Thief.SendLocalizedMessage(502723); // You fail to steal the item.
}
caught = m_Thief.Skills[SkillName.Stealing].Value < Utility.Random(150);
}
}
return stolen;
}
protected override void OnTarget(Mobile from, object target)
{
from.RevealingAction();
Item stolen = null;
object root = null;
bool caught = false;
if (target is Item)
{
root = ((Item)target).RootParent;
stolen = TryStealItem((Item)target, ref caught);
}
else if (target is Mobile)
{
Container pack = ((Mobile)target).Backpack;
if (pack != null && pack.Items.Count > 0)
{
int randomIndex = Utility.Random(pack.Items.Count);
root = target;
stolen = TryStealItem(pack.Items[randomIndex], ref caught);
}
}
else
{
m_Thief.SendLocalizedMessage(502710); // You can't steal that!
}
if (stolen != null)
{
from.AddToBackpack(stolen);
if (!(stolen is Container || stolen.Stackable)) StolenItem.Add(stolen, m_Thief, root as Mobile);
}
if (caught)
{
if (root == null)
{
m_Thief.CriminalAction(false);
}
else if (root is Corpse && ((Corpse)root).IsCriminalAction(m_Thief))
{
m_Thief.CriminalAction(false);
}
else if (root is Mobile)
{
Mobile mobRoot = (Mobile)root;
if (!IsInGuild(mobRoot) && IsInnocentTo(m_Thief, mobRoot))
m_Thief.CriminalAction(false);
string message = $"You notice {m_Thief.Name} trying to steal from {mobRoot.Name}.";
foreach (NetState ns in m_Thief.GetClientsInRange(8))
if (ns.Mobile != m_Thief)
ns.Mobile.SendMessage(message);
}
}
else if (root is Corpse && ((Corpse)root).IsCriminalAction(m_Thief))
{
m_Thief.CriminalAction(false);
}
if (root is Mobile && ((Mobile)root).Player && m_Thief is PlayerMobile &&
IsInnocentTo(m_Thief, (Mobile)root) && !IsInGuild((Mobile)root))
{
PlayerMobile pm = (PlayerMobile)m_Thief;
pm.PermaFlags.Add((Mobile)root);
pm.Delta(MobileDelta.Noto);
}
}
}
}
public class StolenItem
{
public static readonly TimeSpan StealTime = TimeSpan.FromMinutes(2.0);
private static Queue<StolenItem> m_Queue = new Queue<StolenItem>();
public StolenItem(Item stolen, Mobile thief, Mobile victim)
{
Stolen = stolen;
Thief = thief;
Victim = victim;
Expires = DateTime.UtcNow + StealTime;
}
public Item Stolen{ get; }
public Mobile Thief{ get; }
public Mobile Victim{ get; }
public DateTime Expires{ get; private set; }
public bool IsExpired => DateTime.UtcNow >= Expires;
public static void Add(Item item, Mobile thief, Mobile victim)
{
Clean();
m_Queue.Enqueue(new StolenItem(item, thief, victim));
}
public static bool IsStolen(Item item)
{
Mobile victim = null;
return IsStolen(item, ref victim);
}
public static bool IsStolen(Item item, ref Mobile victim)
{
Clean();
foreach (StolenItem si in m_Queue)
if (si.Stolen == item && !si.IsExpired)
{
victim = si.Victim;
return true;
}
return false;
}
public static void ReturnOnDeath(Mobile killed, Container corpse)
{
Clean();
foreach (StolenItem si in m_Queue)
if (si.Stolen.RootParent == corpse && si.Victim != null && !si.IsExpired)
{
if (si.Victim.AddToBackpack(si.Stolen))
si.Victim.SendLocalizedMessage(1010464); // the item that was stolen is returned to you.
else
si.Victim.SendLocalizedMessage(1010463); // the item that was stolen from you falls to the ground.
si.Expires = DateTime.UtcNow; // such a hack
}
}
public static void Clean()
{
while (m_Queue.Count > 0)
{
StolenItem si = m_Queue.Peek();
if (si.IsExpired)
m_Queue.Dequeue();
else
break;
}
}
}
}

View file

@ -4,109 +4,110 @@ using Server.Mobiles;
namespace Server.SkillHandlers
{
public class Stealth
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Stealth].Callback = OnUse;
}
public class Stealth
{
public static double HidingRequirement => Core.ML ? 30.0 : Core.SE ? 50.0 : 80.0;
public static double HidingRequirement => ( Core.ML ? 30.0 : ( Core.SE ? 50.0 : 80.0 ) );
public static int[,] ArmorTable{ get; } =
{
// Gorget Gloves Helmet Arms Legs Chest Shield
/* Cloth */ { 0, 0, 0, 0, 0, 0, 0 },
/* Leather */ { 0, 0, 0, 0, 0, 0, 0 },
/* Studded */ { 2, 2, 0, 4, 6, 10, 0 },
/* Bone */ { 0, 5, 10, 10, 15, 25, 0 },
/* Spined */ { 0, 0, 0, 0, 0, 0, 0 },
/* Horned */ { 0, 0, 0, 0, 0, 0, 0 },
/* Barbed */ { 0, 0, 0, 0, 0, 0, 0 },
/* Ring */ { 0, 5, 0, 10, 15, 25, 0 },
/* Chain */ { 0, 0, 10, 0, 15, 25, 0 },
/* Plate */ { 5, 5, 10, 10, 15, 25, 0 },
/* Dragon */ { 0, 5, 10, 10, 15, 25, 0 }
};
public static int[,] ArmorTable { get; } =
{
// Gorget Gloves Helmet Arms Legs Chest Shield
/* Cloth */ { 0, 0, 0, 0, 0, 0, 0 },
/* Leather */ { 0, 0, 0, 0, 0, 0, 0 },
/* Studded */ { 2, 2, 0, 4, 6, 10, 0 },
/* Bone */ { 0, 5, 10, 10, 15, 25, 0 },
/* Spined */ { 0, 0, 0, 0, 0, 0, 0 },
/* Horned */ { 0, 0, 0, 0, 0, 0, 0 },
/* Barbed */ { 0, 0, 0, 0, 0, 0, 0 },
/* Ring */ { 0, 5, 0, 10, 15, 25, 0 },
/* Chain */ { 0, 0, 10, 0, 15, 25, 0 },
/* Plate */ { 5, 5, 10, 10, 15, 25, 0 },
/* Dragon */ { 0, 5, 10, 10, 15, 25, 0 }
};
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Stealth].Callback = OnUse;
}
public static int GetArmorRating( Mobile m )
{
if ( !Core.AOS )
return (int)m.ArmorRating;
public static int GetArmorRating(Mobile m)
{
if (!Core.AOS)
return (int)m.ArmorRating;
int ar = 0;
int ar = 0;
for( int i = 0; i < m.Items.Count; i++ )
{
BaseArmor armor = m.Items[i] as BaseArmor;
for (int i = 0; i < m.Items.Count; i++)
{
BaseArmor armor = m.Items[i] as BaseArmor;
if ( armor == null )
continue;
if (armor == null)
continue;
int materialType = (int)armor.MaterialType;
int bodyPosition = (int)armor.BodyPosition;
int materialType = (int)armor.MaterialType;
int bodyPosition = (int)armor.BodyPosition;
if ( materialType >= ArmorTable.GetLength( 0 ) || bodyPosition >= ArmorTable.GetLength( 1 ) )
continue;
if (materialType >= ArmorTable.GetLength(0) || bodyPosition >= ArmorTable.GetLength(1))
continue;
if ( armor.ArmorAttributes.MageArmor == 0 )
ar += ArmorTable[materialType, bodyPosition];
}
if (armor.ArmorAttributes.MageArmor == 0)
ar += ArmorTable[materialType, bodyPosition];
}
return ar;
}
return ar;
}
public static TimeSpan OnUse( Mobile m )
{
if ( !m.Hidden )
{
m.SendLocalizedMessage( 502725 ); // You must hide first
}
else if ( m.Skills[SkillName.Hiding].Base < HidingRequirement )
{
m.SendLocalizedMessage( 502726 ); // You are not hidden well enough. Become better at hiding.
m.RevealingAction();
}
else if ( !m.CanBeginAction( typeof( Stealth ) ) )
{
m.SendLocalizedMessage( 1063086 ); // You cannot use this skill right now.
m.RevealingAction();
}
else
{
int armorRating = GetArmorRating( m );
public static TimeSpan OnUse(Mobile m)
{
if (!m.Hidden)
{
m.SendLocalizedMessage(502725); // You must hide first
}
else if (m.Skills[SkillName.Hiding].Base < HidingRequirement)
{
m.SendLocalizedMessage(502726); // You are not hidden well enough. Become better at hiding.
m.RevealingAction();
}
else if (!m.CanBeginAction(typeof(Stealth)))
{
m.SendLocalizedMessage(1063086); // You cannot use this skill right now.
m.RevealingAction();
}
else
{
int armorRating = GetArmorRating(m);
if ( armorRating >= (Core.AOS ? 42 : 26) ) //I have a hunch '42' was chosen cause someone's a fan of DNA
{
m.SendLocalizedMessage( 502727 ); // You could not hope to move quietly wearing this much armor.
m.RevealingAction();
}
else if ( m.CheckSkill( SkillName.Stealth, -20.0 + (armorRating * 2), (Core.AOS ? 60.0 : 80.0) + (armorRating * 2) ) )
{
int steps = (int)(m.Skills[SkillName.Stealth].Value / (Core.AOS ? 5.0 : 10.0));
if (armorRating >= (Core.AOS ? 42 : 26)) //I have a hunch '42' was chosen cause someone's a fan of DNA
{
m.SendLocalizedMessage(502727); // You could not hope to move quietly wearing this much armor.
m.RevealingAction();
}
else if (m.CheckSkill(SkillName.Stealth, -20.0 + armorRating * 2,
(Core.AOS ? 60.0 : 80.0) + armorRating * 2))
{
int steps = (int)(m.Skills[SkillName.Stealth].Value / (Core.AOS ? 5.0 : 10.0));
if ( steps < 1 )
steps = 1;
if (steps < 1)
steps = 1;
m.AllowedStealthSteps = steps;
m.AllowedStealthSteps = steps;
PlayerMobile pm = m as PlayerMobile; // IsStealthing should be moved to Server.Mobiles
PlayerMobile pm = m as PlayerMobile; // IsStealthing should be moved to Server.Mobiles
if ( pm != null )
pm.IsStealthing = true;
if (pm != null)
pm.IsStealthing = true;
m.SendLocalizedMessage( 502730 ); // You begin to move quietly.
m.SendLocalizedMessage(502730); // You begin to move quietly.
return TimeSpan.FromSeconds( 10.0 );
}
else
{
m.SendLocalizedMessage( 502731 ); // You fail in your attempt to move unnoticed.
m.RevealingAction();
}
}
return TimeSpan.FromSeconds(10.0);
}
else
{
m.SendLocalizedMessage(502731); // You fail in your attempt to move unnoticed.
m.RevealingAction();
}
}
return TimeSpan.FromSeconds( 10.0 );
}
}
}
return TimeSpan.FromSeconds(10.0);
}
}
}

View file

@ -1,94 +1,89 @@
using System;
using Server.Targeting;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
namespace Server.SkillHandlers
{
public class TasteID
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.TasteID].Callback = OnUse;
}
public class TasteID
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.TasteID].Callback = OnUse;
}
public static TimeSpan OnUse( Mobile m )
{
m.Target = new InternalTarget();
public static TimeSpan OnUse(Mobile m)
{
m.Target = new InternalTarget();
m.SendLocalizedMessage( 502807 ); // What would you like to taste?
m.SendLocalizedMessage(502807); // What would you like to taste?
return TimeSpan.FromSeconds( 1.0 );
}
return TimeSpan.FromSeconds(1.0);
}
[PlayerVendorTarget]
private class InternalTarget : Target
{
public InternalTarget() : base ( 2, false, TargetFlags.None )
{
AllowNonlocal = true;
}
[PlayerVendorTarget]
private class InternalTarget : Target
{
public InternalTarget() : base(2, false, TargetFlags.None)
{
AllowNonlocal = true;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Mobile )
{
from.SendLocalizedMessage( 502816 ); // You feel that such an action would be inappropriate.
}
else if ( targeted is Food )
{
Food food = (Food) targeted;
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is Mobile)
{
from.SendLocalizedMessage(502816); // You feel that such an action would be inappropriate.
}
else if (targeted is Food)
{
Food food = (Food)targeted;
if ( from.CheckTargetSkill( SkillName.TasteID, food, 0, 100 ) )
{
if ( food.Poison != null )
{
food.SendLocalizedMessageTo( from, 1038284 ); // It appears to have poison smeared on it.
}
else
{
// No poison on the food
food.SendLocalizedMessageTo( from, 1010600 ); // You detect nothing unusual about this substance.
}
}
else
{
// Skill check failed
food.SendLocalizedMessageTo( from, 502823 ); // You cannot discern anything about this substance.
}
}
else if ( targeted is BasePotion )
{
BasePotion potion = (BasePotion) targeted;
if (from.CheckTargetSkill(SkillName.TasteID, food, 0, 100))
{
if (food.Poison != null)
food.SendLocalizedMessageTo(from, 1038284); // It appears to have poison smeared on it.
else
food.SendLocalizedMessageTo(from, 1010600); // You detect nothing unusual about this substance.
}
else
{
// Skill check failed
food.SendLocalizedMessageTo(from, 502823); // You cannot discern anything about this substance.
}
}
else if (targeted is BasePotion)
{
BasePotion potion = (BasePotion)targeted;
potion.SendLocalizedMessageTo( from, 502813 ); // You already know what kind of potion that is.
potion.SendLocalizedMessageTo( from, potion.LabelNumber );
}
else if ( targeted is PotionKeg )
{
PotionKeg keg = (PotionKeg) targeted;
potion.SendLocalizedMessageTo(from, 502813); // You already know what kind of potion that is.
potion.SendLocalizedMessageTo(from, potion.LabelNumber);
}
else if (targeted is PotionKeg)
{
PotionKeg keg = (PotionKeg)targeted;
if ( keg.Held <= 0 )
{
keg.SendLocalizedMessageTo( from, 502228 ); // There is nothing in the keg to taste!
}
else
{
keg.SendLocalizedMessageTo( from, 502229 ); // You are already familiar with this keg's contents.
keg.SendLocalizedMessageTo( from, keg.LabelNumber );
}
}
else
{
// The target is not food or potion or potion keg.
from.SendLocalizedMessage( 502820 ); // That's not something you can taste.
}
}
if (keg.Held <= 0)
{
keg.SendLocalizedMessageTo(from, 502228); // There is nothing in the keg to taste!
}
else
{
keg.SendLocalizedMessageTo(from, 502229); // You are already familiar with this keg's contents.
keg.SendLocalizedMessageTo(from, keg.LabelNumber);
}
}
else
{
// The target is not food or potion or potion keg.
from.SendLocalizedMessage(502820); // That's not something you can taste.
}
}
protected override void OnTargetOutOfRange( Mobile from, object targeted )
{
from.SendLocalizedMessage( 502815 ); // You are too far away to taste that.
}
}
}
protected override void OnTargetOutOfRange(Mobile from, object targeted)
{
from.SendLocalizedMessage(502815); // You are too far away to taste that.
}
}
}
}

View file

@ -2,397 +2,401 @@ using System;
using System.Collections.Generic;
using Server.Gumps;
using Server.Network;
using Server.Spells.Necromancy;
using Server.Spells;
using Server.Spells.Necromancy;
namespace Server.SkillHandlers
{
public class Tracking
{
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Tracking].Callback = OnUse;
}
public class Tracking
{
private static Dictionary<Mobile, TrackingInfo> m_Table = new Dictionary<Mobile, TrackingInfo>();
public static TimeSpan OnUse( Mobile m )
{
m.SendLocalizedMessage( 1011350 ); // What do you wish to track?
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Tracking].Callback = OnUse;
}
public static TimeSpan OnUse(Mobile m)
{
m.SendLocalizedMessage(1011350); // What do you wish to track?
m.CloseGump( typeof( TrackWhatGump ) );
m.CloseGump( typeof( TrackWhoGump ) );
m.SendGump( new TrackWhatGump( m ) );
m.CloseGump(typeof(TrackWhatGump));
m.CloseGump(typeof(TrackWhoGump));
m.SendGump(new TrackWhatGump(m));
return TimeSpan.FromSeconds(10.0); // 10 second delay before beign able to re-use a skill
}
public static void AddInfo(Mobile tracker, Mobile target)
{
TrackingInfo info = new TrackingInfo(tracker, target);
m_Table[tracker] = info;
}
public static double GetStalkingBonus(Mobile tracker, Mobile target)
{
m_Table.TryGetValue(tracker, out TrackingInfo info);
if (info == null || info.m_Target != target || info.m_Map != target.Map)
return 0.0;
int xDelta = info.m_Location.X - target.X;
int yDelta = info.m_Location.Y - target.Y;
double bonus = Math.Sqrt(xDelta * xDelta + yDelta * yDelta);
return TimeSpan.FromSeconds( 10.0 ); // 10 second delay before beign able to re-use a skill
}
m_Table.Remove(tracker); //Reset as of Pub 40, counting it as bug for Core.SE.
public class TrackingInfo
{
public Mobile m_Tracker;
public Mobile m_Target;
public Point2D m_Location;
public Map m_Map;
public TrackingInfo( Mobile tracker, Mobile target )
{
m_Tracker = tracker;
m_Target = target;
m_Location = new Point2D( target.X, target.Y );
m_Map = target.Map;
}
}
private static Dictionary<Mobile, TrackingInfo> m_Table = new Dictionary<Mobile, TrackingInfo>();
public static void AddInfo( Mobile tracker, Mobile target )
{
TrackingInfo info = new TrackingInfo( tracker, target );
m_Table[tracker] = info;
}
public static double GetStalkingBonus( Mobile tracker, Mobile target )
{
m_Table.TryGetValue( tracker, out TrackingInfo info );
if ( info == null || info.m_Target != target || info.m_Map != target.Map )
return 0.0;
int xDelta = info.m_Location.X - target.X;
int yDelta = info.m_Location.Y - target.Y;
double bonus = Math.Sqrt( (xDelta * xDelta) + (yDelta * yDelta) );
m_Table.Remove( tracker ); //Reset as of Pub 40, counting it as bug for Core.SE.
if ( Core.ML )
return Math.Min( bonus, 10 + tracker.Skills.Tracking.Value/10 );
return bonus;
}
public static void ClearTrackingInfo( Mobile tracker )
{
m_Table.Remove( tracker );
}
}
public class TrackWhatGump : Gump
{
private Mobile m_From;
private bool m_Success;
public TrackWhatGump( Mobile from ) : base( 20, 30 )
{
m_From = from;
m_Success = from.CheckSkill( SkillName.Tracking, 0.0, 21.1 );
AddPage( 0 );
AddBackground( 0, 0, 440, 135, 5054 );
AddBackground( 10, 10, 420, 75, 2620 );
AddBackground( 10, 85, 420, 25, 3000 );
AddItem( 20, 20, 9682 );
AddButton( 20, 110, 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 20, 90, 100, 20, 1018087, false, false ); // Animals
AddItem( 120, 20, 9607 );
AddButton( 120, 110, 4005, 4007, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 120, 90, 100, 20, 1018088, false, false ); // Monsters
AddItem( 220, 20, 8454 );
AddButton( 220, 110, 4005, 4007, 3, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 220, 90, 100, 20, 1018089, false, false ); // Human NPCs
AddItem( 320, 20, 8455 );
AddButton( 320, 110, 4005, 4007, 4, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 320, 90, 100, 20, 1018090, false, false ); // Players
}
public override void OnResponse( NetState state, RelayInfo info )
{
if ( info.ButtonID >= 1 && info.ButtonID <= 4 )
TrackWhoGump.DisplayTo( m_Success, m_From, info.ButtonID - 1 );
}
}
public delegate bool TrackTypeDelegate( Mobile m );
public class TrackWhoGump : Gump
{
private Mobile m_From;
private int m_Range;
private static TrackTypeDelegate[] m_Delegates = {
IsAnimal,
IsMonster,
IsHumanNPC,
IsPlayer
};
private class InternalSorter : IComparer<Mobile>
{
private Mobile m_From;
public InternalSorter( Mobile from )
{
m_From = from;
}
public int Compare( Mobile x, Mobile y )
{
if ( x == null && y == null )
return 0;
if ( x == null )
return -1;
if ( y == null )
return 1;
return m_From.GetDistanceToSqrt( x ).CompareTo( m_From.GetDistanceToSqrt( y ) );
}
}
public static void DisplayTo( bool success, Mobile from, int type )
{
if ( !success )
{
from.SendLocalizedMessage( 1018092 ); // You see no evidence of those in the area.
return;
}
Map map = from.Map;
if ( map == null )
return;
TrackTypeDelegate check = m_Delegates[type];
from.CheckSkill( SkillName.Tracking, 21.1, 100.0 ); // Passive gain
int range = 10 + (int)(from.Skills[SkillName.Tracking].Value / 10);
List<Mobile> list = new List<Mobile>();
foreach ( Mobile m in from.GetMobilesInRange( range ) )
{
// Ghosts can no longer be tracked
if ( m != from && (!Core.AOS || m.Alive) && (!m.Hidden || m.AccessLevel == AccessLevel.Player || from.AccessLevel > m.AccessLevel) && check( m ) && CheckDifficulty( from, m ) )
list.Add( m );
}
if ( list.Count > 0 )
{
list.Sort( new InternalSorter( from ) );
from.SendGump( new TrackWhoGump( from, list, range ) );
from.SendLocalizedMessage( 1018093 ); // Select the one you would like to track.
}
else
{
if ( type == 0 )
from.SendLocalizedMessage( 502991 ); // You see no evidence of animals in the area.
else if ( type == 1 )
from.SendLocalizedMessage( 502993 ); // You see no evidence of creatures in the area.
else
from.SendLocalizedMessage( 502995 ); // You see no evidence of people in the area.
}
}
// Tracking players uses tracking and detect hidden vs. hiding and stealth
private static bool CheckDifficulty( Mobile from, Mobile m )
{
if ( !Core.AOS || !m.Player )
return true;
int tracking = from.Skills[SkillName.Tracking].Fixed;
int detectHidden = from.Skills[SkillName.DetectHidden].Fixed;
if ( Core.ML && m.Race == Race.Elf )
tracking /= 2; //The 'Guide' says that it requires twice as Much tracking SKILL to track an elf. Not the total difficulty to track.
int hiding = m.Skills[SkillName.Hiding].Fixed;
int stealth = m.Skills[SkillName.Stealth].Fixed;
int divisor = hiding + stealth;
// Necromancy forms affect tracking difficulty
if ( TransformationSpellHelper.UnderTransformation( m, typeof( HorrificBeastSpell ) ) )
divisor -= 200;
else if ( TransformationSpellHelper.UnderTransformation( m, typeof( VampiricEmbraceSpell ) ) && divisor < 500 )
divisor = 500;
else if ( TransformationSpellHelper.UnderTransformation( m, typeof( WraithFormSpell ) ) && divisor <= 2000 )
divisor += 200;
int chance;
if ( divisor > 0 )
{
if ( Core.SE )
chance = 50 * (tracking * 2 + detectHidden) / divisor;
else
chance = 50 * (tracking + detectHidden + 10 * Utility.RandomMinMax( 1, 20 )) / divisor;
}
else
chance = 100;
return chance > Utility.Random( 100 );
}
private static bool IsAnimal( Mobile m )
{
return ( !m.Player && m.Body.IsAnimal );
}
private static bool IsMonster( Mobile m )
{
return ( !m.Player && m.Body.IsMonster );
}
private static bool IsHumanNPC( Mobile m )
{
return ( !m.Player && m.Body.IsHuman );
}
private static bool IsPlayer( Mobile m )
{
return m.Player;
}
private List<Mobile> m_List;
private TrackWhoGump( Mobile from, List<Mobile> list, int range ) : base( 20, 30 )
{
m_From = from;
m_List = list;
m_Range = range;
AddPage( 0 );
AddBackground( 0, 0, 440, 155, 5054 );
AddBackground( 10, 10, 420, 75, 2620 );
AddBackground( 10, 85, 420, 45, 3000 );
if ( list.Count > 4 )
{
AddBackground( 0, 155, 440, 155, 5054 );
AddBackground( 10, 165, 420, 75, 2620 );
AddBackground( 10, 240, 420, 45, 3000 );
if ( list.Count > 8 )
{
AddBackground( 0, 310, 440, 155, 5054 );
AddBackground( 10, 320, 420, 75, 2620 );
AddBackground( 10, 395, 420, 45, 3000 );
}
}
for ( int i = 0; i < list.Count && i < 12; ++i )
{
Mobile m = list[i];
AddItem( 20 + ((i % 4) * 100), 20 + ((i / 4) * 155), ShrinkTable.Lookup( m ) );
AddButton( 20 + ((i % 4) * 100), 130 + ((i / 4) * 155), 4005, 4007, i + 1, GumpButtonType.Reply, 0 );
if ( m.Name != null )
AddHtml( 20 + ((i % 4) * 100), 90 + ((i / 4) * 155), 90, 40, m.Name, false, false );
}
}
public override void OnResponse( NetState state, RelayInfo info )
{
int index = info.ButtonID - 1;
if ( index >= 0 && index < m_List.Count && index < 12 )
{
Mobile m = m_List[index];
m_From.QuestArrow = new TrackArrow( m_From, m, m_Range * 2 );
if ( Core.SE )
Tracking.AddInfo( m_From, m );
}
}
}
public class TrackArrow : QuestArrow
{
private Mobile m_From;
private Timer m_Timer;
public TrackArrow( Mobile from, Mobile target, int range ) : base( from, target )
{
m_From = from;
m_Timer = new TrackTimer( from, target, range, this );
m_Timer.Start();
}
public override void OnClick( bool rightClick )
{
if ( rightClick )
{
Tracking.ClearTrackingInfo( m_From );
m_From = null;
Stop();
}
}
public override void OnStop()
{
m_Timer.Stop();
if ( m_From != null )
{
Tracking.ClearTrackingInfo( m_From );
m_From.SendLocalizedMessage( 503177 ); // You have lost your quarry.
}
}
}
public class TrackTimer : Timer
{
private Mobile m_From, m_Target;
private int m_Range;
private int m_LastX, m_LastY;
private QuestArrow m_Arrow;
public TrackTimer( Mobile from, Mobile target, int range, QuestArrow arrow ) : base( TimeSpan.FromSeconds( 0.25 ), TimeSpan.FromSeconds( 2.5 ) )
{
m_From = from;
m_Target = target;
m_Range = range;
m_Arrow = arrow;
}
protected override void OnTick()
{
if ( !m_Arrow.Running )
{
Stop();
return;
}
if ( m_From.NetState == null || m_From.Deleted || m_Target.Deleted || m_From.Map != m_Target.Map || !m_From.InRange( m_Target, m_Range ) || ( m_Target.Hidden && m_Target.AccessLevel > m_From.AccessLevel ) )
{
m_Arrow.Stop();
Stop();
return;
}
if ( m_LastX != m_Target.X || m_LastY != m_Target.Y )
{
m_LastX = m_Target.X;
m_LastY = m_Target.Y;
m_Arrow.Update();
}
}
}
}
if (Core.ML)
return Math.Min(bonus, 10 + tracker.Skills.Tracking.Value / 10);
return bonus;
}
public static void ClearTrackingInfo(Mobile tracker)
{
m_Table.Remove(tracker);
}
public class TrackingInfo
{
public Point2D m_Location;
public Map m_Map;
public Mobile m_Target;
public Mobile m_Tracker;
public TrackingInfo(Mobile tracker, Mobile target)
{
m_Tracker = tracker;
m_Target = target;
m_Location = new Point2D(target.X, target.Y);
m_Map = target.Map;
}
}
}
public class TrackWhatGump : Gump
{
private Mobile m_From;
private bool m_Success;
public TrackWhatGump(Mobile from) : base(20, 30)
{
m_From = from;
m_Success = from.CheckSkill(SkillName.Tracking, 0.0, 21.1);
AddPage(0);
AddBackground(0, 0, 440, 135, 5054);
AddBackground(10, 10, 420, 75, 2620);
AddBackground(10, 85, 420, 25, 3000);
AddItem(20, 20, 9682);
AddButton(20, 110, 4005, 4007, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(20, 90, 100, 20, 1018087, false, false); // Animals
AddItem(120, 20, 9607);
AddButton(120, 110, 4005, 4007, 2, GumpButtonType.Reply, 0);
AddHtmlLocalized(120, 90, 100, 20, 1018088, false, false); // Monsters
AddItem(220, 20, 8454);
AddButton(220, 110, 4005, 4007, 3, GumpButtonType.Reply, 0);
AddHtmlLocalized(220, 90, 100, 20, 1018089, false, false); // Human NPCs
AddItem(320, 20, 8455);
AddButton(320, 110, 4005, 4007, 4, GumpButtonType.Reply, 0);
AddHtmlLocalized(320, 90, 100, 20, 1018090, false, false); // Players
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (info.ButtonID >= 1 && info.ButtonID <= 4)
TrackWhoGump.DisplayTo(m_Success, m_From, info.ButtonID - 1);
}
}
public delegate bool TrackTypeDelegate(Mobile m);
public class TrackWhoGump : Gump
{
private static TrackTypeDelegate[] m_Delegates =
{
IsAnimal,
IsMonster,
IsHumanNPC,
IsPlayer
};
private Mobile m_From;
private List<Mobile> m_List;
private int m_Range;
private TrackWhoGump(Mobile from, List<Mobile> list, int range) : base(20, 30)
{
m_From = from;
m_List = list;
m_Range = range;
AddPage(0);
AddBackground(0, 0, 440, 155, 5054);
AddBackground(10, 10, 420, 75, 2620);
AddBackground(10, 85, 420, 45, 3000);
if (list.Count > 4)
{
AddBackground(0, 155, 440, 155, 5054);
AddBackground(10, 165, 420, 75, 2620);
AddBackground(10, 240, 420, 45, 3000);
if (list.Count > 8)
{
AddBackground(0, 310, 440, 155, 5054);
AddBackground(10, 320, 420, 75, 2620);
AddBackground(10, 395, 420, 45, 3000);
}
}
for (int i = 0; i < list.Count && i < 12; ++i)
{
Mobile m = list[i];
AddItem(20 + i % 4 * 100, 20 + i / 4 * 155, ShrinkTable.Lookup(m));
AddButton(20 + i % 4 * 100, 130 + i / 4 * 155, 4005, 4007, i + 1, GumpButtonType.Reply, 0);
if (m.Name != null)
AddHtml(20 + i % 4 * 100, 90 + i / 4 * 155, 90, 40, m.Name, false, false);
}
}
public static void DisplayTo(bool success, Mobile from, int type)
{
if (!success)
{
from.SendLocalizedMessage(1018092); // You see no evidence of those in the area.
return;
}
Map map = from.Map;
if (map == null)
return;
TrackTypeDelegate check = m_Delegates[type];
from.CheckSkill(SkillName.Tracking, 21.1, 100.0); // Passive gain
int range = 10 + (int)(from.Skills[SkillName.Tracking].Value / 10);
List<Mobile> list = new List<Mobile>();
foreach (Mobile m in from.GetMobilesInRange(range))
// Ghosts can no longer be tracked
if (m != from && (!Core.AOS || m.Alive) &&
(!m.Hidden || m.AccessLevel == AccessLevel.Player || from.AccessLevel > m.AccessLevel) && check(m) &&
CheckDifficulty(from, m))
list.Add(m);
if (list.Count > 0)
{
list.Sort(new InternalSorter(from));
from.SendGump(new TrackWhoGump(from, list, range));
from.SendLocalizedMessage(1018093); // Select the one you would like to track.
}
else
{
if (type == 0)
from.SendLocalizedMessage(502991); // You see no evidence of animals in the area.
else if (type == 1)
from.SendLocalizedMessage(502993); // You see no evidence of creatures in the area.
else
from.SendLocalizedMessage(502995); // You see no evidence of people in the area.
}
}
// Tracking players uses tracking and detect hidden vs. hiding and stealth
private static bool CheckDifficulty(Mobile from, Mobile m)
{
if (!Core.AOS || !m.Player)
return true;
int tracking = from.Skills[SkillName.Tracking].Fixed;
int detectHidden = from.Skills[SkillName.DetectHidden].Fixed;
if (Core.ML && m.Race == Race.Elf)
tracking /= 2; //The 'Guide' says that it requires twice as Much tracking SKILL to track an elf. Not the total difficulty to track.
int hiding = m.Skills[SkillName.Hiding].Fixed;
int stealth = m.Skills[SkillName.Stealth].Fixed;
int divisor = hiding + stealth;
// Necromancy forms affect tracking difficulty
if (TransformationSpellHelper.UnderTransformation(m, typeof(HorrificBeastSpell)))
divisor -= 200;
else if (TransformationSpellHelper.UnderTransformation(m, typeof(VampiricEmbraceSpell)) && divisor < 500)
divisor = 500;
else if (TransformationSpellHelper.UnderTransformation(m, typeof(WraithFormSpell)) && divisor <= 2000)
divisor += 200;
int chance;
if (divisor > 0)
{
if (Core.SE)
chance = 50 * (tracking * 2 + detectHidden) / divisor;
else
chance = 50 * (tracking + detectHidden + 10 * Utility.RandomMinMax(1, 20)) / divisor;
}
else
{
chance = 100;
}
return chance > Utility.Random(100);
}
private static bool IsAnimal(Mobile m)
{
return !m.Player && m.Body.IsAnimal;
}
private static bool IsMonster(Mobile m)
{
return !m.Player && m.Body.IsMonster;
}
private static bool IsHumanNPC(Mobile m)
{
return !m.Player && m.Body.IsHuman;
}
private static bool IsPlayer(Mobile m)
{
return m.Player;
}
public override void OnResponse(NetState state, RelayInfo info)
{
int index = info.ButtonID - 1;
if (index >= 0 && index < m_List.Count && index < 12)
{
Mobile m = m_List[index];
m_From.QuestArrow = new TrackArrow(m_From, m, m_Range * 2);
if (Core.SE)
Tracking.AddInfo(m_From, m);
}
}
private class InternalSorter : IComparer<Mobile>
{
private Mobile m_From;
public InternalSorter(Mobile from)
{
m_From = from;
}
public int Compare(Mobile x, Mobile y)
{
if (x == null && y == null)
return 0;
if (x == null)
return -1;
if (y == null)
return 1;
return m_From.GetDistanceToSqrt(x).CompareTo(m_From.GetDistanceToSqrt(y));
}
}
}
public class TrackArrow : QuestArrow
{
private Mobile m_From;
private Timer m_Timer;
public TrackArrow(Mobile from, Mobile target, int range) : base(from, target)
{
m_From = from;
m_Timer = new TrackTimer(from, target, range, this);
m_Timer.Start();
}
public override void OnClick(bool rightClick)
{
if (rightClick)
{
Tracking.ClearTrackingInfo(m_From);
m_From = null;
Stop();
}
}
public override void OnStop()
{
m_Timer.Stop();
if (m_From != null)
{
Tracking.ClearTrackingInfo(m_From);
m_From.SendLocalizedMessage(503177); // You have lost your quarry.
}
}
}
public class TrackTimer : Timer
{
private QuestArrow m_Arrow;
private Mobile m_From, m_Target;
private int m_LastX, m_LastY;
private int m_Range;
public TrackTimer(Mobile from, Mobile target, int range, QuestArrow arrow) : base(TimeSpan.FromSeconds(0.25),
TimeSpan.FromSeconds(2.5))
{
m_From = from;
m_Target = target;
m_Range = range;
m_Arrow = arrow;
}
protected override void OnTick()
{
if (!m_Arrow.Running)
{
Stop();
return;
}
if (m_From.NetState == null || m_From.Deleted || m_Target.Deleted || m_From.Map != m_Target.Map ||
!m_From.InRange(m_Target, m_Range) || m_Target.Hidden && m_Target.AccessLevel > m_From.AccessLevel)
{
m_Arrow.Stop();
Stop();
return;
}
if (m_LastX != m_Target.X || m_LastY != m_Target.Y)
{
m_LastX = m_Target.X;
m_LastY = m_Target.Y;
m_Arrow.Update();
}
}
}
}