fix: Fixes special scroll logic and display (#1691)
### Summary - Fixes edge case calculations with values that aren't exact. - Fixes skill text casing. - Fixes cliloc error for stat cap scroll gump. - Adds `AosSkillBonuses.GetLowercaseLabel()` for lower case localized skill names. - Fixes initial value for constructing a stat scroll so it isn't negative. - Fixes message for Scroll of Alacrity gump. - Fixes missing property invalidation for Skill/Value.
This commit is contained in:
parent
de0d205fd3
commit
7a71e8b340
6 changed files with 120 additions and 62 deletions
|
|
@ -74,7 +74,7 @@ public partial class PowerScroll : SpecialScroll
|
|||
{
|
||||
Hue = 0x481;
|
||||
|
||||
if (Value == 105.0 || skill is SkillName.Blacksmith or SkillName.Tailoring)
|
||||
if (Value - 105.0 < 0.1 || skill is SkillName.Blacksmith or SkillName.Tailoring)
|
||||
{
|
||||
LootType = LootType.Regular;
|
||||
}
|
||||
|
|
@ -91,23 +91,26 @@ public partial class PowerScroll : SpecialScroll
|
|||
{
|
||||
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)
|
||||
var skillValue = Value;
|
||||
if (skillValue is >= 105 and <= 120)
|
||||
{
|
||||
return 1049635 + (int)level;
|
||||
var truncValue = Math.Floor(skillValue);
|
||||
if (skillValue - truncValue < 0.1)
|
||||
{
|
||||
/* Wondrous Scroll (105 Skill): OR
|
||||
* Exalted Scroll (110 Skill): OR
|
||||
* Mythical Scroll (115 Skill): OR
|
||||
* Legendary Scroll (120 Skill):
|
||||
*/
|
||||
return 1049635 + ((int)truncValue - 105) / 5;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override string DefaultTitle => $"<basefont color=#FFFFFF>Power Scroll ({Value} Skill):</basefont>";
|
||||
public override string DefaultTitle => $"<basefont color=#FFFFFF>Power Scroll ({Math.Floor(Value * 10) / 10:0.#} Skill):</basefont>";
|
||||
|
||||
public static SkillName[] Skills
|
||||
{
|
||||
|
|
@ -183,35 +186,53 @@ public partial class PowerScroll : SpecialScroll
|
|||
|
||||
public override void AddNameProperty(IPropertyList list)
|
||||
{
|
||||
var level = (Value - 105.0) / 5.0;
|
||||
var skillValue = Value;
|
||||
// Truncate to 1 decimal by multiplying by 10 and flooring.
|
||||
var truncValue = Math.Floor(skillValue * 10) / 10.0;
|
||||
|
||||
if (level is >= 0.0 and <= 3.0 && Value % 5.0 == 0.0)
|
||||
// If the scroll is a 105-120 skill scroll and the value is a whole multiple of 5.
|
||||
if (skillValue is >= 105 and <= 120 && skillValue - truncValue < 0.1)
|
||||
{
|
||||
/* 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.AddLocalized(1049639 + (int)level, AosSkillBonuses.GetLabel(Skill));
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add($"a power scroll of {GetName()} ({Value} Skill)");
|
||||
var level = Math.DivRem((int)truncValue - 105, 5, out var rem);
|
||||
if (rem == 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.AddLocalized(1049639 + level, AosSkillBonuses.GetLowercaseLabel(Skill));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list.Add($"a power scroll of {GetSkillName()} ({truncValue:0.#} Skill)");
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
var level = (Value - 105.0) / 5.0;
|
||||
var skillValue = Value;
|
||||
// Truncate to 1 decimal by multiplying by 10 and flooring.
|
||||
// This will need to be divided by 10 to get the actual value.
|
||||
var truncValue = Math.Floor(skillValue * 10) / 10.0;
|
||||
|
||||
if (level is >= 0.0 and <= 3.0 && Value % 5.0 == 0.0)
|
||||
// If the scroll is a 105-120 skill scroll and the value is a whole multiple of 5.
|
||||
if (skillValue is >= 105 and <= 120 && skillValue - truncValue < 0.1)
|
||||
{
|
||||
LabelTo(from, 1049639 + (int)level, GetNameLocalized());
|
||||
}
|
||||
else
|
||||
{
|
||||
LabelTo(from, $"a power scroll of {GetName()} ({Value} Skill)");
|
||||
var level = Math.DivRem((int)truncValue - 105, 5, out var rem);
|
||||
if (rem == 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)
|
||||
*/
|
||||
LabelTo(from, 1049639 + level, $"#{AosSkillBonuses.GetLowercaseLabel(Skill)}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LabelTo(from, $"a power scroll of {GetSkillName()} ({truncValue:0.#} Skill)");
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
|
|
@ -231,7 +252,7 @@ public partial class PowerScroll : SpecialScroll
|
|||
if (skill.Cap >= Value)
|
||||
{
|
||||
// Your ~1_type~ is too high for this power scroll.
|
||||
from.SendLocalizedMessage(1049511, GetNameLocalized());
|
||||
from.SendLocalizedMessage(1049511, $"#{AosSkillBonuses.GetLowercaseLabel(Skill)}");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +267,7 @@ public partial class PowerScroll : SpecialScroll
|
|||
}
|
||||
|
||||
// You feel a surge of magic as the scroll enhances your ~1_type~!
|
||||
from.SendLocalizedMessage(1049513, GetNameLocalized());
|
||||
from.SendLocalizedMessage(1049513, $"#{AosSkillBonuses.GetLowercaseLabel(Skill)}");
|
||||
|
||||
from.Skills[Skill].Cap = Value;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ public partial class ScrollofAlacrity : SpecialScroll
|
|||
|
||||
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.
|
||||
/*
|
||||
* Using a Scroll of Alacrity for a given skill will increase the amount of skillgain you receive for that skill.
|
||||
* Once the Scroll of Alacrity duration has expired, skillgain will return to normal for that skill.
|
||||
*/
|
||||
public override int Message => 1078602;
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ public partial class ScrollofAlacrity : SpecialScroll
|
|||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(1071345, GetName()); // Skill: ~1_val~
|
||||
list.AddLocalized(1071345, SkillLabel); // Skill: ~1_val~
|
||||
list.Add(1071346, 15); // Duration: ~1_val~ minutes
|
||||
}
|
||||
|
||||
|
|
@ -75,10 +75,11 @@ public partial class ScrollofAlacrity : SpecialScroll
|
|||
return;
|
||||
}
|
||||
|
||||
var tskill = from.Skills[Skill].Base;
|
||||
var tcap = from.Skills[Skill].Cap;
|
||||
var skill = from.Skills[Skill];
|
||||
var skillBase = skill.Base;
|
||||
var skillCap = skill.Cap;
|
||||
|
||||
if (tskill >= tcap || from.Skills[Skill].Lock != SkillLock.Up)
|
||||
if (skillBase >= skillCap || 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.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Engines.MLQuests;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
|
|
@ -24,7 +25,7 @@ public partial class ScrollofTranscendence : SpecialScroll
|
|||
public override int Message => 1094933;
|
||||
|
||||
public override string DefaultTitle =>
|
||||
$"<basefont color=#FFFFFF>Scroll of Transcendence ({Value} Skill):</basefont>";
|
||||
$"<basefont color=#FFFFFF>Scroll of Transcendence ({Math.Floor(Value * 10) / 10:0.#} Skill):</basefont>";
|
||||
|
||||
public static ScrollofTranscendence CreateRandom(int min, int max) =>
|
||||
new(Utility.RandomSkill(), Utility.RandomMinMax(min, max) * 0.1);
|
||||
|
|
@ -32,7 +33,7 @@ public partial class ScrollofTranscendence : SpecialScroll
|
|||
public override void GetProperties(IPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
list.Add(1076759, $"{GetName()}\t{Value:0.#} Skill Points");
|
||||
list.Add(1151930, $"{SkillLabel:#}\t{Math.Floor(Value * 10) / 10:0.#}\t{1151931:#}");
|
||||
}
|
||||
|
||||
public override bool CanUse(Mobile from)
|
||||
|
|
@ -76,18 +77,19 @@ public partial class ScrollofTranscendence : SpecialScroll
|
|||
return;
|
||||
}
|
||||
|
||||
var tskill = from.Skills[Skill].Base; // value of skill without item bonuses etc
|
||||
var tcap = from.Skills[Skill].Cap; // maximum value permitted
|
||||
var skill = from.Skills[Skill];
|
||||
var skillBase = skill.Base;
|
||||
var skillCap = skill.Cap;
|
||||
var canGain = false;
|
||||
|
||||
var newValue = Value;
|
||||
|
||||
if (tskill + newValue > tcap)
|
||||
if (skillBase + newValue > skillCap)
|
||||
{
|
||||
newValue = tcap - tskill;
|
||||
newValue = skillCap - skillBase;
|
||||
}
|
||||
|
||||
if (tskill < tcap && from.Skills[Skill].Lock == SkillLock.Up)
|
||||
if (skillBase < skillCap && skill.Lock == SkillLock.Up)
|
||||
{
|
||||
if (from.SkillsTotal + newValue * 10 > from.SkillsCap)
|
||||
{
|
||||
|
|
@ -95,10 +97,11 @@ public partial class ScrollofTranscendence : SpecialScroll
|
|||
|
||||
for (var i = 0; i < ns; i++)
|
||||
{
|
||||
var sk = from.Skills[i];
|
||||
// skill must point down and its value must be enough
|
||||
if (from.Skills[i].Lock == SkillLock.Down && from.Skills[i].Base >= newValue)
|
||||
if (sk.Lock == SkillLock.Down && sk.Base >= newValue)
|
||||
{
|
||||
from.Skills[i].Base -= newValue;
|
||||
sk.Base -= newValue;
|
||||
canGain = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -120,7 +123,7 @@ public partial class ScrollofTranscendence : SpecialScroll
|
|||
}
|
||||
|
||||
// You feel a surge of magic as the scroll enhances your ~1_type~!
|
||||
from.SendLocalizedMessage(1049513, GetNameLocalized());
|
||||
from.SendLocalizedMessage(1049513, $"#{AosSkillBonuses.GetLowercaseLabel(Skill)}");
|
||||
|
||||
from.Skills[Skill].Base += newValue;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ namespace Server.Items;
|
|||
[SerializationGenerator(0, false)]
|
||||
public abstract partial class SpecialScroll : Item
|
||||
{
|
||||
[InvalidateProperties]
|
||||
[SerializableField(0)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private SkillName _skill;
|
||||
|
||||
[InvalidateProperties]
|
||||
[SerializableField(1)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private double _value;
|
||||
|
|
@ -28,9 +30,9 @@ public abstract partial class SpecialScroll : Item
|
|||
public virtual int Title => 0;
|
||||
public abstract string DefaultTitle { get; }
|
||||
|
||||
public virtual string GetNameLocalized() => $"#{AosSkillBonuses.GetLabel(Skill)}";
|
||||
public virtual int SkillLabel => AosSkillBonuses.GetLabel(Skill);
|
||||
|
||||
public virtual string GetName()
|
||||
public virtual string GetSkillName()
|
||||
{
|
||||
var index = (int)Skill;
|
||||
var table = SkillInfo.Table;
|
||||
|
|
@ -110,8 +112,12 @@ public abstract partial class SpecialScroll : Item
|
|||
AddHtml(40, 20, 260, 20, _scroll.DefaultTitle);
|
||||
}
|
||||
|
||||
var skillLabel = _scroll is StatCapScroll ? 1038019 : AosSkillBonuses.GetLabel(_scroll.Skill);
|
||||
AddHtmlLocalized(310, 20, 120, 20, skillLabel, 0xFFFFFF); // Power
|
||||
var skillLabel = _scroll.SkillLabel;
|
||||
|
||||
if (skillLabel > 0)
|
||||
{
|
||||
AddHtmlLocalized(310, 20, 120, 20, skillLabel, 0xFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
using System;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(0, false)]
|
||||
[TypeAlias("Server.Items.StatScroll")]
|
||||
public partial class StatCapScroll : SpecialScroll
|
||||
{
|
||||
[Constructible]
|
||||
public StatCapScroll(int value = 105) : base(SkillName.Alchemy, value) => Hue = 0x481;
|
||||
public StatCapScroll(int value = 230) : base(SkillName.Alchemy, value) => Hue = 0x481;
|
||||
|
||||
public override int SkillLabel => 0;
|
||||
|
||||
/* 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.
|
||||
|
|
@ -20,7 +24,7 @@ public partial class StatCapScroll : SpecialScroll
|
|||
{
|
||||
get
|
||||
{
|
||||
var level = ((int)Value - 230) / 5;
|
||||
var level = Math.DivRem((int)Value - 230, 5, out var rem);
|
||||
|
||||
/* Wondrous Scroll (+5 Maximum Stats): OR
|
||||
* Exalted Scroll (+10 Maximum Stats): OR
|
||||
|
|
@ -28,7 +32,7 @@ public partial class StatCapScroll : SpecialScroll
|
|||
* Legendary Scroll (+20 Maximum Stats): OR
|
||||
* Ultimate Scroll (+25 Maximum Stats):
|
||||
*/
|
||||
if (level is >= 0 and <= 4 && Value % 5 == 0)
|
||||
if (level is >= 0 and <= 4 && rem == 0)
|
||||
{
|
||||
return 1049458 + level;
|
||||
}
|
||||
|
|
@ -42,9 +46,10 @@ public partial class StatCapScroll : SpecialScroll
|
|||
|
||||
public override void AddNameProperty(IPropertyList list)
|
||||
{
|
||||
var level = ((int)Value - 230) / 5;
|
||||
var truncValue = (int)Value;
|
||||
var level = Math.DivRem(truncValue - 230, 5, out var rem);
|
||||
|
||||
if (level is >= 0 and <= 4 && (int)Value % 5 == 0)
|
||||
if (level is >= 0 and <= 4 && rem == 0)
|
||||
{
|
||||
/* a wondrous scroll of ~1_type~ (+5 Maximum Stats) OR
|
||||
* an exalted scroll of ~1_type~ (+10 Maximum Stats) OR
|
||||
|
|
@ -56,22 +61,23 @@ public partial class StatCapScroll : SpecialScroll
|
|||
}
|
||||
else
|
||||
{
|
||||
var diff = Value - 225;
|
||||
var diff = truncValue - 225;
|
||||
list.Add($"a scroll of power ({(diff >= 0 ? "+" : "")}{diff} Maximum Stats)");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
var level = ((int)Value - 230) / 5;
|
||||
var truncValue = (int)Value;
|
||||
var level = (truncValue - 230) / 5;
|
||||
|
||||
if (level is >= 0 and <= 4 && (int)Value % 5 == 0)
|
||||
if (level is >= 0 and <= 4)
|
||||
{
|
||||
LabelTo(from, 1049463 + level, "#1049476");
|
||||
}
|
||||
else
|
||||
{
|
||||
var diff = Value - 225;
|
||||
var diff = truncValue - 225;
|
||||
LabelTo(from, $"a scroll of power ({(diff >= 0 ? "+" : "")}{diff} Maximum Stats)");
|
||||
}
|
||||
}
|
||||
|
|
@ -1085,6 +1085,27 @@ namespace Server
|
|||
};
|
||||
}
|
||||
|
||||
public static int GetLowercaseLabel(SkillName skill)
|
||||
{
|
||||
return skill switch
|
||||
{
|
||||
SkillName.Provocation => 1049473, // provocation
|
||||
SkillName.MagicResist => 1049471, // resisting spells
|
||||
SkillName.AnimalTaming => 1049472, // animal taming
|
||||
SkillName.Macing => 1049470, // mace fighting
|
||||
SkillName.Necromancy => 1060842, // necromancy
|
||||
SkillName.Focus => 1061616, // focus
|
||||
SkillName.Chivalry => 1061615, // chivalry
|
||||
SkillName.Bushido => 1062935, // bushido
|
||||
SkillName.Ninjitsu => 1062936, // ninjitsu
|
||||
SkillName.Spellweaving => 1074397, // spellweaving
|
||||
SkillName.Mysticism => 1112544, // mysticism
|
||||
SkillName.Imbuing => 1112545, // imbuing
|
||||
SkillName.Throwing => 1112553, // throwing
|
||||
_ => 1042347 + (int)skill
|
||||
};
|
||||
}
|
||||
|
||||
public void AddTo(Mobile m)
|
||||
{
|
||||
Remove();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue