Skip to content

Commit

Permalink
fix: Fixes special scroll logic and display (#1691)
Browse files Browse the repository at this point in the history
### 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.
  • Loading branch information
kamronbatman committed Mar 2, 2024
1 parent de0d205 commit 7a71e8b
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 62 deletions.
85 changes: 53 additions & 32 deletions Projects/UOContent/Items/Special/Special Scrolls/PowerScroll.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public PowerScroll(SkillName skill = SkillName.Alchemy, double value = 0.0) : ba
{
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;
}
Expand All @@ -91,23 +91,26 @@ 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)
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
{
Expand Down Expand Up @@ -183,35 +186,53 @@ public static PowerScroll CreateRandomNoCraft(int min, int max)

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)
{
/* 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
// 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)
{
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)
{
LabelTo(from, 1049639 + (int)level, GetNameLocalized());
}
else
// 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, $"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)
Expand All @@ -231,7 +252,7 @@ public override bool CanUse(Mobile from)
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;
}

Expand All @@ -246,7 +267,7 @@ public override void Use(Mobile from)
}

// 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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public ScrollofAlacrity(SkillName skill = SkillName.Alchemy) : base(skill, 0.0)

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;

Expand All @@ -30,7 +30,7 @@ public override void GetProperties(IPropertyList list)
{
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
}

Expand Down Expand Up @@ -75,10 +75,11 @@ public override void Use(Mobile from)
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.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using ModernUO.Serialization;
using Server.Engines.MLQuests;
using Server.Engines.MLQuests.Objectives;
Expand All @@ -24,15 +25,15 @@ public ScrollofTranscendence(SkillName skill = SkillName.Alchemy, double value =
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);

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)
Expand Down Expand Up @@ -76,29 +77,31 @@ public override void Use(Mobile 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 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)
{
var ns = from.Skills.Length; // number of items in from.Skills[]

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;
}
Expand All @@ -120,7 +123,7 @@ public override void Use(Mobile from)
}

// 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;

Expand Down
14 changes: 10 additions & 4 deletions Projects/UOContent/Items/Special/Special Scrolls/SpecialScroll.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -28,9 +30,9 @@ public SpecialScroll(SkillName skill, double value) : base(0x14F0)
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;
Expand Down Expand Up @@ -110,8 +112,12 @@ public InternalGump(Mobile mobile, SpecialScroll scroll) : base(25, 50)
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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -20,15 +24,15 @@ public override int Title
{
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
* 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)
if (level is >= 0 and <= 4 && rem == 0)
{
return 1049458 + level;
}
Expand All @@ -42,9 +46,10 @@ public override int Title

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
Expand All @@ -56,22 +61,23 @@ public override void AddNameProperty(IPropertyList list)
}
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)");
}
}
Expand Down
21 changes: 21 additions & 0 deletions Projects/UOContent/Misc/AOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,27 @@ public static int GetLabel(SkillName skill)
};
}

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();
Expand Down

0 comments on commit 7a71e8b

Please sign in to comment.