fix: Fixes special scrolls (#1373)
This commit is contained in:
parent
7635db4834
commit
e797ec7f53
12 changed files with 804 additions and 918 deletions
|
|
@ -127,10 +127,8 @@ namespace Server.Items
|
|||
|
||||
if (!IsEmpty)
|
||||
{
|
||||
list.Add(
|
||||
1070721, // Skill stored: ~1_skillname~ ~2_skillamount~
|
||||
$"{AosSkillBonuses.GetLabel(Skill):#}\t{SkillValue:F1}"
|
||||
);
|
||||
// Skill stored: ~1_skillname~ ~2_skillamount~
|
||||
list.Add(1070721, $"{AosSkillBonuses.GetLabel(Skill):#}\t{SkillValue:F1}");
|
||||
}
|
||||
|
||||
if (LastUserName != null)
|
||||
|
|
|
|||
|
|
@ -1,326 +1,318 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using ModernUO.Serialization;
|
||||
|
||||
namespace Server.Items
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class PowerScroll : SpecialScroll
|
||||
{
|
||||
public class PowerScroll : SpecialScroll
|
||||
private static readonly SkillName[] _preAosSkills =
|
||||
{
|
||||
private static readonly SkillName[] m_Skills =
|
||||
SkillName.Blacksmith,
|
||||
SkillName.Tailoring,
|
||||
SkillName.Swords,
|
||||
SkillName.Fencing,
|
||||
SkillName.Macing,
|
||||
SkillName.Archery,
|
||||
SkillName.Wrestling,
|
||||
SkillName.Parry,
|
||||
SkillName.Tactics,
|
||||
SkillName.Anatomy,
|
||||
SkillName.Healing,
|
||||
SkillName.Magery,
|
||||
SkillName.Meditation,
|
||||
SkillName.EvalInt,
|
||||
SkillName.MagicResist,
|
||||
SkillName.AnimalTaming,
|
||||
SkillName.AnimalLore,
|
||||
SkillName.Veterinary,
|
||||
SkillName.Musicianship,
|
||||
SkillName.Provocation,
|
||||
SkillName.Discordance,
|
||||
SkillName.Peacemaking
|
||||
};
|
||||
|
||||
private static readonly SkillName[] _aosSkills =
|
||||
{
|
||||
SkillName.Chivalry,
|
||||
SkillName.Focus,
|
||||
SkillName.Necromancy,
|
||||
SkillName.Stealing,
|
||||
SkillName.Stealth,
|
||||
SkillName.SpiritSpeak
|
||||
};
|
||||
|
||||
private static readonly SkillName[] _seSkills =
|
||||
{
|
||||
SkillName.Ninjitsu,
|
||||
SkillName.Bushido
|
||||
};
|
||||
|
||||
private static readonly SkillName[] _mlSkills =
|
||||
{
|
||||
SkillName.Spellweaving
|
||||
};
|
||||
|
||||
/*
|
||||
private static SkillName[] _saSkills = new SkillName[]
|
||||
{
|
||||
SkillName.Throwing,
|
||||
SkillName.Mysticism,
|
||||
SkillName.Imbuing
|
||||
};
|
||||
|
||||
private static SkillName[] _hsSkills = new SkillName[]
|
||||
{
|
||||
SkillName.Fishing
|
||||
};
|
||||
*/
|
||||
|
||||
private static SkillName[] _skills;
|
||||
|
||||
[Constructible]
|
||||
public PowerScroll(SkillName skill = SkillName.Alchemy, double value = 0.0) : base(skill, value)
|
||||
{
|
||||
Hue = 0x481;
|
||||
|
||||
if (Value == 105.0 || skill is SkillName.Blacksmith or SkillName.Tailoring)
|
||||
{
|
||||
SkillName.Blacksmith,
|
||||
SkillName.Tailoring,
|
||||
SkillName.Swords,
|
||||
SkillName.Fencing,
|
||||
SkillName.Macing,
|
||||
SkillName.Archery,
|
||||
SkillName.Wrestling,
|
||||
SkillName.Parry,
|
||||
SkillName.Tactics,
|
||||
SkillName.Anatomy,
|
||||
SkillName.Healing,
|
||||
SkillName.Magery,
|
||||
SkillName.Meditation,
|
||||
SkillName.EvalInt,
|
||||
SkillName.MagicResist,
|
||||
SkillName.AnimalTaming,
|
||||
SkillName.AnimalLore,
|
||||
SkillName.Veterinary,
|
||||
SkillName.Musicianship,
|
||||
SkillName.Provocation,
|
||||
SkillName.Discordance,
|
||||
SkillName.Peacemaking
|
||||
};
|
||||
|
||||
private static readonly SkillName[] m_AOSSkills =
|
||||
{
|
||||
SkillName.Chivalry,
|
||||
SkillName.Focus,
|
||||
SkillName.Necromancy,
|
||||
SkillName.Stealing,
|
||||
SkillName.Stealth,
|
||||
SkillName.SpiritSpeak
|
||||
};
|
||||
|
||||
private static readonly SkillName[] m_SESkills =
|
||||
{
|
||||
SkillName.Ninjitsu,
|
||||
SkillName.Bushido
|
||||
};
|
||||
|
||||
private static readonly SkillName[] m_MLSkills =
|
||||
{
|
||||
SkillName.Spellweaving
|
||||
};
|
||||
|
||||
/*
|
||||
private static SkillName[] m_SASkills = new SkillName[]
|
||||
{
|
||||
SkillName.Throwing,
|
||||
SkillName.Mysticism,
|
||||
SkillName.Imbuing
|
||||
};
|
||||
|
||||
private static SkillName[] m_HSSkills = new SkillName[]
|
||||
{
|
||||
SkillName.Fishing
|
||||
};
|
||||
*/
|
||||
|
||||
private static readonly List<SkillName> _Skills = new();
|
||||
|
||||
[Constructible]
|
||||
public PowerScroll(SkillName skill = SkillName.Alchemy, double value = 0.0) : base(skill, value)
|
||||
{
|
||||
Hue = 0x481;
|
||||
|
||||
if (Value == 105.0 || skill is SkillName.Blacksmith or SkillName.Tailoring)
|
||||
{
|
||||
LootType = LootType.Regular;
|
||||
}
|
||||
}
|
||||
|
||||
public PowerScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
/* Using a scroll increases the maximum amount of a specific skill or your maximum statistics.
|
||||
* When used, the effect is not immediately seen without a gain of points with that skill or statistics.
|
||||
* You can view your maximum skill values in your skills window.
|
||||
* You can view your maximum statistic value in your statistics window.
|
||||
*/
|
||||
public override int Message =>
|
||||
1049469;
|
||||
|
||||
public override int Title
|
||||
{
|
||||
get
|
||||
{
|
||||
var level = (Value - 105.0) / 5.0;
|
||||
|
||||
/* Wonderous Scroll (105 Skill): OR
|
||||
* Exalted Scroll (110 Skill): OR
|
||||
* Mythical Scroll (115 Skill): OR
|
||||
* Legendary Scroll (120 Skill):
|
||||
*/
|
||||
if (level >= 0.0 && level <= 3.0 && Value % 5.0 == 0.0)
|
||||
{
|
||||
return 1049635 + (int)level;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override string DefaultTitle => $"<basefont color=#FFFFFF>Power Scroll ({Value} Skill):</basefont>";
|
||||
|
||||
public static List<SkillName> Skills
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_Skills.Count == 0)
|
||||
{
|
||||
_Skills.AddRange(m_Skills);
|
||||
if (Core.AOS)
|
||||
{
|
||||
_Skills.AddRange(m_AOSSkills);
|
||||
if (Core.SE)
|
||||
{
|
||||
_Skills.AddRange(m_SESkills);
|
||||
if (Core.ML)
|
||||
{
|
||||
_Skills.AddRange(m_MLSkills);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _Skills;
|
||||
}
|
||||
}
|
||||
|
||||
public static PowerScroll CreateRandom(int min, int max)
|
||||
{
|
||||
min /= 5;
|
||||
max /= 5;
|
||||
|
||||
return new PowerScroll(Skills.RandomElement(), 100 + Utility.RandomMinMax(min, max) * 5);
|
||||
}
|
||||
|
||||
public static PowerScroll CreateRandomNoCraft(int min, int max)
|
||||
{
|
||||
min /= 5;
|
||||
max /= 5;
|
||||
|
||||
SkillName skillName;
|
||||
|
||||
do
|
||||
{
|
||||
skillName = Skills.RandomElement();
|
||||
} while (skillName is SkillName.Blacksmith or SkillName.Tailoring);
|
||||
|
||||
return new PowerScroll(skillName, 100 + Utility.RandomMinMax(min, max) * 5);
|
||||
}
|
||||
|
||||
public override void AddNameProperty(IPropertyList list)
|
||||
{
|
||||
var level = (Value - 105.0) / 5.0;
|
||||
|
||||
if (level >= 0.0 && level <= 3.0 && Value % 5.0 == 0.0)
|
||||
/* a wonderous scroll of ~1_type~ (105 Skill) OR
|
||||
* an exalted scroll of ~1_type~ (110 Skill) OR
|
||||
* a mythical scroll of ~1_type~ (115 Skill) OR
|
||||
* a legendary scroll of ~1_type~ (120 Skill)
|
||||
*/
|
||||
{
|
||||
list.Add(1049639 + (int)level, GetNameLocalized());
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add($"a power scroll of {GetName()} ({Value} Skill)");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
var level = (Value - 105.0) / 5.0;
|
||||
|
||||
if (level >= 0.0 && level <= 3.0 && Value % 5.0 == 0.0)
|
||||
{
|
||||
LabelTo(from, 1049639 + (int)level, GetNameLocalized());
|
||||
}
|
||||
else
|
||||
{
|
||||
LabelTo(from, $"a power scroll of {GetName()} ({Value} Skill)");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
{
|
||||
if (!base.CanUse(from))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var skill = from.Skills[Skill];
|
||||
|
||||
if (skill == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (skill.Cap >= Value)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1049511,
|
||||
GetNameLocalized()
|
||||
); // Your ~1_type~ is too high for this power scroll.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Use(Mobile from)
|
||||
{
|
||||
if (!CanUse(from))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(
|
||||
1049513,
|
||||
GetNameLocalized()
|
||||
); // You feel a surge of magic as the scroll enhances your ~1_type~!
|
||||
|
||||
from.Skills[Skill].Cap = Value;
|
||||
|
||||
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(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.SendMovingParticles(
|
||||
new Entity(Serial.Zero, new Point3D(from.X - 4, from.Y - 6, from.Z + 15), from.Map),
|
||||
from,
|
||||
0x36D4,
|
||||
7,
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
0x497,
|
||||
0,
|
||||
9502,
|
||||
1,
|
||||
0,
|
||||
(EffectLayer)255,
|
||||
0x100
|
||||
);
|
||||
Effects.SendMovingParticles(
|
||||
new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 4, 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);
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = InheritsItem ? 0 : reader.ReadInt(); // Required for SpecialScroll insertion
|
||||
|
||||
if (Value == 105.0 || Skill is SkillName.Blacksmith or SkillName.Tailoring)
|
||||
{
|
||||
LootType = LootType.Regular;
|
||||
}
|
||||
else
|
||||
{
|
||||
LootType = LootType.Cursed;
|
||||
Insured = false;
|
||||
}
|
||||
LootType = LootType.Regular;
|
||||
}
|
||||
}
|
||||
|
||||
/* Using a scroll increases the maximum amount of a specific skill or your maximum statistics.
|
||||
* When used, the effect is not immediately seen without a gain of points with that skill or statistics.
|
||||
* You can view your maximum skill values in your skills window.
|
||||
* You can view your maximum statistic value in your statistics window.
|
||||
*/
|
||||
public override int Message => 1049469;
|
||||
|
||||
public override int Title
|
||||
{
|
||||
get
|
||||
{
|
||||
var level = (Value - 105.0) / 5.0;
|
||||
|
||||
/* Wondrous Scroll (105 Skill): OR
|
||||
* Exalted Scroll (110 Skill): OR
|
||||
* Mythical Scroll (115 Skill): OR
|
||||
* Legendary Scroll (120 Skill):
|
||||
*/
|
||||
if (level is >= 0.0 and <= 3.0 && Value % 5.0 == 0.0)
|
||||
{
|
||||
return 1049635 + (int)level;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override string DefaultTitle => $"<basefont color=#FFFFFF>Power Scroll ({Value} Skill):</basefont>";
|
||||
|
||||
public static SkillName[] Skills
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_skills == null)
|
||||
{
|
||||
var totalSkills = _preAosSkills.Length;
|
||||
if (Core.AOS)
|
||||
{
|
||||
totalSkills += _aosSkills.Length;
|
||||
}
|
||||
|
||||
if (Core.SE)
|
||||
{
|
||||
totalSkills += _seSkills.Length;
|
||||
}
|
||||
|
||||
if (Core.ML)
|
||||
{
|
||||
totalSkills += _mlSkills.Length;
|
||||
}
|
||||
|
||||
_skills = new SkillName[totalSkills];
|
||||
Array.Copy(_preAosSkills, 0, _skills, 0, _preAosSkills.Length);
|
||||
int pos = 0;
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
pos = _preAosSkills.Length;
|
||||
Array.Copy(_aosSkills, 0, _skills, pos, _aosSkills.Length);
|
||||
}
|
||||
|
||||
if (Core.SE)
|
||||
{
|
||||
pos += _aosSkills.Length;
|
||||
Array.Copy(_seSkills, 0, _skills, pos, _seSkills.Length);
|
||||
}
|
||||
|
||||
if (Core.ML)
|
||||
{
|
||||
pos += _seSkills.Length;
|
||||
Array.Copy(_mlSkills, 0, _skills, pos, _mlSkills.Length);
|
||||
}
|
||||
}
|
||||
|
||||
return _skills;
|
||||
}
|
||||
}
|
||||
|
||||
public static PowerScroll CreateRandom(int min, int max)
|
||||
{
|
||||
min /= 5;
|
||||
max /= 5;
|
||||
|
||||
return new PowerScroll(Skills.RandomElement(), 100 + Utility.RandomMinMax(min, max) * 5);
|
||||
}
|
||||
|
||||
public static PowerScroll CreateRandomNoCraft(int min, int max)
|
||||
{
|
||||
min /= 5;
|
||||
max /= 5;
|
||||
|
||||
SkillName skillName;
|
||||
|
||||
do
|
||||
{
|
||||
skillName = Skills.RandomElement();
|
||||
} while (skillName is SkillName.Blacksmith or SkillName.Tailoring);
|
||||
|
||||
return new PowerScroll(skillName, 100 + Utility.RandomMinMax(min, max) * 5);
|
||||
}
|
||||
|
||||
public override void AddNameProperty(IPropertyList list)
|
||||
{
|
||||
var level = (Value - 105.0) / 5.0;
|
||||
|
||||
if (level is >= 0.0 and <= 3.0 && Value % 5.0 == 0.0)
|
||||
{
|
||||
/* a wondrous scroll of ~1_type~ (105 Skill) OR
|
||||
* an exalted scroll of ~1_type~ (110 Skill) OR
|
||||
* a mythical scroll of ~1_type~ (115 Skill) OR
|
||||
* a legendary scroll of ~1_type~ (120 Skill)
|
||||
*/
|
||||
list.Add(1049639 + (int)level, AosSkillBonuses.GetLabel(Skill));
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add($"a power scroll of {GetName()} ({Value} Skill)");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
var level = (Value - 105.0) / 5.0;
|
||||
|
||||
if (level is >= 0.0 and <= 3.0 && Value % 5.0 == 0.0)
|
||||
{
|
||||
LabelTo(from, 1049639 + (int)level, GetNameLocalized());
|
||||
}
|
||||
else
|
||||
{
|
||||
LabelTo(from, $"a power scroll of {GetName()} ({Value} Skill)");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
{
|
||||
if (!base.CanUse(from))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var skill = from.Skills[Skill];
|
||||
|
||||
if (skill == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (skill.Cap >= Value)
|
||||
{
|
||||
// Your ~1_type~ is too high for this power scroll.
|
||||
from.SendLocalizedMessage(1049511, GetNameLocalized());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Use(Mobile from)
|
||||
{
|
||||
if (!CanUse(from))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// You feel a surge of magic as the scroll enhances your ~1_type~!
|
||||
from.SendLocalizedMessage(1049513, GetNameLocalized());
|
||||
|
||||
from.Skills[Skill].Cap = Value;
|
||||
|
||||
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(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.SendMovingParticles(
|
||||
new Entity(Serial.Zero, new Point3D(from.X - 4, from.Y - 6, from.Z + 15), from.Map),
|
||||
from,
|
||||
0x36D4,
|
||||
7,
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
0x497,
|
||||
0,
|
||||
9502,
|
||||
1,
|
||||
0,
|
||||
(EffectLayer)255,
|
||||
0x100
|
||||
);
|
||||
Effects.SendMovingParticles(
|
||||
new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 4, 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);
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,133 +1,111 @@
|
|||
using System;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Engines.MLQuests;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class ScrollofAlacrity : SpecialScroll
|
||||
{
|
||||
public class ScrollofAlacrity : SpecialScroll
|
||||
[Constructible]
|
||||
public ScrollofAlacrity(SkillName skill = SkillName.Alchemy) : base(skill, 0.0)
|
||||
{
|
||||
[Constructible]
|
||||
public ScrollofAlacrity(SkillName skill = SkillName.Alchemy) : base(skill, 0.0)
|
||||
ItemID = 0x14EF;
|
||||
Hue = 0x4AB;
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1078604; // Scroll of Alacrity
|
||||
|
||||
/* Using a Scroll of Transcendence for a given skill will permanently increase your current
|
||||
* level in that skill by the amount of points displayed on the scroll.
|
||||
* As you may not gain skills beyond your maximum skill cap, any excess points will be lost.
|
||||
*/
|
||||
public override int Message => 1078602;
|
||||
|
||||
public override string DefaultTitle => "<basefont color=#FFFFFF>Scroll of Alacrity:</basefont>";
|
||||
|
||||
public override void GetProperties(IPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(1071345, GetName()); // Skill: ~1_val~
|
||||
list.Add(1071346, 15); // Duration: ~1_val~ minutes
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
{
|
||||
if (!(base.CanUse(from) && from is PlayerMobile pm))
|
||||
{
|
||||
ItemID = 0x14EF;
|
||||
Hue = 0x4AB;
|
||||
return false;
|
||||
}
|
||||
|
||||
public ScrollofAlacrity(Serial serial) : base(serial)
|
||||
var context = MLQuestSystem.GetContext(pm);
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1078604; // Scroll of Alacrity
|
||||
|
||||
/* Using a Scroll of Transcendence for a given skill will permanently increase your current
|
||||
* level in that skill by the amount of points displayed on the scroll.
|
||||
* As you may not gain skills beyond your maximum skill cap, any excess points will be lost.
|
||||
*/
|
||||
public override int Message =>
|
||||
1078602;
|
||||
|
||||
public override string DefaultTitle => "<basefont color=#FFFFFF>Scroll of Alacrity:</basefont>";
|
||||
|
||||
public override void GetProperties(IPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(1071345, $"{GetName()} 15 Minutes"); // Skill: ~1_val~
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
{
|
||||
if (!(base.CanUse(from) && from is PlayerMobile pm))
|
||||
foreach (var instance in context.QuestInstances)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var context = MLQuestSystem.GetContext(pm);
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
foreach (var instance in context.QuestInstances)
|
||||
foreach (var objective in instance.Objectives)
|
||||
{
|
||||
foreach (var objective in instance.Objectives)
|
||||
if (!objective.Expired && objective is GainSkillObjectiveInstance objectiveInstance &&
|
||||
objectiveInstance.Handles(Skill))
|
||||
{
|
||||
if (!objective.Expired && objective is GainSkillObjectiveInstance objectiveInstance &&
|
||||
objectiveInstance.Handles(Skill))
|
||||
{
|
||||
from.SendMessage("You are already under the effect of an enhanced skillgain quest.");
|
||||
return false;
|
||||
}
|
||||
from.SendMessage("You are already under the effect of an enhanced skillgain quest.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pm.AcceleratedStart > Core.Now)
|
||||
{
|
||||
from.SendLocalizedMessage(1077951); // You are already under the effect of an accelerated skillgain scroll.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Use(Mobile from)
|
||||
if (pm.AcceleratedStart > Core.Now)
|
||||
{
|
||||
if (!(CanUse(from) && from is PlayerMobile pm))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tskill = from.Skills[Skill].Base;
|
||||
var tcap = from.Skills[Skill].Cap;
|
||||
|
||||
if (tskill >= tcap || from.Skills[Skill].Lock != SkillLock.Up)
|
||||
{
|
||||
/* You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu.
|
||||
* If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap.
|
||||
*/
|
||||
from.SendLocalizedMessage(1094935);
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(
|
||||
1077956
|
||||
); // You are infused with intense energy. You are under the effects of an accelerated skillgain scroll.
|
||||
|
||||
Effects.PlaySound(from.Location, from.Map, 0x1E9);
|
||||
Effects.SendTargetParticles(from, 0x373A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
|
||||
|
||||
pm.AcceleratedStart = Core.Now + TimeSpan.FromMinutes(15);
|
||||
Timer.StartTimer(TimeSpan.FromMinutes(15), () => Expire_Callback(from));
|
||||
|
||||
pm.AcceleratedSkill = Skill;
|
||||
|
||||
Delete();
|
||||
from.SendLocalizedMessage(1077951); // You are already under the effect of an accelerated skillgain scroll.
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Handle this upon deserialization. Create Dictionary and serialize Mobile/Timers?
|
||||
private static void Expire_Callback(Mobile m)
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Use(Mobile from)
|
||||
{
|
||||
if (!(CanUse(from) && from is PlayerMobile pm))
|
||||
{
|
||||
m.PlaySound(0x1F8);
|
||||
m.SendLocalizedMessage(
|
||||
1077957
|
||||
); // The intense energy dissipates. You are no longer under the effects of an accelerated skillgain scroll.
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
var tskill = from.Skills[Skill].Base;
|
||||
var tcap = from.Skills[Skill].Cap;
|
||||
|
||||
if (tskill >= tcap || from.Skills[Skill].Lock != SkillLock.Up)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
/* You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu.
|
||||
* If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap.
|
||||
*/
|
||||
from.SendLocalizedMessage(1094935);
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
// You are infused with intense energy. You are under the effects of an accelerated skillgain scroll.
|
||||
from.SendLocalizedMessage(1077956);
|
||||
|
||||
var version = InheritsItem ? 0 : reader.ReadInt(); // Required for SpecialScroll insertion
|
||||
Effects.PlaySound(from.Location, from.Map, 0x1E9);
|
||||
Effects.SendTargetParticles(from, 0x373A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
|
||||
|
||||
LootType = LootType.Cursed;
|
||||
Insured = false;
|
||||
}
|
||||
pm.AcceleratedStart = Core.Now + TimeSpan.FromMinutes(15);
|
||||
Timer.StartTimer(TimeSpan.FromMinutes(15), () => Expire_Callback(from));
|
||||
|
||||
pm.AcceleratedSkill = Skill;
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
// TODO: Handle this upon deserialization. Create Dictionary and serialize Mobile/Timers?
|
||||
private static void Expire_Callback(Mobile m)
|
||||
{
|
||||
m.PlaySound(0x1F8);
|
||||
// The intense energy dissipates. You are no longer under the effects of an accelerated skillgain scroll.
|
||||
m.SendLocalizedMessage(1077957);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,163 +1,133 @@
|
|||
using ModernUO.Serialization;
|
||||
using Server.Engines.MLQuests;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class ScrollofTranscendence : SpecialScroll
|
||||
{
|
||||
public class ScrollofTranscendence : SpecialScroll
|
||||
[Constructible]
|
||||
public ScrollofTranscendence(SkillName skill = SkillName.Alchemy, double value = 0.0) : base(skill, value)
|
||||
{
|
||||
[Constructible]
|
||||
public ScrollofTranscendence(SkillName skill = SkillName.Alchemy, double value = 0.0) : base(skill, value)
|
||||
ItemID = 0x14EF;
|
||||
Hue = 0x490;
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1094934; // Scroll of Transcendence
|
||||
|
||||
/* Using a Scroll of Transcendence for a given skill will permanently increase your current
|
||||
* level in that skill by the amount of points displayed on the scroll.
|
||||
* As you may not gain skills beyond your maximum skill cap, any excess points will be lost.
|
||||
*/
|
||||
public override int Message => 1094933;
|
||||
|
||||
public override string DefaultTitle =>
|
||||
$"<basefont color=#FFFFFF>Scroll of Transcendence ({Value} Skill):</basefont>";
|
||||
|
||||
public static ScrollofTranscendence CreateRandom(int min, int max) =>
|
||||
new(Utility.RandomSkill(), Utility.RandomMinMax(min, max) * 0.1);
|
||||
|
||||
public override void GetProperties(IPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
list.Add(1076759, $"{GetName()}\t{Value:0.#} Skill Points");
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
{
|
||||
if (!(base.CanUse(from) && from is PlayerMobile pm))
|
||||
{
|
||||
ItemID = 0x14EF;
|
||||
Hue = 0x490;
|
||||
return false;
|
||||
}
|
||||
|
||||
public ScrollofTranscendence(Serial serial) : base(serial)
|
||||
var context = MLQuestSystem.GetContext(pm);
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1094934; // Scroll of Transcendence
|
||||
|
||||
/* Using a Scroll of Transcendence for a given skill will permanently increase your current
|
||||
* level in that skill by the amount of points displayed on the scroll.
|
||||
* As you may not gain skills beyond your maximum skill cap, any excess points will be lost.
|
||||
*/
|
||||
public override int Message =>
|
||||
1094933;
|
||||
|
||||
public override string DefaultTitle =>
|
||||
$"<basefont color=#FFFFFF>Scroll of Transcendence ({Value} Skill):</basefont>";
|
||||
|
||||
public static ScrollofTranscendence CreateRandom(int min, int max) =>
|
||||
new(Utility.RandomSkill(), Utility.RandomMinMax(min, max) * 0.1);
|
||||
|
||||
public override void GetProperties(IPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
list.Add(1076759, $"{GetName()}\t{Value:0.#} Skill Points");
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
{
|
||||
if (!(base.CanUse(from) && from is PlayerMobile pm))
|
||||
foreach (var instance in context.QuestInstances)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var context = MLQuestSystem.GetContext(pm);
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
foreach (var instance in context.QuestInstances)
|
||||
foreach (var objective in instance.Objectives)
|
||||
{
|
||||
foreach (var objective in instance.Objectives)
|
||||
if (!objective.Expired && objective is GainSkillObjectiveInstance objectiveInstance &&
|
||||
objectiveInstance.Handles(Skill))
|
||||
{
|
||||
if (!objective.Expired && objective is GainSkillObjectiveInstance objectiveInstance &&
|
||||
objectiveInstance.Handles(Skill))
|
||||
{
|
||||
from.SendMessage("You are already under the effect of an enhanced skillgain quest.");
|
||||
return false;
|
||||
}
|
||||
from.SendMessage("You are already under the effect of an enhanced skillgain quest.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pm.AcceleratedStart > Core.Now)
|
||||
{
|
||||
from.SendLocalizedMessage(1077951); // You are already under the effect of an accelerated skillgain scroll.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Use(Mobile from)
|
||||
if (pm.AcceleratedStart > Core.Now)
|
||||
{
|
||||
if (!CanUse(from))
|
||||
from.SendLocalizedMessage(1077951); // You are already under the effect of an accelerated skillgain scroll.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Use(Mobile from)
|
||||
{
|
||||
if (!CanUse(from))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tskill = from.Skills[Skill].Base; // value of skill without item bonuses etc
|
||||
var tcap = from.Skills[Skill].Cap; // maximum value permitted
|
||||
var canGain = false;
|
||||
|
||||
var newValue = Value;
|
||||
|
||||
if (tskill + newValue > tcap)
|
||||
{
|
||||
newValue = tcap - tskill;
|
||||
}
|
||||
|
||||
if (tskill < tcap && from.Skills[Skill].Lock == SkillLock.Up)
|
||||
{
|
||||
if (from.SkillsTotal + newValue * 10 > from.SkillsCap)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var ns = from.Skills.Length; // number of items in from.Skills[]
|
||||
|
||||
var tskill = from.Skills[Skill].Base; // value of skill without item bonuses etc
|
||||
var tcap = from.Skills[Skill].Cap; // maximum value permitted
|
||||
var canGain = false;
|
||||
|
||||
var newValue = Value;
|
||||
|
||||
if (tskill + newValue > tcap)
|
||||
{
|
||||
newValue = tcap - tskill;
|
||||
}
|
||||
|
||||
if (tskill < tcap && from.Skills[Skill].Lock == SkillLock.Up)
|
||||
{
|
||||
if (from.SkillsTotal + newValue * 10 > from.SkillsCap)
|
||||
for (var i = 0; i < ns; i++)
|
||||
{
|
||||
var ns = from.Skills.Length; // number of items in from.Skills[]
|
||||
|
||||
for (var i = 0; i < ns; i++)
|
||||
// skill must point down and its value must be enough
|
||||
// skill must point down and its value must be enough
|
||||
if (from.Skills[i].Lock == SkillLock.Down && from.Skills[i].Base >= newValue)
|
||||
{
|
||||
if (from.Skills[i].Lock == SkillLock.Down && from.Skills[i].Base >= newValue)
|
||||
{
|
||||
from.Skills[i].Base -= newValue;
|
||||
canGain = true;
|
||||
break;
|
||||
}
|
||||
from.Skills[i].Base -= newValue;
|
||||
canGain = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
canGain = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!canGain)
|
||||
else
|
||||
{
|
||||
/* You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu.
|
||||
* If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap.
|
||||
*/
|
||||
from.SendLocalizedMessage(
|
||||
1094935
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(
|
||||
1049513,
|
||||
GetNameLocalized()
|
||||
); // You feel a surge of magic as the scroll enhances your ~1_type~!
|
||||
|
||||
from.Skills[Skill].Base += newValue;
|
||||
|
||||
Effects.PlaySound(from.Location, from.Map, 0x1F7);
|
||||
Effects.SendTargetParticles(from, 0x373A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
|
||||
Effects.SendTargetParticles(from, 0x376A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = InheritsItem ? 0 : reader.ReadInt(); // Required for SpecialScroll insertion
|
||||
|
||||
LootType = LootType.Cursed;
|
||||
Insured = false;
|
||||
|
||||
if (Hue == 0x7E)
|
||||
{
|
||||
Hue = 0x490;
|
||||
canGain = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!canGain)
|
||||
{
|
||||
/* You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu.
|
||||
* If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap.
|
||||
*/
|
||||
from.SendLocalizedMessage(1094935);
|
||||
return;
|
||||
}
|
||||
|
||||
// You feel a surge of magic as the scroll enhances your ~1_type~!
|
||||
from.SendLocalizedMessage(1049513, GetNameLocalized());
|
||||
|
||||
from.Skills[Skill].Base += newValue;
|
||||
|
||||
Effects.PlaySound(from.Location, from.Map, 0x1F7);
|
||||
Effects.SendTargetParticles(from, 0x373A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
|
||||
Effects.SendTargetParticles(from, 0x376A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,190 +1,124 @@
|
|||
using ModernUO.Serialization;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(0, false)]
|
||||
public abstract partial class SpecialScroll : Item
|
||||
{
|
||||
public abstract class SpecialScroll : Item
|
||||
[SerializableField(0)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private SkillName _skill;
|
||||
|
||||
[SerializableField(1)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private double _value;
|
||||
|
||||
public SpecialScroll(SkillName skill, double value) : base(0x14F0)
|
||||
{
|
||||
public SpecialScroll(SkillName skill, double value) : base(0x14F0)
|
||||
{
|
||||
LootType = LootType.Cursed;
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Cursed;
|
||||
Weight = 1.0;
|
||||
|
||||
Skill = skill;
|
||||
Value = value;
|
||||
_skill = skill;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public abstract int Message { get; }
|
||||
public virtual int Title => 0;
|
||||
public abstract string DefaultTitle { get; }
|
||||
|
||||
public virtual string GetNameLocalized() => $"#{AosSkillBonuses.GetLabel(Skill)}";
|
||||
|
||||
public virtual string GetName()
|
||||
{
|
||||
var index = (int)Skill;
|
||||
var table = SkillInfo.Table;
|
||||
|
||||
if (index >= 0 && index < table.Length)
|
||||
{
|
||||
return table[index].Name.ToLower();
|
||||
}
|
||||
|
||||
public SpecialScroll(Serial serial) : base(serial)
|
||||
return "???";
|
||||
}
|
||||
|
||||
public virtual bool CanUse(Mobile from)
|
||||
{
|
||||
if (Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* DO NOT USE! Only used in serialization of special scrolls that originally derived from Item */
|
||||
|
||||
protected bool InheritsItem { get; private set; }
|
||||
|
||||
public abstract int Message { get; }
|
||||
public virtual int Title => 0;
|
||||
public abstract string DefaultTitle { get; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SkillName Skill { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public double Value { get; set; }
|
||||
|
||||
public virtual string GetNameLocalized() => $"#{AosSkillBonuses.GetLabel(Skill)}";
|
||||
|
||||
public virtual string GetName()
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
var index = (int)Skill;
|
||||
var table = SkillInfo.Table;
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index >= 0 && index < table.Length)
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Use(Mobile from)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!CanUse(from))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
from.CloseGump<InternalGump>();
|
||||
from.SendGump(new InternalGump(from, this));
|
||||
}
|
||||
|
||||
public class InternalGump : Gump
|
||||
{
|
||||
private readonly Mobile _mobile;
|
||||
private readonly SpecialScroll _scroll;
|
||||
|
||||
public InternalGump(Mobile mobile, SpecialScroll scroll) : base(25, 50)
|
||||
{
|
||||
_mobile = mobile;
|
||||
_scroll = scroll;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(25, 10, 420, 200, 5054);
|
||||
|
||||
AddImageTiled(33, 20, 401, 181, 2624);
|
||||
AddAlphaRegion(33, 20, 401, 181);
|
||||
|
||||
AddHtmlLocalized(40, 48, 387, 100, _scroll.Message, true, true);
|
||||
|
||||
AddHtmlLocalized(125, 148, 200, 20, 1049478, 0xFFFFFF); // Do you wish to use this scroll?
|
||||
|
||||
AddButton(100, 172, 4005, 4007, 1);
|
||||
AddHtmlLocalized(135, 172, 120, 20, 1046362, 0xFFFFFF); // Yes
|
||||
|
||||
AddButton(275, 172, 4005, 4007, 0);
|
||||
AddHtmlLocalized(310, 172, 120, 20, 1046363, 0xFFFFFF); // No
|
||||
|
||||
if (_scroll.Title != 0)
|
||||
{
|
||||
return table[index].Name.ToLower();
|
||||
AddHtmlLocalized(40, 20, 260, 20, _scroll.Title, 0xFFFFFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtml(40, 20, 260, 20, _scroll.DefaultTitle);
|
||||
}
|
||||
|
||||
return "???";
|
||||
var skillLabel = _scroll is StatCapScroll ? 1038019 : AosSkillBonuses.GetLabel(_scroll.Skill);
|
||||
AddHtmlLocalized(310, 20, 120, 20, skillLabel, 0xFFFFFF); // Power
|
||||
}
|
||||
|
||||
public virtual bool CanUse(Mobile from)
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (Deleted)
|
||||
if (info.ButtonID == 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Use(Mobile from)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!CanUse(from))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
from.CloseGump<InternalGump>();
|
||||
from.SendGump(new InternalGump(from, this));
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write((int)Skill);
|
||||
writer.Write(Value);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Skill = (SkillName)reader.ReadInt();
|
||||
Value = reader.ReadDouble();
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
InheritsItem = true;
|
||||
|
||||
if (this is not StatCapScroll)
|
||||
{
|
||||
Skill = (SkillName)reader.ReadInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
Skill = SkillName.Alchemy;
|
||||
}
|
||||
|
||||
if (this is ScrollofAlacrity)
|
||||
{
|
||||
Value = 0.0;
|
||||
}
|
||||
else if (this is StatCapScroll)
|
||||
{
|
||||
Value = reader.ReadInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = reader.ReadDouble();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalGump : Gump
|
||||
{
|
||||
private readonly Mobile m_Mobile;
|
||||
private readonly SpecialScroll m_Scroll;
|
||||
|
||||
public InternalGump(Mobile mobile, SpecialScroll scroll) : base(25, 50)
|
||||
{
|
||||
m_Mobile = mobile;
|
||||
m_Scroll = scroll;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(25, 10, 420, 200, 5054);
|
||||
|
||||
AddImageTiled(33, 20, 401, 181, 2624);
|
||||
AddAlphaRegion(33, 20, 401, 181);
|
||||
|
||||
AddHtmlLocalized(40, 48, 387, 100, m_Scroll.Message, true, true);
|
||||
|
||||
AddHtmlLocalized(125, 148, 200, 20, 1049478, 0xFFFFFF); // Do you wish to use this scroll?
|
||||
|
||||
AddButton(100, 172, 4005, 4007, 1);
|
||||
AddHtmlLocalized(135, 172, 120, 20, 1046362, 0xFFFFFF); // Yes
|
||||
|
||||
AddButton(275, 172, 4005, 4007, 0);
|
||||
AddHtmlLocalized(310, 172, 120, 20, 1046363, 0xFFFFFF); // No
|
||||
|
||||
if (m_Scroll.Title != 0)
|
||||
{
|
||||
AddHtmlLocalized(40, 20, 260, 20, m_Scroll.Title, 0xFFFFFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtml(40, 20, 260, 20, m_Scroll.DefaultTitle);
|
||||
}
|
||||
|
||||
if (m_Scroll is StatCapScroll)
|
||||
{
|
||||
AddHtmlLocalized(310, 20, 120, 20, 1038019, 0xFFFFFF); // Power
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtmlLocalized(310, 20, 120, 20, AosSkillBonuses.GetLabel(m_Scroll.Skill), 0xFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1)
|
||||
{
|
||||
m_Scroll.Use(m_Mobile);
|
||||
}
|
||||
_scroll.Use(_mobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,206 +1,185 @@
|
|||
using ModernUO.Serialization;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class StatCapScroll : SpecialScroll
|
||||
{
|
||||
public class StatCapScroll : SpecialScroll
|
||||
[Constructible]
|
||||
public StatCapScroll(int value = 105) : base(SkillName.Alchemy, value) => Hue = 0x481;
|
||||
|
||||
/* Using a scroll increases the maximum amount of a specific skill or your maximum statistics.
|
||||
* When used, the effect is not immediately seen without a gain of points with that skill or statistics.
|
||||
* You can view your maximum skill values in your skills window.
|
||||
* You can view your maximum statistic value in your statistics window.
|
||||
*/
|
||||
public override int Message => 1049469;
|
||||
|
||||
public override int Title
|
||||
{
|
||||
[Constructible]
|
||||
public StatCapScroll(int value = 105) : base(SkillName.Alchemy, value) => Hue = 0x481;
|
||||
|
||||
public StatCapScroll(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
/* Using a scroll increases the maximum amount of a specific skill or your maximum statistics.
|
||||
* When used, the effect is not immediately seen without a gain of points with that skill or statistics.
|
||||
* You can view your maximum skill values in your skills window.
|
||||
* You can view your maximum statistic value in your statistics window.
|
||||
*/
|
||||
public override int Message =>
|
||||
1049469;
|
||||
|
||||
public override int Title
|
||||
{
|
||||
get
|
||||
{
|
||||
var level = ((int)Value - 230) / 5;
|
||||
|
||||
/* Wonderous Scroll (+5 Maximum Stats): OR
|
||||
* Exalted Scroll (+10 Maximum Stats): OR
|
||||
* Mythical Scroll (+15 Maximum Stats): OR
|
||||
* Legendary Scroll (+20 Maximum Stats): OR
|
||||
* Ultimate Scroll (+25 Maximum Stats):
|
||||
*/
|
||||
if (level >= 0 && level <= 4 && Value % 5 == 0)
|
||||
{
|
||||
return 1049458 + level;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override string DefaultTitle =>
|
||||
$"<basefont color=#FFFFFF>Power Scroll ({((int)Value - 225 >= 0 ? "+" : "")}{(int)Value - 225} Maximum Stats):</basefont>";
|
||||
|
||||
public override void AddNameProperty(IPropertyList list)
|
||||
get
|
||||
{
|
||||
var level = ((int)Value - 230) / 5;
|
||||
|
||||
if (level >= 0 && level <= 4 && (int)Value % 5 == 0)
|
||||
/* a wonderous scroll of ~1_type~ (+5 Maximum Stats) OR
|
||||
* an exalted scroll of ~1_type~ (+10 Maximum Stats) OR
|
||||
* a mythical scroll of ~1_type~ (+15 Maximum Stats) OR
|
||||
* a legendary scroll of ~1_type~ (+20 Maximum Stats) OR
|
||||
* an ultimate scroll of ~1_type~ (+25 Maximum Stats)
|
||||
*/
|
||||
/* Wondrous Scroll (+5 Maximum Stats): OR
|
||||
* Exalted Scroll (+10 Maximum Stats): OR
|
||||
* Mythical Scroll (+15 Maximum Stats): OR
|
||||
* Legendary Scroll (+20 Maximum Stats): OR
|
||||
* Ultimate Scroll (+25 Maximum Stats):
|
||||
*/
|
||||
if (level is >= 0 and <= 4 && Value % 5 == 0)
|
||||
{
|
||||
list.Add(1049463 + level, "#1049476");
|
||||
}
|
||||
else
|
||||
{
|
||||
var diff = Value - 225;
|
||||
list.Add($"a scroll of power ({(diff >= 0 ? "+" : "")}{diff} Maximum Stats)");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
var level = ((int)Value - 230) / 5;
|
||||
|
||||
if (level >= 0 && level <= 4 && (int)Value % 5 == 0)
|
||||
{
|
||||
LabelTo(from, 1049463 + level, "#1049476");
|
||||
}
|
||||
else
|
||||
{
|
||||
var diff = Value - 225;
|
||||
LabelTo(from, $"a scroll of power ({(diff >= 0 ? "+" : "")}{diff} Maximum Stats)");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
{
|
||||
if (!base.CanUse(from))
|
||||
{
|
||||
return false;
|
||||
return 1049458 + level;
|
||||
}
|
||||
|
||||
var newValue = (int)Value;
|
||||
|
||||
if (from is PlayerMobile mobile && mobile.HasStatReward)
|
||||
{
|
||||
newValue += 5;
|
||||
}
|
||||
|
||||
if (from.StatCap >= newValue)
|
||||
{
|
||||
from.SendLocalizedMessage(1049510); // Your stats are too high for this power scroll.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Use(Mobile from)
|
||||
{
|
||||
if (!CanUse(from))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(1049512); // You feel a surge of magic as the scroll enhances your powers!
|
||||
|
||||
if (from is PlayerMobile mobile && mobile.HasStatReward)
|
||||
{
|
||||
mobile.StatCap = (int)Value + 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.StatCap = (int)Value;
|
||||
}
|
||||
|
||||
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(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.SendMovingParticles(
|
||||
new Entity(Serial.Zero, new Point3D(from.X - 4, from.Y - 6, from.Z + 15), from.Map),
|
||||
from,
|
||||
0x36D4,
|
||||
7,
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
0x497,
|
||||
0,
|
||||
9502,
|
||||
1,
|
||||
0,
|
||||
(EffectLayer)255,
|
||||
0x100
|
||||
);
|
||||
Effects.SendMovingParticles(
|
||||
new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 4, 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);
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = InheritsItem ? 0 : reader.ReadInt(); // Required for SpecialScroll insertion
|
||||
|
||||
LootType = LootType.Cursed;
|
||||
Insured = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override string DefaultTitle =>
|
||||
$"<basefont color=#FFFFFF>Power Scroll ({((int)Value - 225 >= 0 ? "+" : "")}{(int)Value - 225} Maximum Stats):</basefont>";
|
||||
|
||||
public override void AddNameProperty(IPropertyList list)
|
||||
{
|
||||
var level = ((int)Value - 230) / 5;
|
||||
|
||||
if (level is >= 0 and <= 4 && (int)Value % 5 == 0)
|
||||
{
|
||||
/* a wondrous scroll of ~1_type~ (+5 Maximum Stats) OR
|
||||
* an exalted scroll of ~1_type~ (+10 Maximum Stats) OR
|
||||
* a mythical scroll of ~1_type~ (+15 Maximum Stats) OR
|
||||
* a legendary scroll of ~1_type~ (+20 Maximum Stats) OR
|
||||
* an ultimate scroll of ~1_type~ (+25 Maximum Stats)
|
||||
*/
|
||||
list.Add(1049463 + level, 1049476);
|
||||
}
|
||||
else
|
||||
{
|
||||
var diff = Value - 225;
|
||||
list.Add($"a scroll of power ({(diff >= 0 ? "+" : "")}{diff} Maximum Stats)");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
var level = ((int)Value - 230) / 5;
|
||||
|
||||
if (level is >= 0 and <= 4 && (int)Value % 5 == 0)
|
||||
{
|
||||
LabelTo(from, 1049463 + level, "#1049476");
|
||||
}
|
||||
else
|
||||
{
|
||||
var diff = Value - 225;
|
||||
LabelTo(from, $"a scroll of power ({(diff >= 0 ? "+" : "")}{diff} Maximum Stats)");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
{
|
||||
if (!base.CanUse(from))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var newValue = (int)Value;
|
||||
|
||||
if (from is PlayerMobile { HasStatReward: true })
|
||||
{
|
||||
newValue += 5;
|
||||
}
|
||||
|
||||
if (from.StatCap >= newValue)
|
||||
{
|
||||
from.SendLocalizedMessage(1049510); // Your stats are too high for this power scroll.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Use(Mobile from)
|
||||
{
|
||||
if (!CanUse(from))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(1049512); // You feel a surge of magic as the scroll enhances your powers!
|
||||
|
||||
if (from is PlayerMobile { HasStatReward: true } mobile)
|
||||
{
|
||||
mobile.StatCap = (int)Value + 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.StatCap = (int)Value;
|
||||
}
|
||||
|
||||
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(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.SendMovingParticles(
|
||||
new Entity(Serial.Zero, new Point3D(from.X - 4, from.Y - 6, from.Z + 15), from.Map),
|
||||
from,
|
||||
0x36D4,
|
||||
7,
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
0x497,
|
||||
0,
|
||||
9502,
|
||||
1,
|
||||
0,
|
||||
(EffectLayer)255,
|
||||
0x100
|
||||
);
|
||||
Effects.SendMovingParticles(
|
||||
new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 4, 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);
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
4
Projects/UOContent/Migrations/Server.Items.PowerScroll.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Items.PowerScroll.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.PowerScroll"
|
||||
}
|
||||
4
Projects/UOContent/Migrations/Server.Items.ScrollofAlacrity.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Items.ScrollofAlacrity.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.ScrollofAlacrity"
|
||||
}
|
||||
4
Projects/UOContent/Migrations/Server.Items.ScrollofTranscendence.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Items.ScrollofTranscendence.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.ScrollofTranscendence"
|
||||
}
|
||||
19
Projects/UOContent/Migrations/Server.Items.SpecialScroll.v0.json
generated
Normal file
19
Projects/UOContent/Migrations/Server.Items.SpecialScroll.v0.json
generated
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.SpecialScroll",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Skill",
|
||||
"type": "Server.SkillName",
|
||||
"rule": "EnumMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Value",
|
||||
"type": "double",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
4
Projects/UOContent/Migrations/Server.Items.StatCapScroll.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Items.StatCapScroll.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.StatCapScroll"
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ namespace Server.Misc
|
|||
|
||||
// The new AOS bankboxes don't have powerscrolls, they are automatically 'applied':
|
||||
|
||||
for (var i = 0; i < PowerScroll.Skills.Count; ++i)
|
||||
for (var i = 0; i < PowerScroll.Skills.Length; ++i)
|
||||
{
|
||||
m.Skills[PowerScroll.Skills[i]].Cap = 120.0;
|
||||
}
|
||||
|
|
@ -658,7 +658,7 @@ namespace Server.Misc
|
|||
{
|
||||
var bag = new Bag();
|
||||
|
||||
for (var i = 0; i < PowerScroll.Skills.Count; ++i)
|
||||
for (var i = 0; i < PowerScroll.Skills.Length; ++i)
|
||||
{
|
||||
bag.DropItem(new PowerScroll(PowerScroll.Skills[i], 120.0));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue