Skip to content

Commit 6948c6a

Browse files
feature/chore: format for abbreviated time (AscensionGameDev#2097)
* feature: FormatTimeAbbreviated chore: status duration label chore: inventory/hotbar - items cooldown label chore: inventory/hotbar - spells cooldown label chore: item description - attack speed label chore: spell description - timing labels * fix: review comments --------- Co-authored-by: Robbie Lodico <[email protected]>
1 parent 558ce41 commit 6948c6a

File tree

11 files changed

+306
-118
lines changed

11 files changed

+306
-118
lines changed

Intersect (Core)/Intersect.Core.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
<AutoGen>True</AutoGen>
4141
<DependentUpon>Resources.resx</DependentUpon>
4242
</Compile>
43+
<Compile Update="Utilities\MeasurementFormattingResources.Designer.cs">
44+
<DesignTime>True</DesignTime>
45+
<AutoGen>True</AutoGen>
46+
<DependentUpon>MeasurementFormattingResources.resx</DependentUpon>
47+
</Compile>
4348
</ItemGroup>
4449

4550
<ItemGroup>
@@ -55,6 +60,10 @@
5560
<Generator>ResXFileCodeGenerator</Generator>
5661
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
5762
</EmbeddedResource>
63+
<EmbeddedResource Update="Utilities\MeasurementFormattingResources.resx">
64+
<Generator>ResXFileCodeGenerator</Generator>
65+
<LastGenOutput>MeasurementFormattingResources.Designer.cs</LastGenOutput>
66+
</EmbeddedResource>
5867
</ItemGroup>
5968

6069
<ItemGroup>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
namespace Intersect.Utilities;
2+
3+
public delegate string ProvideNumericalFormatString(double timeInUnit);
4+
5+
public static class MeasurementExtensions
6+
{
7+
public static readonly ProvideNumericalFormatString RoundAboveTen = timeInUnit => timeInUnit > 10 ? "0." : "0.#";
8+
9+
public static string WithSuffix(
10+
this TimeSpan timeSpan,
11+
string? numericalFormat = default,
12+
ProvideNumericalFormatString? numericalFormatProvider = default,
13+
uint truncateDigits = 1
14+
)
15+
{
16+
double timeInUnit;
17+
string suffix;
18+
19+
switch (timeSpan.Ticks)
20+
{
21+
case < TimeSpan.TicksPerMicrosecond:
22+
timeInUnit = timeSpan.Ticks;
23+
suffix = MeasurementFormattingResources.TimeNanosecondSuffix;
24+
break;
25+
26+
case < TimeSpan.TicksPerMillisecond:
27+
timeInUnit = timeSpan.Ticks / (double)TimeSpan.TicksPerMicrosecond;
28+
suffix = MeasurementFormattingResources.TimeMicrosecondSuffix;
29+
break;
30+
31+
case < TimeSpan.TicksPerSecond:
32+
timeInUnit = timeSpan.Ticks / (double)TimeSpan.TicksPerMillisecond;
33+
suffix = MeasurementFormattingResources.TimeMillisecondSuffix;
34+
break;
35+
36+
case < TimeSpan.TicksPerMinute:
37+
timeInUnit = timeSpan.Ticks / (double)TimeSpan.TicksPerSecond;
38+
suffix = MeasurementFormattingResources.TimeSecondSuffix;
39+
break;
40+
41+
case < TimeSpan.TicksPerHour:
42+
timeInUnit = timeSpan.Ticks / (double)TimeSpan.TicksPerMinute;
43+
suffix = MeasurementFormattingResources.TimeMinuteSuffix;
44+
break;
45+
46+
case < TimeSpan.TicksPerDay:
47+
timeInUnit = timeSpan.Ticks / (double)TimeSpan.TicksPerHour;
48+
suffix = MeasurementFormattingResources.TimeHourSuffix;
49+
break;
50+
51+
case < TimeSpan.TicksPerDay * 7:
52+
timeInUnit = timeSpan.Ticks / (double)TimeSpan.TicksPerDay;
53+
suffix = MeasurementFormattingResources.TimeDaySuffix;
54+
break;
55+
56+
case < TimeSpan.TicksPerDay * 365:
57+
timeInUnit = timeSpan.Ticks / (double)(TimeSpan.TicksPerDay * 7);
58+
suffix = MeasurementFormattingResources.TimeWeekSuffix;
59+
break;
60+
61+
default:
62+
timeInUnit = timeSpan.Ticks / (double)(TimeSpan.TicksPerDay * 7);
63+
suffix = MeasurementFormattingResources.TimeYearSuffix;
64+
break;
65+
}
66+
67+
if (numericalFormat == default)
68+
{
69+
numericalFormatProvider ??= RoundAboveTen;
70+
numericalFormat = numericalFormatProvider(timeInUnit);
71+
}
72+
73+
if (truncateDigits > 0)
74+
{
75+
var truncationScale = Math.Pow(10, truncateDigits);
76+
timeInUnit = Math.Truncate(timeInUnit * truncationScale) / truncationScale;
77+
}
78+
79+
var formattedTimeSpan = timeInUnit.ToString($"{numericalFormat}'{suffix}");
80+
return formattedTimeSpan;
81+
}
82+
}

Intersect (Core)/Utilities/MeasurementFormattingResources.Designer.cs

Lines changed: 108 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<root>
4+
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
5+
<xsd:element name="root" msdata:IsDataSet="true">
6+
7+
</xsd:element>
8+
</xsd:schema>
9+
<resheader name="resmimetype">
10+
<value>text/microsoft-resx</value>
11+
</resheader>
12+
<resheader name="version">
13+
<value>1.3</value>
14+
</resheader>
15+
<resheader name="reader">
16+
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
17+
</resheader>
18+
<resheader name="writer">
19+
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
20+
</resheader>
21+
<data name="TimeSecondSuffix" xml:space="preserve">
22+
<value>s</value>
23+
</data>
24+
<data name="TimeMinuteSuffix" xml:space="preserve">
25+
<value>m</value>
26+
</data>
27+
<data name="TimeNanosecondSuffix" xml:space="preserve">
28+
<value>ns</value>
29+
</data>
30+
<data name="TimeMicrosecondSuffix" xml:space="preserve">
31+
<value>μs</value>
32+
</data>
33+
<data name="TimeMillisecondSuffix" xml:space="preserve">
34+
<value>ms</value>
35+
</data>
36+
<data name="TimeDaySuffix" xml:space="preserve">
37+
<value>d</value>
38+
</data>
39+
<data name="TimeMonthSuffix" xml:space="preserve">
40+
<value>mo</value>
41+
</data>
42+
<data name="TimeYearSuffix" xml:space="preserve">
43+
<value>y</value>
44+
</data>
45+
<data name="TimeWeekSuffix" xml:space="preserve">
46+
<value>w</value>
47+
</data>
48+
<data name="TimeHourSuffix" xml:space="preserve">
49+
<value>h</value>
50+
</data>
51+
</root>

Intersect.Client/Interface/Game/DescriptionWindows/ItemDescriptionWindow.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Intersect.Client.Localization;
88
using Intersect.Logging;
99
using Intersect.Network.Packets.Server;
10+
using Intersect.Utilities;
1011

1112
namespace Intersect.Client.Interface.Game.DescriptionWindows
1213
{
@@ -264,12 +265,12 @@ protected void SetupEquipmentInfo()
264265
}
265266

266267
// Display the actual speed this weapon would have based off of our calculated speed stat.
267-
rows.AddKeyValueRow(Strings.ItemDescription.AttackSpeed, Strings.ItemDescription.Seconds.ToString(Globals.Me.CalculateAttackTime(speed) / 1000f));
268+
rows.AddKeyValueRow(Strings.ItemDescription.AttackSpeed, TimeSpan.FromMilliseconds(Globals.Me.CalculateAttackTime(speed)).WithSuffix());
268269
}
269270
else if (mItem.AttackSpeedModifier == 1)
270271
{
271272
// Static, so this weapon's attack speed.
272-
rows.AddKeyValueRow(Strings.ItemDescription.AttackSpeed, Strings.ItemDescription.Seconds.ToString(mItem.AttackSpeedValue / 1000f));
273+
rows.AddKeyValueRow(Strings.ItemDescription.AttackSpeed, TimeSpan.FromMilliseconds(mItem.AttackSpeedValue).WithSuffix());
273274
}
274275
else if (mItem.AttackSpeedModifier == 2)
275276
{

Intersect.Client/Interface/Game/DescriptionWindows/SpellDescriptionWindow.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Intersect.GameObjects;
55
using Intersect.Client.General;
66
using Intersect.Client.Localization;
7+
using Intersect.Utilities;
78

89
namespace Intersect.Client.Interface.Game.DescriptionWindows
910
{
@@ -120,7 +121,7 @@ protected void SetupSpellInfo()
120121
var castTime = Strings.SpellDescription.Instant;
121122
if (mSpell.CastDuration > 0)
122123
{
123-
castTime = Strings.SpellDescription.Seconds.ToString(mSpell.CastDuration / 1000f);
124+
castTime = TimeSpan.FromMilliseconds(mSpell.CastDuration).WithSuffix();
124125
}
125126
rows.AddKeyValueRow(Strings.SpellDescription.CastTime, castTime);
126127

@@ -136,7 +137,7 @@ protected void SetupSpellInfo()
136137
// Add Cooldown time
137138
if (mSpell.CooldownDuration > 0)
138139
{
139-
rows.AddKeyValueRow(Strings.SpellDescription.Cooldown, Strings.SpellDescription.Seconds.ToString(mSpell.CooldownDuration / 1000f));
140+
rows.AddKeyValueRow(Strings.SpellDescription.Cooldown, TimeSpan.FromMilliseconds(mSpell.CooldownDuration).WithSuffix());
140141
}
141142

142143
// Add Cooldown Group
@@ -262,7 +263,7 @@ protected void SetupCombatInfo()
262263
{
263264
rows.AddKeyValueRow(Strings.SpellDescription.DoT, string.Empty);
264265
}
265-
rows.AddKeyValueRow(Strings.SpellDescription.Tick, Strings.SpellDescription.Seconds.ToString(mSpell.Combat.HotDotInterval / 1000f));
266+
rows.AddKeyValueRow(Strings.SpellDescription.Tick, TimeSpan.FromMilliseconds(mSpell.Combat.HotDotInterval).WithSuffix());
266267
}
267268

268269
// Handle effect display.
@@ -276,7 +277,7 @@ protected void SetupCombatInfo()
276277
// Show Stat Buff / Effect / HoT / DoT duration.
277278
if (showDuration)
278279
{
279-
rows.AddKeyValueRow(Strings.SpellDescription.Duration, Strings.SpellDescription.Seconds.ToString(mSpell.Combat.Duration / 1000f));
280+
rows.AddKeyValueRow(Strings.SpellDescription.Duration, TimeSpan.FromMilliseconds(mSpell.Combat.Duration).WithSuffix("0.#"));
280281
}
281282

282283
// Resize and position the container.

0 commit comments

Comments
 (0)