using System;
using Server.Accounting;
using Server.Engines.VeteranRewards;
using Server.Gumps;
using Server.Mobiles;
using Server.Multis;
using Server.Network;
using System.Linq;
using Server.Engines.Craft;
namespace Server.Items
{
public class SoulStone : Item, ISecurable
{
public override int LabelNumber
{
get
{
return 1030899;
}
}// soulstone
private int m_ActiveItemID;
private int m_InactiveItemID;
private SecureLevel m_Level;
[CommandProperty(AccessLevel.GameMaster)]
public SecureLevel Level
{
get
{
return m_Level;
}
set
{
m_Level = value;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public virtual int ActiveItemID
{
get
{
return m_ActiveItemID;
}
set
{
m_ActiveItemID = value;
if (!IsEmpty)
ItemID = m_ActiveItemID;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public virtual int InactiveItemID
{
get
{
return m_InactiveItemID;
}
set
{
m_InactiveItemID = value;
if (IsEmpty)
ItemID = m_InactiveItemID;
}
}
private string m_Account, m_LastUserName;
private DateTime m_NextUse; // TODO: unused, it's here not to break serialize/deserialize
private SkillName m_Skill;
private double m_SkillValue;
[CommandProperty(AccessLevel.GameMaster)]
public string Account
{
get
{
return m_Account;
}
set
{
m_Account = value;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public string LastUserName
{
get
{
return m_LastUserName;
}
set
{
m_LastUserName = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public SkillName Skill
{
get
{
return m_Skill;
}
set
{
m_Skill = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public double SkillValue
{
get
{
return m_SkillValue;
}
set
{
m_SkillValue = value;
if (!IsEmpty)
ItemID = m_ActiveItemID;
else
ItemID = m_InactiveItemID;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool IsEmpty
{
get
{
return m_SkillValue <= 0.0;
}
}
[Constructable]
public SoulStone()
: this(null)
{
}
[Constructable]
public SoulStone(string account)
: this(account, 0x2A93, 0x2A94)
{
}
public SoulStone(string account, int itemID)
: this(account, itemID, itemID)
{
}
public SoulStone(string account, int inactiveItemID, int activeItemID)
: base(inactiveItemID)
{
Light = LightType.Circle300;
LootType = LootType.Blessed;
m_InactiveItemID = inactiveItemID;
m_ActiveItemID = activeItemID;
m_Account = account;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (!IsEmpty)
list.Add(1070721, "#{0}\t{1:0.0}", AosSkillBonuses.GetLabel(Skill), SkillValue); // Skill stored: ~1_skillname~ ~2_skillamount~
string name = LastUserName;
if (name == null)
name = String.Format("#{0}", 1074235); // Unknown
list.Add(1041602, "{0}", name); // Owner: ~1_val~
}
private static bool CheckCombat(Mobile m, TimeSpan time)
{
for (int i = 0; i < m.Aggressed.Count; ++i)
{
AggressorInfo info = m.Aggressed[i];
if (DateTime.UtcNow - info.LastCombatTime < time)
return true;
}
return false;
}
protected virtual bool CheckUse(Mobile from)
{
DateTime now = DateTime.UtcNow;
PlayerMobile pm = from as PlayerMobile;
if (Deleted || !IsAccessibleTo(from))
{
return false;
}
else if (from.Map != Map || !from.InRange(GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
return false;
}
else if (Account != null && (!(from.Account is Account) || from.Account.Username != Account))
{
from.SendLocalizedMessage(1070714); // This is an Account Bound Soulstone, and your character is not bound to it. You cannot use this Soulstone.
return false;
}
else if (CheckCombat(from, TimeSpan.FromMinutes(2.0)))
{
from.SendLocalizedMessage(1070727); // You must wait two minutes after engaging in combat before you can use a Soulstone.
return false;
}
else if (from.Criminal)
{
from.SendLocalizedMessage(1070728); // You must wait two minutes after committing a criminal act before you can use a Soulstone.
return false;
}
else if (from.Region.GetLogoutDelay(from) > TimeSpan.Zero)
{
from.SendLocalizedMessage(1070729); // In order to use your Soulstone, you must be in a safe log-out location.
return false;
}
else if (!from.Alive)
{
from.SendLocalizedMessage(1070730); // You may not use a Soulstone while your character is dead.
return false;
}
else if (Factions.Sigil.ExistsOn(from))
{
from.SendLocalizedMessage(1070731); // You may not use a Soulstone while your character has a faction town sigil.
return false;
}
else if (from.Spell != null && from.Spell.IsCasting)
{
from.SendLocalizedMessage(1070733); // You may not use a Soulstone while your character is casting a spell.
return false;
}
else if (from.Poisoned)
{
from.SendLocalizedMessage(1070734); // You may not use a Soulstone while your character is poisoned.
return false;
}
else if (from.Paralyzed)
{
from.SendLocalizedMessage(1070735); // You may not use a Soulstone while your character is paralyzed.
return false;
}
#region Scroll of Alacrity
if (pm.AcceleratedStart > DateTime.UtcNow)
{
from.SendLocalizedMessage(1078115); // You may not use a soulstone while your character is under the effects of a Scroll of Alacrity.
return false;
}
#endregion
else
{
return true;
}
}
public virtual void OnSkillTransfered(Mobile from)
{
}
public override void OnDoubleClick(Mobile from)
{
if (!CheckUse(from))
return;
from.CloseGump(typeof(SelectSkillGump));
from.CloseGump(typeof(ConfirmSkillGump));
from.CloseGump(typeof(ConfirmTransferGump));
from.CloseGump(typeof(ConfirmRemovalGump));
from.CloseGump(typeof(ErrorGump));
if (IsEmpty)
from.SendGump(new SelectSkillGump(this, from));
else
from.SendGump(new ConfirmTransferGump(this, from));
}
private class SelectSkillGump : Gump
{
private readonly SoulStone m_Stone;
public SelectSkillGump(SoulStone stone, Mobile from)
: base(50, 50)
{
m_Stone = stone;
AddPage(0);
AddBackground(0, 0, 520, 440, 0x13BE);
AddImageTiled(10, 10, 500, 20, 0xA40);
AddImageTiled(10, 40, 500, 360, 0xA40);
AddImageTiled(10, 410, 500, 20, 0xA40);
AddAlphaRegion(10, 10, 500, 420);
AddHtmlLocalized(10, 12, 500, 20, 1061087, 0x7FFF, false, false); // Which skill do you wish to transfer to the Soulstone?
AddButton(10, 410, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 412, 450, 20, 1060051, 0x7FFF, false, false); // CANCEL
for (int i = 0, n = 0; i < from.Skills.Length; i++)
{
Skill skill = from.Skills[i];
if (skill.Base > 0.0)
{
int p = n % 30;
if (p == 0)
{
int page = n / 30;
if (page > 0)
{
AddButton(260, 380, 0xFA5, 0xFA6, 0, GumpButtonType.Page, page + 1);
AddHtmlLocalized(305, 382, 200, 20, 1011066, 0x7FFF, false, false); // Next page
}
AddPage(page + 1);
if (page > 0)
{
AddButton(10, 380, 0xFAE, 0xFAF, 0, GumpButtonType.Page, page);
AddHtmlLocalized(55, 382, 200, 20, 1011067, 0x7FFF, false, false); // Previous page
}
}
int x = (p % 2 == 0) ? 10 : 260;
int y = (p / 2) * 20 + 40;
AddButton(x, y, 0xFA5, 0xFA6, i + 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(x + 45, y + 2, 200, 20, AosSkillBonuses.GetLabel(skill.SkillName), 0x7FFF, false, false);
n++;
}
}
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 0 || !m_Stone.IsEmpty)
return;
Mobile from = sender.Mobile;
int iSkill = info.ButtonID - 1;
if (iSkill < 0 || iSkill >= from.Skills.Length)
return;
Skill skill = from.Skills[iSkill];
if (skill.Base <= 0.0)
return;
if (!m_Stone.CheckUse(from))
return;
from.SendGump(new ConfirmSkillGump(m_Stone, skill));
}
}
private class ConfirmSkillGump : Gump
{
private readonly SoulStone m_Stone;
private readonly Skill m_Skill;
public ConfirmSkillGump(SoulStone stone, Skill skill)
: base(50, 50)
{
m_Stone = stone;
m_Skill = skill;
AddBackground(0, 0, 520, 440, 0x13BE);
AddImageTiled(10, 10, 500, 20, 0xA40);
AddImageTiled(10, 40, 500, 360, 0xA40);
AddImageTiled(10, 410, 500, 20, 0xA40);
AddAlphaRegion(10, 10, 500, 420);
AddHtmlLocalized(10, 12, 500, 20, 1070709, 0x7FFF, false, false); //
Confirm Soulstone Transfer
/* Soulstone
* You are using a Soulstone. This powerful artifact allows you to remove skill points
* from your character and store them in the stone for later retrieval. In order to use
* the stone, you must make sure your Skill Lock for the indicated skill is pointed downward.
* Click the "Skills" button on your Paperdoll to access the Skill List, and double-check
* your skill lock.
*
* Once you activate the stone, all skill points in the indicated skill will be removed from
* your character. These skill points can later be retrieved. IMPORTANT: When retrieving
* skill points from a Soulstone, the Soulstone WILL REPLACE any existing skill points
* already on your character!
*
* This is an Account Bound Soulstone. Skill pointsstored inside can be retrieved by any
* character on the same account as the character who placed them into the stone.
*/
AddHtmlLocalized(10, 42, 500, 110, 1061067, 0x7FFF, false, true);
AddHtmlLocalized(10, 200, 390, 20, 1062297, 0x7FFF, false, false); // Skill Chosen:
AddHtmlLocalized(210, 200, 390, 20, AosSkillBonuses.GetLabel(skill.SkillName), 0x7FFF, false, false);
AddHtmlLocalized(10, 220, 390, 20, 1062298, 0x7FFF, false, false); // Current Value:
AddLabel(210, 220, 0x481, skill.Base.ToString("0.0"));
AddHtmlLocalized(10, 240, 390, 20, 1062299, 0x7FFF, false, false); // Current Cap:
AddLabel(210, 240, 0x481, skill.Cap.ToString("0.0"));
AddHtmlLocalized(10, 260, 390, 20, 1062300, 0x7FFF, false, false); // New Value:
AddLabel(210, 260, 0x481, "0.0");
AddButton(10, 360, 0xFA5, 0xFA6, 2, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 362, 450, 20, 1070720, 0x7FFF, false, false); // Activate the stone. I am ready to transfer the skill points to it.
AddButton(10, 380, 0xFA5, 0xFA6, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 382, 450, 20, 1062279, 0x7FFF, false, false); // No, let me make another selection.
AddButton(10, 410, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 412, 450, 20, 1060051, 0x7FFF, false, false); // CANCEL
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 0 || !m_Stone.IsEmpty)
return;
Mobile from = sender.Mobile;
if (!m_Stone.CheckUse(from))
return;
if (info.ButtonID == 1) // Is asking for another selection
{
from.SendGump(new SelectSkillGump(m_Stone, from));
return;
}
if (m_Skill.Base <= 0.0)
return;
if (m_Skill.Lock != SkillLock.Down)
{
// Unable to Transfer Selected Skill to Soulstone
/* You cannot transfer the selected skill to the Soulstone at this time. The selected
* skill may be locked or set to raise in your skill menu. Click on "Skills" in your
* paperdoll menu to check your raise/locked/lower settings and your total skills.
* Make any needed adjustments, then click "Continue". If you do not wish to transfer
* the selected skill at this time, click "Cancel".
*/
from.SendGump(new ErrorGump(m_Stone, 1070710, 1070711));
return;
}
m_Stone.Skill = m_Skill.SkillName;
m_Stone.SkillValue = m_Skill.Base;
m_Skill.Base = 0.0;
CheckSkill(from);
from.SendLocalizedMessage(1070712); // You have successfully transferred your skill points into the Soulstone.
m_Stone.LastUserName = from.Name;
Effects.SendLocationParticles(EffectItem.Create(from.Location, from.Map, EffectItem.DefaultDuration), 0, 0, 0, 0, 0, 5060, 0);
Effects.PlaySound(from.Location, from.Map, 0x243);
Effects.SendMovingParticles(new Entity(Server.Serial.Zero, new Point3D(from.X - 6, from.Y - 6, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
Effects.SendTargetParticles(from, 0x375A, 35, 90, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
m_Stone.OnSkillTransfered(from);
}
private void CheckSkill(Mobile from)
{
if (m_Skill.SkillName == SkillName.AnimalTaming)
{
PlayerMobile owner = from as PlayerMobile;
if (owner != null && owner.AllFollowers != null && owner.AllFollowers.Count > 0)
{
foreach (BaseCreature bc in owner.AllFollowers.OfType())
{
if (bc.CheckControlChance(owner))
{
bc.ControlTarget = null;
bc.ControlOrder = OrderType.None;
if (bc is BaseMount && ((BaseMount)bc).Rider == from)
{
from.SendLocalizedMessage(1042317); // You may not ride at this time
((BaseMount)bc).Rider = null;
}
}
}
}
}
}
}
private class ConfirmTransferGump : Gump
{
private readonly SoulStone m_Stone;
public ConfirmTransferGump(SoulStone stone, Mobile from)
: base(50, 50)
{
m_Stone = stone;
AddBackground(0, 0, 520, 440, 0x13BE);
AddImageTiled(10, 10, 500, 20, 0xA40);
AddImageTiled(10, 40, 500, 360, 0xA40);
AddImageTiled(10, 410, 500, 20, 0xA40);
AddAlphaRegion(10, 10, 500, 420);
AddHtmlLocalized(10, 12, 500, 20, 1070709, 0x7FFF, false, false); // Confirm Soulstone Transfer
/* Soulstone
* You are using a Soulstone. This powerful artifact allows you to remove skill points
* from your character and store them in the stone for later retrieval. In order to use
* the stone, you must make sure your Skill Lock for the indicated skill is pointed downward.
* Click the "Skills" button on your Paperdoll to access the Skill List, and double-check
* your skill lock.
*
* Once you activate the stone, all skill points in the indicated skill will be removed from
* your character. These skill points can later be retrieved. IMPORTANT: When retrieving
* skill points from a Soulstone, the Soulstone WILL REPLACE any existing skill points
* already on your character!
*
* This is an Account Bound Soulstone. Skill pointsstored inside can be retrieved by any
* character on the same account as the character who placed them into the stone.
*/
AddHtmlLocalized(10, 42, 500, 110, 1061067, 0x7FFF, false, true);
AddHtmlLocalized(10, 200, 390, 20, 1070718, 0x7FFF, false, false); // Skill Stored:
AddHtmlLocalized(210, 200, 390, 20, AosSkillBonuses.GetLabel(stone.Skill), 0x7FFF, false, false);
Skill fromSkill = from.Skills[stone.Skill];
AddHtmlLocalized(10, 220, 390, 20, 1062298, 0x7FFF, false, false); // Current Value:
AddLabel(210, 220, 0x481, fromSkill.Base.ToString("0.0"));
AddHtmlLocalized(10, 240, 390, 20, 1062299, 0x7FFF, false, false); // Current Cap:
AddLabel(210, 240, 0x481, fromSkill.Cap.ToString("0.0"));
AddHtmlLocalized(10, 260, 390, 20, 1062300, 0x7FFF, false, false); // New Value:
AddLabel(210, 260, 0x481, stone.SkillValue.ToString("0.0"));
AddButton(10, 360, 0xFA5, 0xFA6, 2, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 362, 450, 20, 1070719, 0x7FFF, false, false); // Activate the stone. I am ready to retrieve the skill points from it.
AddButton(10, 380, 0xFA5, 0xFA6, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 382, 450, 20, 1070723, 0x7FFF, false, false); // Remove all skill points from this stone and DO NOT absorb them.
AddButton(10, 410, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 412, 450, 20, 1060051, 0x7FFF, false, false); // CANCEL
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 0 || m_Stone.IsEmpty)
return;
Mobile from = sender.Mobile;
if (!m_Stone.CheckUse(from))
return;
if (info.ButtonID == 1) // Remove skill points
{
from.SendGump(new ConfirmRemovalGump(m_Stone));
return;
}
SkillName skill = m_Stone.Skill;
double skillValue = m_Stone.SkillValue;
Skill fromSkill = from.Skills[m_Stone.Skill];
/* If we have, say, 88.4 in our skill and the stone holds 100, we need
* 11.6 free points. Also, if we're below our skillcap by, say, 8.2 points,
* we only need 11.6 - 8.2 = 3.4 points.
*/
int requiredAmount = (int)(skillValue * 10) - fromSkill.BaseFixedPoint - (from.SkillsCap - from.SkillsTotal);
bool cannotAbsorb = false;
if (fromSkill.Lock != SkillLock.Up)
{
cannotAbsorb = true;
}
else if (requiredAmount > 0)
{
int available = 0;
for (int i = 0; i < from.Skills.Length; ++i)
{
if (from.Skills[i].Lock != SkillLock.Down)
continue;
available += from.Skills[i].BaseFixedPoint;
}
if (requiredAmount > available)
cannotAbsorb = true;
}
if (cannotAbsorb)
{
// Unable to Absorb Selected Skill from Soulstone
/* You cannot absorb the selected skill from the Soulstone at this time. The selected
* skill may be locked or set to lower in your skill menu. You may also be at your
* total skill cap. Click on "Skills" in your paperdoll menu to check your
* raise/locked/lower settings and your total skills. Make any needed adjustments,
* then click "Continue". If you do not wish to transfer the selected skill at this
* time, click "Cancel".
*/
from.SendGump(new ErrorGump(m_Stone, 1070717, 1070716));
return;
}
if (skillValue > fromSkill.Cap)
{
// Unable to Absorb Selected Skill from Soulstone
/* The amount of skill stored in this stone exceeds your individual skill cap for
* that skill. In order to retrieve the skill points stored in this stone, you must
* obtain a Power Scroll of the appropriate type and level in order to increase your
* skill cap. You cannot currently retrieve the skill points stored in this stone.
*/
from.SendGump(new ErrorGump(m_Stone, 1070717, 1070715));
return;
}
if (fromSkill.Base >= skillValue)
{
// Unable to Absorb Selected Skill from Soulstone
/* You cannot transfer the selected skill to the Soulstone at this time. The selected
* skill has a skill level higher than what is stored in the Soulstone.
*/
// Wrong message?!
from.SendGump(new ErrorGump(m_Stone, 1070717, 1070802));
return;
}
#region Scroll of ALacrity
PlayerMobile pm = from as PlayerMobile;
if (pm.AcceleratedStart > DateTime.UtcNow)
{
// Unable to Absorb Selected Skill from Soulstone
/*You may not use a soulstone while your character is under the effects of a Scroll of Alacrity.*/
// Wrong message?!
from.SendGump(new ErrorGump(m_Stone, 1070717, 1078115));
return;
}
#endregion
if (requiredAmount > 0)
{
for (int i = 0; i < from.Skills.Length; ++i)
{
if (from.Skills[i].Lock != SkillLock.Down)
continue;
if (requiredAmount >= from.Skills[i].BaseFixedPoint)
{
requiredAmount -= from.Skills[i].BaseFixedPoint;
from.Skills[i].Base = 0.0;
}
else
{
from.Skills[i].BaseFixedPoint -= requiredAmount;
break;
}
}
}
fromSkill.Base = skillValue;
m_Stone.SkillValue = 0.0;
from.SendLocalizedMessage(1070713); // You have successfully absorbed the Soulstone's skill points.
m_Stone.LastUserName = from.Name;
Effects.SendLocationParticles(EffectItem.Create(from.Location, from.Map, EffectItem.DefaultDuration), 0, 0, 0, 0, 0, 5060, 0);
Effects.PlaySound(from.Location, from.Map, 0x243);
Effects.SendMovingParticles(new Entity(Server.Serial.Zero, new Point3D(from.X - 6, from.Y - 6, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
Effects.SendTargetParticles(from, 0x375A, 35, 90, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
if (m_Stone is SoulstoneFragment)
{
SoulstoneFragment frag = m_Stone as SoulstoneFragment;
if (--frag.UsesRemaining <= 0)
from.SendLocalizedMessage(1070974); // You have used up your soulstone fragment.
}
}
}
private class ConfirmRemovalGump : Gump
{
private readonly SoulStone m_Stone;
public ConfirmRemovalGump(SoulStone stone)
: base(50, 50)
{
m_Stone = stone;
AddBackground(0, 0, 520, 440, 0x13BE);
AddImageTiled(10, 10, 500, 20, 0xA40);
AddImageTiled(10, 40, 500, 360, 0xA40);
AddImageTiled(10, 410, 500, 20, 0xA40);
AddAlphaRegion(10, 10, 500, 420);
AddHtmlLocalized(10, 12, 500, 20, 1070725, 0x7FFF, false, false); // Confirm Soulstone Skill Removal
/* WARNING!
*
* You are about to permanently remove all skill points stored in this Soulstone.
* You WILL NOT absorb these skill points. They will be DELETED.
*
* Are you sure you wish to do this? If not, press the Cancel button.
*/
AddHtmlLocalized(10, 42, 500, 110, 1070724, 0x7FFF, false, true);
AddButton(10, 380, 0xFA5, 0xFA6, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 382, 450, 20, 1052072, 0x7FFF, false, false); // Continue
AddButton(10, 410, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 412, 450, 20, 1060051, 0x7FFF, false, false); // CANCEL
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 0 || m_Stone.IsEmpty)
return;
Mobile from = sender.Mobile;
if (!m_Stone.CheckUse(from))
return;
m_Stone.SkillValue = 0.0;
from.SendLocalizedMessage(1070726); // You have successfully deleted the Soulstone's skill points.
}
}
private class ErrorGump : Gump
{
private readonly SoulStone m_Stone;
public ErrorGump(SoulStone stone, int title, int message)
: base(50, 50)
{
m_Stone = stone;
AddBackground(0, 0, 520, 440, 0x13BE);
AddImageTiled(10, 10, 500, 20, 0xA40);
AddImageTiled(10, 40, 500, 360, 0xA40);
AddImageTiled(10, 410, 500, 20, 0xA40);
AddAlphaRegion(10, 10, 500, 420);
AddHtmlLocalized(10, 12, 500, 20, title, 0x7FFF, false, false);
AddHtmlLocalized(10, 42, 500, 110, message, 0x7FFF, false, true);
AddButton(10, 380, 0xFA5, 0xFA6, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 382, 450, 20, 1052072, 0x7FFF, false, false); // Continue
AddButton(10, 410, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 412, 450, 20, 1060051, 0x7FFF, false, false); // CANCEL
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 0)
return;
Mobile from = sender.Mobile;
if (!m_Stone.CheckUse(from))
return;
if (m_Stone.IsEmpty)
from.SendGump(new SelectSkillGump(m_Stone, from));
else
from.SendGump(new ConfirmTransferGump(m_Stone, from));
}
}
public SoulStone(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(3); // version
//version 3
writer.Write((string)m_LastUserName);
//version 2
writer.Write((int)m_Level);
writer.Write(m_ActiveItemID);
writer.Write(m_InactiveItemID);
writer.Write((string)m_Account);
writer.Write((DateTime)m_NextUse); //TODO: delete it in a harmless way
writer.WriteEncodedInt((int)m_Skill);
writer.Write((double)m_SkillValue);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
switch( version )
{
case 3:
{
m_LastUserName = reader.ReadString();
goto case 2;
}
case 2:
{
m_Level = (SecureLevel)reader.ReadInt();
goto case 1;
}
case 1:
{
m_ActiveItemID = reader.ReadInt();
m_InactiveItemID = reader.ReadInt();
goto case 0;
}
case 0:
{
m_Account = reader.ReadString();
m_NextUse = reader.ReadDateTime(); //TODO: delete it in a harmless way
m_Skill = (SkillName)reader.ReadEncodedInt();
m_SkillValue = reader.ReadDouble();
break;
}
}
if (version == 0)
{
m_ActiveItemID = 0x2A94;
m_InactiveItemID = 0x2A93;
}
}
}
public class SoulstoneFragment : SoulStone, IUsesRemaining, ICraftable
{
private int m_UsesRemaining;
public override int LabelNumber
{
get
{
return 1071000;
}
}// soulstone fragment
[Constructable]
public SoulstoneFragment()
: this(5, null)
{
}
[Constructable]
public SoulstoneFragment(int usesRemaining)
: this(usesRemaining, null)
{
}
[Constructable]
public SoulstoneFragment(string account)
: this(5, account)
{
}
[Constructable]
public SoulstoneFragment(int usesRemaining, string account)
: base(account, Utility.Random(0x2AA1, 9))
{
m_UsesRemaining = usesRemaining;
}
public override void AddUsesRemainingProperties(ObjectPropertyList list)
{
list.Add(1060584, m_UsesRemaining.ToString()); // uses remaining: ~1_val~
}
[CommandProperty(AccessLevel.GameMaster)]
public int UsesRemaining
{
get
{
return m_UsesRemaining;
}
set
{
m_UsesRemaining = value;
InvalidateProperties();
}
}
public override void OnSkillTransfered(Mobile from)
{
if (String.IsNullOrEmpty(Account))
{
Account = from.Account.Username;
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(2); // version
writer.WriteEncodedInt(m_UsesRemaining);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
m_UsesRemaining = reader.ReadEncodedInt();
if (version <= 1)
{
if (ItemID == 0x2A93 || ItemID == 0x2A94)
{
ActiveItemID = Utility.Random(0x2AA1, 9);
}
else
{
ActiveItemID = ItemID;
}
InactiveItemID = ActiveItemID;
}
if (version == 0 && Weight == 1)
Weight = -1;
}
public SoulstoneFragment(Serial serial)
: base(serial)
{
}
protected override bool CheckUse(Mobile from)
{
bool canUse = base.CheckUse(from);
if (canUse)
{
if (m_UsesRemaining <= 0)
{
from.SendLocalizedMessage(1070975); // That soulstone fragment has no more uses.
return false;
}
}
return canUse;
}
public bool ShowUsesRemaining
{
get
{
return true;
}
set
{
}
}
public int OnCraft(int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, ITool tool, CraftItem craftItem, int resHue)
{
UsesRemaining = 1;
Hue = 1150;
return quality;
}
}
[Flipable]
public class BlueSoulstone : SoulStone
{
[Constructable]
public BlueSoulstone()
: this(null)
{
}
[Constructable]
public BlueSoulstone(string account)
: base(account, 0x2ADC, 0x2ADD)
{
}
public BlueSoulstone(Serial serial)
: base(serial)
{
}
public void Flip()
{
switch( ItemID )
{
case 0x2ADC:
ItemID = 0x2AEC;
break;
case 0x2ADD:
ItemID = 0x2AED;
break;
case 0x2AEC:
ItemID = 0x2ADC;
break;
case 0x2AED:
ItemID = 0x2ADD;
break;
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class RedSoulstone : SoulStone, IRewardItem
{
[Constructable]
public RedSoulstone()
: this(null)
{
}
[Constructable]
public RedSoulstone(string account)
: base(account, 0x32F3, 0x32F4)
{
}
public RedSoulstone(Serial serial)
: base(serial)
{
}
private bool m_IsRewardItem;
[CommandProperty(AccessLevel.GameMaster)]
public bool IsRewardItem
{
get
{
return m_IsRewardItem;
}
set
{
m_IsRewardItem = value;
InvalidateProperties();
}
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (m_IsRewardItem)
list.Add(1076217); // 1st Year Veteran Reward
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1); // version
writer.Write((bool)m_IsRewardItem);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 1:
{
m_IsRewardItem = reader.ReadBool();
break;
}
}
}
}
public class VioletSoulstone : SoulStone
{
[Constructable]
public VioletSoulstone()
: this(null)
{
}
[Constructable]
public VioletSoulstone(string account)
: base(account)
{
Hue = 2598;
}
public VioletSoulstone(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}