Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.TimeBoosts
|
||||
{
|
||||
[Flipable(4173, 4174)]
|
||||
public class TimeBoostToken : Item
|
||||
{
|
||||
private ITimeBoost _Boost;
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, true)]
|
||||
public ITimeBoost Boost
|
||||
{
|
||||
get => _Boost ?? (_Boost = TimeBoosts.MinValue);
|
||||
private set
|
||||
{
|
||||
if (_Boost == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Boost = value ?? TimeBoosts.MinValue;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public TimeSpan Value { get => Boost.Value; set => Boost = TimeBoosts.Find(value); }
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public override int Hue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (World.Saving)
|
||||
{
|
||||
return base.Hue;
|
||||
}
|
||||
|
||||
var hue = base.Hue;
|
||||
|
||||
return hue > 0 ? hue : Boost.Hue;
|
||||
}
|
||||
set => base.Hue = value;
|
||||
}
|
||||
|
||||
public override string DefaultName => Boost.Name;
|
||||
|
||||
[Constructable(AccessLevel.Administrator)]
|
||||
public TimeBoostToken()
|
||||
: this(TimeBoosts.RandomValue, 1)
|
||||
{ }
|
||||
|
||||
[Constructable(AccessLevel.Administrator)]
|
||||
public TimeBoostToken(string time)
|
||||
: this(time, 1)
|
||||
{ }
|
||||
|
||||
[Constructable(AccessLevel.Administrator)]
|
||||
public TimeBoostToken(string time, int amount)
|
||||
: this(TimeSpan.Parse(time), amount)
|
||||
{ }
|
||||
|
||||
public TimeBoostToken(TimeSpan time)
|
||||
: this(TimeBoosts.Find(time))
|
||||
{ }
|
||||
|
||||
public TimeBoostToken(TimeSpan time, int amount)
|
||||
: this(TimeBoosts.Find(time), amount)
|
||||
{ }
|
||||
|
||||
public TimeBoostToken(ITimeBoost boost)
|
||||
: this(boost, 1)
|
||||
{ }
|
||||
|
||||
public TimeBoostToken(ITimeBoost boost, int amount)
|
||||
: base(Utility.RandomList(4173, 4174))
|
||||
{
|
||||
Boost = boost;
|
||||
|
||||
Stackable = true;
|
||||
Amount = Math.Max(1, Math.Min(60000, amount));
|
||||
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public TimeBoostToken(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool StackWith(Mobile m, Item dropped, bool playSound)
|
||||
{
|
||||
if (!(dropped is TimeBoostToken) || ((TimeBoostToken)dropped).Boost != Boost)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.StackWith(m, dropped, playSound);
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
new ExtendedOPL(list)
|
||||
{
|
||||
{"Use: Credits {0:#,0} {1} to your account".WrapUOHtmlColor(Color.LawnGreen), Amount, Boost},
|
||||
"\"Time Boosts reduce the time required to do certain things\"".WrapUOHtmlColor(Color.Gold)
|
||||
}.Apply();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (!this.CheckDoubleClick(m, true, false, -1, true, false, false) || !(m is PlayerMobile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var user = (PlayerMobile)m;
|
||||
|
||||
if (TimeBoosts.Credit(user, Boost, Amount))
|
||||
{
|
||||
TimeBoostsUI.Update(user);
|
||||
|
||||
m.SendMessage(85, "{0:#,0} {1} has been credited to your account.", Amount, Boost);
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
|
||||
writer.Write(Boost);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
|
||||
Boost = reader.ReadTimeBoost();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.TimeBoosts
|
||||
{
|
||||
public interface ITimeBoost
|
||||
{
|
||||
int RawValue { get; }
|
||||
TimeSpan Value { get; }
|
||||
|
||||
string Desc { get; }
|
||||
string Name { get; }
|
||||
int Hue { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.TimeBoosts
|
||||
{
|
||||
public struct TimeBoostHours : ITimeBoost
|
||||
{
|
||||
public int RawValue { get; private set; }
|
||||
public TimeSpan Value { get; private set; }
|
||||
|
||||
public string Desc => "Hour";
|
||||
public string Name => String.Format("{0}-{1} Boost", RawValue, Desc);
|
||||
|
||||
public int Hue => 2118;
|
||||
|
||||
public TimeBoostHours(int hours)
|
||||
: this()
|
||||
{
|
||||
Value = TimeSpan.FromHours(RawValue = hours);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hash = RawValue;
|
||||
hash = (hash * 397) ^ Value.Days;
|
||||
hash = (hash * 397) ^ Value.Hours;
|
||||
hash = (hash * 397) ^ Value.Minutes;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator TimeBoostHours(int hours)
|
||||
{
|
||||
return new TimeBoostHours(hours);
|
||||
}
|
||||
|
||||
public static implicit operator TimeBoostHours(TimeSpan time)
|
||||
{
|
||||
return new TimeBoostHours(time.Hours);
|
||||
}
|
||||
|
||||
public static implicit operator TimeSpan(TimeBoostHours value)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static implicit operator int(TimeBoostHours value)
|
||||
{
|
||||
return value.RawValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.TimeBoosts
|
||||
{
|
||||
public struct TimeBoostMinutes : ITimeBoost
|
||||
{
|
||||
public int RawValue { get; private set; }
|
||||
public TimeSpan Value { get; private set; }
|
||||
|
||||
public string Desc => "Minute";
|
||||
public string Name => String.Format("{0}-{1} Boost", RawValue, Desc);
|
||||
|
||||
public int Hue => 2106;
|
||||
|
||||
public TimeBoostMinutes(int minutes)
|
||||
: this()
|
||||
{
|
||||
Value = TimeSpan.FromMinutes(RawValue = minutes);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hash = RawValue;
|
||||
hash = (hash * 397) ^ Value.Days;
|
||||
hash = (hash * 397) ^ Value.Hours;
|
||||
hash = (hash * 397) ^ Value.Minutes;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator TimeBoostMinutes(int minutes)
|
||||
{
|
||||
return new TimeBoostMinutes(minutes);
|
||||
}
|
||||
|
||||
public static implicit operator TimeBoostMinutes(TimeSpan time)
|
||||
{
|
||||
return new TimeBoostMinutes(time.Minutes);
|
||||
}
|
||||
|
||||
public static implicit operator TimeSpan(TimeBoostMinutes value)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static implicit operator int(TimeBoostMinutes value)
|
||||
{
|
||||
return value.RawValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Accounting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.TimeBoosts
|
||||
{
|
||||
public sealed class TimeBoostProfile : PropertyObject, IEnumerable<KeyValuePair<ITimeBoost, int>>
|
||||
{
|
||||
public IAccount Owner { get; private set; }
|
||||
|
||||
private Dictionary<ITimeBoost, int> _Boosts = new Dictionary<ITimeBoost, int>();
|
||||
|
||||
public int this[ITimeBoost key] { get => _Boosts.GetValue(key); set => _Boosts.Update(key, value); }
|
||||
|
||||
public TimeSpan TotalTime => TimeSpan.FromTicks(_Boosts.Sum(kv => kv.Key.Value.Ticks * kv.Value));
|
||||
|
||||
public TimeBoostProfile(IAccount owner)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
public TimeBoostProfile(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
_Boosts.Clear();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_Boosts.Clear();
|
||||
}
|
||||
|
||||
#region Credit
|
||||
public bool CanCredit(ITimeBoost b, int amount)
|
||||
{
|
||||
return b != null && amount >= 0 && (long)this[b] + amount <= Int32.MaxValue;
|
||||
}
|
||||
|
||||
public bool Credit(ITimeBoost b, int amount)
|
||||
{
|
||||
if (CanCredit(b, amount))
|
||||
{
|
||||
this[b] += amount;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CreditHours(int value)
|
||||
{
|
||||
return Credit(value, 0);
|
||||
}
|
||||
|
||||
public bool CreditMinutes(int value)
|
||||
{
|
||||
return Credit(0, value);
|
||||
}
|
||||
|
||||
public bool Credit(int hours, int minutes)
|
||||
{
|
||||
return Credit(hours, minutes, false) && Credit(hours, minutes, true);
|
||||
}
|
||||
|
||||
private bool Credit(int hours, int minutes, bool update)
|
||||
{
|
||||
return Credit(hours, minutes, update, out _, out _);
|
||||
}
|
||||
|
||||
private bool Credit(int hours, int minutes, bool update, out int totalHours, out int totalMinutes)
|
||||
{
|
||||
totalHours = totalMinutes = 0;
|
||||
|
||||
return (hours == 0 || Credit(hours, 0, update, out totalHours)) && (minutes == 0 || Credit(minutes, 1, update, out totalMinutes));
|
||||
}
|
||||
|
||||
private bool Credit(int time, byte index, bool update, out int totalTime)
|
||||
{
|
||||
totalTime = 0;
|
||||
|
||||
if (!TimeBoosts.Times.InBounds(index))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ITimeBoost k;
|
||||
int v, t = time;
|
||||
|
||||
var i = TimeBoosts.Times[index].Length;
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
k = TimeBoosts.Times[index][i];
|
||||
v = k.RawValue;
|
||||
|
||||
if (time >= v && this[k] < Int32.MaxValue)
|
||||
{
|
||||
time -= v;
|
||||
totalTime += v;
|
||||
|
||||
if (update)
|
||||
{
|
||||
++this[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return totalTime >= t;
|
||||
}
|
||||
#endregion Credit
|
||||
|
||||
#region Consume
|
||||
public bool CanConsume(ITimeBoost b, int amount)
|
||||
{
|
||||
return b != null && amount >= 0 && this[b] >= amount;
|
||||
}
|
||||
|
||||
public bool Consume(ITimeBoost b, int amount)
|
||||
{
|
||||
if (CanConsume(b, amount))
|
||||
{
|
||||
this[b] -= amount;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ConsumeHours(int value)
|
||||
{
|
||||
return Consume(value, 0);
|
||||
}
|
||||
|
||||
public bool ConsumeMinutes(int value)
|
||||
{
|
||||
return Consume(0, value);
|
||||
}
|
||||
|
||||
public bool Consume(int hours, int minutes)
|
||||
{
|
||||
return Consume(hours, minutes, false) && Consume(hours, minutes, true);
|
||||
}
|
||||
|
||||
private bool Consume(int hours, int minutes, bool update)
|
||||
{
|
||||
return Consume(hours, minutes, update, out _, out _);
|
||||
}
|
||||
|
||||
private bool Consume(int hours, int minutes, bool update, out int totalHours, out int totalMinutes)
|
||||
{
|
||||
totalHours = totalMinutes = 0;
|
||||
|
||||
return (hours == 0 || Consume(hours, 0, update, out totalHours)) && (minutes == 0 || Consume(minutes, 1, update, out totalMinutes));
|
||||
}
|
||||
|
||||
private bool Consume(int time, byte index, bool update, out int totalTime)
|
||||
{
|
||||
totalTime = 0;
|
||||
|
||||
if (!TimeBoosts.Times.InBounds(index))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ITimeBoost k;
|
||||
int v, t = time;
|
||||
|
||||
var i = TimeBoosts.Times[index].Length;
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
k = TimeBoosts.Times[index][i];
|
||||
v = k.RawValue;
|
||||
|
||||
if (time >= v && this[k] > 0)
|
||||
{
|
||||
time -= v;
|
||||
totalTime += v;
|
||||
|
||||
if (update)
|
||||
{
|
||||
--this[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return totalTime >= t;
|
||||
}
|
||||
#endregion Consume
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<ITimeBoost, int>> GetEnumerator()
|
||||
{
|
||||
return _Boosts.GetEnumerator();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
|
||||
writer.Write(Owner);
|
||||
|
||||
writer.WriteDictionary(_Boosts, (w, k, v) =>
|
||||
{
|
||||
w.Write(k);
|
||||
w.Write(v);
|
||||
});
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
|
||||
Owner = reader.ReadAccount();
|
||||
|
||||
_Boosts = reader.ReadDictionary(r =>
|
||||
{
|
||||
var k = r.ReadTimeBoost();
|
||||
var v = r.ReadInt();
|
||||
|
||||
return new KeyValuePair<ITimeBoost, int>(k, v);
|
||||
},
|
||||
_Boosts);
|
||||
|
||||
_Boosts.RemoveValueRange(v => v <= 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
261
Scripts/SubSystem/VitaNex/Core/Services/TimeBoosts/TimeBoosts.cs
Normal file
261
Scripts/SubSystem/VitaNex/Core/Services/TimeBoosts/TimeBoosts.cs
Normal file
@@ -0,0 +1,261 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Accounting;
|
||||
using Server.Mobiles;
|
||||
|
||||
using VitaNex.IO;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.TimeBoosts
|
||||
{
|
||||
public static partial class TimeBoosts
|
||||
{
|
||||
public static TimeBoostHours[] Hours { get; private set; }
|
||||
public static TimeBoostMinutes[] Minutes { get; private set; }
|
||||
|
||||
public static ITimeBoost[][] Times { get; private set; }
|
||||
public static ITimeBoost[] AllTimes { get; private set; }
|
||||
|
||||
public static ITimeBoost RandomHours => Hours.GetRandom();
|
||||
public static ITimeBoost RandomMinutes => Minutes.GetRandom();
|
||||
|
||||
public static ITimeBoost RandomValue => AllTimes.GetRandom();
|
||||
|
||||
public static ITimeBoost MinValue => AllTimes.Lowest(b => b.Value);
|
||||
public static ITimeBoost MaxValue => AllTimes.Highest(b => b.Value);
|
||||
|
||||
public static BinaryDataStore<IAccount, TimeBoostProfile> Profiles { get; private set; }
|
||||
|
||||
public static TimeBoostProfile FindProfile(PlayerMobile m)
|
||||
{
|
||||
if (m == null || m.Account == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return FindProfile(m.Account);
|
||||
}
|
||||
|
||||
public static TimeBoostProfile FindProfile(IAccount a)
|
||||
{
|
||||
return Profiles.GetValue(a);
|
||||
}
|
||||
|
||||
public static TimeBoostProfile EnsureProfile(PlayerMobile m)
|
||||
{
|
||||
if (m == null || m.Account == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return EnsureProfile(m.Account);
|
||||
}
|
||||
|
||||
public static TimeBoostProfile EnsureProfile(IAccount a)
|
||||
{
|
||||
TimeBoostProfile profile = null;
|
||||
|
||||
Profiles.Update(a, p => profile = p ?? new TimeBoostProfile(a));
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
public static IEnumerable<KeyValuePair<ITimeBoost, int>> FindBoosts(PlayerMobile m)
|
||||
{
|
||||
if (m == null || m.Account == null)
|
||||
{
|
||||
return Enumerable.Empty<KeyValuePair<ITimeBoost, int>>();
|
||||
}
|
||||
|
||||
return FindBoosts(m.Account);
|
||||
}
|
||||
|
||||
public static IEnumerable<KeyValuePair<ITimeBoost, int>> FindBoosts(IAccount a)
|
||||
{
|
||||
return FindProfile(a) ?? Enumerable.Empty<KeyValuePair<ITimeBoost, int>>();
|
||||
}
|
||||
|
||||
#region Credit
|
||||
public static bool CanCredit(PlayerMobile m, ITimeBoost b, int amount)
|
||||
{
|
||||
return m != null && CanCredit(m.Account, b, amount);
|
||||
}
|
||||
|
||||
public static bool Credit(PlayerMobile m, ITimeBoost b, int amount)
|
||||
{
|
||||
return m != null && Credit(m.Account, b, amount);
|
||||
}
|
||||
|
||||
public static bool CreditHours(PlayerMobile m, int value)
|
||||
{
|
||||
return m != null && CreditHours(m.Account, value);
|
||||
}
|
||||
|
||||
public static bool CreditMinutes(PlayerMobile m, int value)
|
||||
{
|
||||
return m != null && CreditMinutes(m.Account, value);
|
||||
}
|
||||
|
||||
public static bool Credit(PlayerMobile m, int hours, int minutes)
|
||||
{
|
||||
return m != null && Credit(m.Account, hours, minutes);
|
||||
}
|
||||
|
||||
public static bool CanCredit(IAccount a, ITimeBoost b, int amount)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.CanCredit(b, amount);
|
||||
}
|
||||
|
||||
public static bool Credit(IAccount a, ITimeBoost b, int amount)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.Credit(b, amount);
|
||||
}
|
||||
|
||||
public static bool CreditHours(IAccount a, int value)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.CreditHours(value);
|
||||
}
|
||||
|
||||
public static bool CreditMinutes(IAccount a, int value)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.CreditMinutes(value);
|
||||
}
|
||||
|
||||
public static bool Credit(IAccount a, int hours, int minutes)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.Credit(hours, minutes);
|
||||
}
|
||||
#endregion Credit
|
||||
|
||||
#region Consume
|
||||
public static bool CanConsume(PlayerMobile m, ITimeBoost b, int amount)
|
||||
{
|
||||
return m != null && CanConsume(m.Account, b, amount);
|
||||
}
|
||||
|
||||
public static bool Consume(PlayerMobile m, ITimeBoost b, int amount)
|
||||
{
|
||||
return m != null && Consume(m.Account, b, amount);
|
||||
}
|
||||
|
||||
public static bool ConsumeHours(PlayerMobile m, int value)
|
||||
{
|
||||
return m != null && ConsumeHours(m.Account, value);
|
||||
}
|
||||
|
||||
public static bool ConsumeMinutes(PlayerMobile m, int value)
|
||||
{
|
||||
return m != null && ConsumeMinutes(m.Account, value);
|
||||
}
|
||||
|
||||
public static bool Consume(PlayerMobile m, int hours, int minutes)
|
||||
{
|
||||
return m != null && Consume(m.Account, hours, minutes);
|
||||
}
|
||||
|
||||
public static bool CanConsume(IAccount a, ITimeBoost b, int amount)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.CanConsume(b, amount);
|
||||
}
|
||||
|
||||
public static bool Consume(IAccount a, ITimeBoost b, int amount)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.Consume(b, amount);
|
||||
}
|
||||
|
||||
public static bool ConsumeHours(IAccount a, int value)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.ConsumeHours(value);
|
||||
}
|
||||
|
||||
public static bool ConsumeMinutes(IAccount a, int value)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.ConsumeMinutes(value);
|
||||
}
|
||||
|
||||
public static bool Consume(IAccount a, int hours, int minutes)
|
||||
{
|
||||
var p = EnsureProfile(a);
|
||||
|
||||
return p != null && p.Consume(hours, minutes);
|
||||
}
|
||||
#endregion Consume
|
||||
|
||||
public static ITimeBoost Find(TimeSpan time)
|
||||
{
|
||||
var index = AllTimes.Length;
|
||||
|
||||
while (--index >= 0)
|
||||
{
|
||||
var b = AllTimes[index];
|
||||
|
||||
if (time >= b.Value)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Write(this GenericWriter writer, ITimeBoost boost)
|
||||
{
|
||||
writer.SetVersion(0);
|
||||
|
||||
if (boost != null)
|
||||
{
|
||||
writer.Write(true);
|
||||
writer.Write(boost.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static ITimeBoost ReadTimeBoost(this GenericReader reader)
|
||||
{
|
||||
reader.GetVersion();
|
||||
|
||||
if (reader.ReadBool())
|
||||
{
|
||||
return Find(reader.ReadTimeSpan());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Accounting;
|
||||
|
||||
using VitaNex.IO;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.TimeBoosts
|
||||
{
|
||||
[CoreService("Time Boosts", "1.0.0.0", TaskPriority.High)]
|
||||
public static partial class TimeBoosts
|
||||
{
|
||||
public static CoreServiceOptions CSOptions { get; private set; }
|
||||
|
||||
static TimeBoosts()
|
||||
{
|
||||
Hours = new TimeBoostHours[] { 1, 3, 6, 12 };
|
||||
Minutes = new TimeBoostMinutes[] { 1, 3, 5, 15, 30 };
|
||||
|
||||
Times = new[] { Hours.CastToArray<ITimeBoost>(), Minutes.CastToArray<ITimeBoost>() };
|
||||
|
||||
AllTimes = Times.SelectMany(t => t).OrderBy(b => b.Value).ToArray();
|
||||
|
||||
CSOptions = new CoreServiceOptions(typeof(TimeBoosts));
|
||||
|
||||
Profiles = new BinaryDataStore<IAccount, TimeBoostProfile>(VitaNexCore.SavesDirectory + "/TimeBoosts", "Profiles")
|
||||
{
|
||||
Async = true,
|
||||
OnSerialize = Serialize,
|
||||
OnDeserialize = Deserialize
|
||||
};
|
||||
}
|
||||
|
||||
private static void CSSave()
|
||||
{
|
||||
Profiles.Export();
|
||||
}
|
||||
|
||||
private static void CSLoad()
|
||||
{
|
||||
Profiles.Import();
|
||||
}
|
||||
|
||||
private static bool Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.SetVersion(0);
|
||||
|
||||
writer.WriteBlockDictionary(Profiles, (w, k, v) =>
|
||||
{
|
||||
w.Write(k);
|
||||
v.Serialize(w);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool Deserialize(GenericReader reader)
|
||||
{
|
||||
reader.GetVersion();
|
||||
|
||||
reader.ReadBlockDictionary(r =>
|
||||
{
|
||||
var k = r.ReadAccount();
|
||||
var v = new TimeBoostProfile(r);
|
||||
|
||||
return new KeyValuePair<IAccount, TimeBoostProfile>(k, v);
|
||||
},
|
||||
Profiles);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,551 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.TimeBoosts
|
||||
{
|
||||
public class TimeBoostsUI : SuperGumpList<ITimeBoost>
|
||||
{
|
||||
public static string DefaultTitle = "Time Boosts";
|
||||
public static string DefaultSubTitle = String.Empty;
|
||||
public static string DefaultEmptyText = "No available Time Boosts.";
|
||||
public static string DefaultSummaryText = "Time Left";
|
||||
public static string DefaultHelpText = "Tip: Click an available time boost to update the time remaining!";
|
||||
|
||||
public static Color DefaultTitleColor = Color.PaleGoldenrod;
|
||||
public static Color DefaultSubTitleColor = Color.Goldenrod;
|
||||
public static Color DefaultEmptyTextColor = Color.SaddleBrown;
|
||||
public static Color DefaultBoostTextColor = Color.Yellow;
|
||||
public static Color DefaultBoostCountColor = Color.LawnGreen;
|
||||
public static Color DefaultSummaryTextColor = Color.Goldenrod;
|
||||
public static Color DefaultHelpTextColor = Color.Gold;
|
||||
|
||||
public static void Update(PlayerMobile user)
|
||||
{
|
||||
foreach (var info in EnumerateInstances<TimeBoostsUI>(user, true).Where(g => g != null && !g.IsDisposed && g.IsOpen))
|
||||
info.Refresh(true);
|
||||
}
|
||||
|
||||
public string Title { get; set; }
|
||||
public string SubTitle { get; set; }
|
||||
public string EmptyText { get; set; }
|
||||
public string SummaryText { get; set; }
|
||||
public string HelpText { get; set; }
|
||||
|
||||
public Color TitleColor { get; set; }
|
||||
public Color SubTitleColor { get; set; }
|
||||
public Color EmptyTextColor { get; set; }
|
||||
public Color BoostTextColor { get; set; }
|
||||
public Color BoostCountColor { get; set; }
|
||||
public Color SummaryTextColor { get; set; }
|
||||
public Color HelpTextColor { get; set; }
|
||||
|
||||
public TimeBoostProfile Profile { get; set; }
|
||||
|
||||
public bool ApplyAutoAllowed { get; set; }
|
||||
public bool ApplyAutoPreview { get; set; }
|
||||
|
||||
public Func<ITimeBoost, bool> CanApply { get; set; }
|
||||
public Action<ITimeBoost> BoostUsed { get; set; }
|
||||
|
||||
public Func<TimeSpan> GetTime { get; set; }
|
||||
public Action<TimeSpan> SetTime { get; set; }
|
||||
|
||||
public TimeSpan? OldTime { get; private set; }
|
||||
|
||||
public TimeSpan? Time { get => GetTime?.Invoke(); set => SetTime?.Invoke(value ?? TimeSpan.Zero); }
|
||||
|
||||
public TimeBoostsUI(Mobile user, Gump parent = null, TimeBoostProfile profile = null, Func<ITimeBoost, bool> canApply = null, Action<ITimeBoost> boostUsed = null, Func<TimeSpan> getTime = null, Action<TimeSpan> setTime = null)
|
||||
: base(user, parent)
|
||||
{
|
||||
Profile = profile;
|
||||
|
||||
CanApply = canApply;
|
||||
BoostUsed = boostUsed;
|
||||
|
||||
GetTime = getTime;
|
||||
SetTime = setTime;
|
||||
|
||||
Title = DefaultTitle;
|
||||
SubTitle = DefaultSubTitle;
|
||||
EmptyText = DefaultEmptyText;
|
||||
SummaryText = DefaultSummaryText;
|
||||
HelpText = DefaultHelpText;
|
||||
|
||||
TitleColor = DefaultTitleColor;
|
||||
SubTitleColor = DefaultSubTitleColor;
|
||||
EmptyTextColor = DefaultEmptyTextColor;
|
||||
BoostTextColor = DefaultBoostTextColor;
|
||||
BoostCountColor = DefaultBoostCountColor;
|
||||
SummaryTextColor = DefaultSummaryTextColor;
|
||||
HelpTextColor = DefaultHelpTextColor;
|
||||
|
||||
ApplyAutoAllowed = true;
|
||||
|
||||
EntriesPerPage = 4;
|
||||
|
||||
Sorted = true;
|
||||
|
||||
CanClose = true;
|
||||
CanDispose = true;
|
||||
CanMove = true;
|
||||
CanResize = false;
|
||||
|
||||
AutoRefreshRate = TimeSpan.FromMinutes(1.0);
|
||||
AutoRefresh = true;
|
||||
|
||||
ForceRecompile = true;
|
||||
}
|
||||
|
||||
protected override void Compile()
|
||||
{
|
||||
if (Profile == null && User != null)
|
||||
Profile = TimeBoosts.EnsureProfile(User.Account);
|
||||
|
||||
if (!ApplyAutoAllowed)
|
||||
ApplyAutoPreview = false;
|
||||
|
||||
base.Compile();
|
||||
}
|
||||
|
||||
protected override void CompileList(List<ITimeBoost> list)
|
||||
{
|
||||
list.Clear();
|
||||
|
||||
var boosts = TimeBoosts.AllTimes.Where(b => Profile == null || Profile[b] > 0);
|
||||
|
||||
if (ApplyAutoAllowed && ApplyAutoPreview)
|
||||
{
|
||||
var time = Time?.Ticks ?? 0;
|
||||
|
||||
if (time > 0)
|
||||
{
|
||||
foreach (var boost in boosts.OrderByDescending(b => b.Value.Ticks))
|
||||
{
|
||||
if (boost.Value.Ticks > time)
|
||||
break;
|
||||
|
||||
var take = Math.Min(Profile[boost], (int)(time / boost.Value.Ticks));
|
||||
|
||||
if (take <= 0)
|
||||
break;
|
||||
|
||||
time -= take * boost.Value.Ticks;
|
||||
|
||||
list.Add(new BoostPreview(boost, take));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
list.AddRange(boosts);
|
||||
|
||||
base.CompileList(list);
|
||||
}
|
||||
|
||||
protected override void CompileLayout(SuperGumpLayout layout)
|
||||
{
|
||||
base.CompileLayout(layout);
|
||||
|
||||
layout.Add("background", () =>
|
||||
{
|
||||
AddBackground(0, 0, 480, 225, 9270);
|
||||
AddBackground(15, 40, 450, 140, 9350);
|
||||
});
|
||||
|
||||
layout.Add("title", () =>
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(Title))
|
||||
return;
|
||||
|
||||
var text = Title;
|
||||
|
||||
text = text.ToUpper();
|
||||
text = text.WrapUOHtmlBold();
|
||||
text = text.WrapUOHtmlColor(TitleColor, false);
|
||||
|
||||
AddHtml(20, 15, 235, 40, text, false, false);
|
||||
});
|
||||
|
||||
layout.Add("subtitle", () =>
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(SubTitle))
|
||||
return;
|
||||
|
||||
var text = SubTitle;
|
||||
|
||||
text = text.ToUpper();
|
||||
text = text.WrapUOHtmlBold();
|
||||
text = text.WrapUOHtmlColor(SubTitleColor, false);
|
||||
text = text.WrapUOHtmlRight();
|
||||
|
||||
AddHtml(255, 15, 200, 40, text, false, false);
|
||||
});
|
||||
|
||||
layout.Add("page/prev", () =>
|
||||
{
|
||||
if (HasPrevPage)
|
||||
AddButton(7, 150, 9910, 9911, PreviousPage);
|
||||
else
|
||||
AddImage(7, 150, 9909);
|
||||
});
|
||||
|
||||
layout.Add("page/next", () =>
|
||||
{
|
||||
if (HasNextPage)
|
||||
AddButton(451, 150, 9904, 9905, NextPage);
|
||||
else
|
||||
AddImage(451, 150, 9903);
|
||||
});
|
||||
|
||||
CompileEntryLayout(layout, GetListRange());
|
||||
|
||||
layout.Add("summary", () =>
|
||||
{
|
||||
TimeSpan time;
|
||||
|
||||
if (ApplyAutoPreview)
|
||||
time = TimeSpan.FromTicks(List.OfType<BoostPreview>().Aggregate(0L, (t, b) => t + (b.Value.Ticks * b.Amount)));
|
||||
else
|
||||
time = Time ?? TimeSpan.Zero;
|
||||
|
||||
if (time < TimeSpan.Zero)
|
||||
time = TimeSpan.Zero;
|
||||
|
||||
var text = SummaryText;
|
||||
|
||||
if (ApplyAutoPreview)
|
||||
text = "Total Time";
|
||||
|
||||
text = text.ToUpper();
|
||||
text = text.WrapUOHtmlBold();
|
||||
text = text.WrapUOHtmlColor(SummaryTextColor, false);
|
||||
text = text.WrapUOHtmlCenter();
|
||||
|
||||
AddHtml(20, 192, 87, 40, text, false, false);
|
||||
AddImage(112, 185, 30223);
|
||||
|
||||
if (ApplyAutoPreview)
|
||||
AddImageTime(140, 185, time, 0x55); // 175 x 28
|
||||
else
|
||||
AddImageTime(140, 185, time, 0x33); // 175 x 28
|
||||
|
||||
AddImage(315, 185, 30223);
|
||||
});
|
||||
|
||||
layout.Add("auto", () =>
|
||||
{
|
||||
if (ApplyAutoPreview)
|
||||
AddButton(350, 187, 2124, 2123, b => ApplyAuto(false));
|
||||
else if (ApplyAutoAllowed)
|
||||
AddButton(350, 187, 2113, 2112, b => ApplyAuto(true));
|
||||
else
|
||||
AddImage(350, 187, 2113, 900);
|
||||
});
|
||||
|
||||
layout.Add("okay", () =>
|
||||
{
|
||||
if (ApplyAutoPreview)
|
||||
AddButton(410, 187, 2121, 2120, b => ApplyAuto(null));
|
||||
else
|
||||
AddButton(410, 187, 2130, 2129, Close);
|
||||
});
|
||||
|
||||
layout.Add("tip", () =>
|
||||
{
|
||||
AddBackground(0, 225, 480, 40, 9270);
|
||||
|
||||
var text = HelpText;
|
||||
|
||||
if (ApplyAutoPreview)
|
||||
text = "Automatically use boosts as displayed above.";
|
||||
|
||||
text = text.WrapUOHtmlSmall();
|
||||
text = text.WrapUOHtmlCenter();
|
||||
text = text.WrapUOHtmlColor(HelpTextColor);
|
||||
|
||||
AddHtml(20, 235, 440, 40, text, false, false);
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual void CompileEntryLayout(SuperGumpLayout layout, Dictionary<int, ITimeBoost> range)
|
||||
{
|
||||
if (range.Count > 0)
|
||||
{
|
||||
var i = 0;
|
||||
|
||||
foreach (var kv in range)
|
||||
{
|
||||
CompileEntryLayout(layout, range.Count, kv.Key, i, 53 + (i * 93), kv.Value);
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
layout.Add("empty", () =>
|
||||
{
|
||||
var text = EmptyText;
|
||||
|
||||
text = text.WrapUOHtmlColor(EmptyTextColor, false);
|
||||
text = text.WrapUOHtmlCenter();
|
||||
|
||||
AddHtml(35, 150, 355, 40, text, false, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void CompileEntryLayout(SuperGumpLayout layout, int length, int index, int pIndex, int xOffset, ITimeBoost boost)
|
||||
{
|
||||
layout.Add("boosts/" + index, () =>
|
||||
{
|
||||
BoostPreview? bp = null;
|
||||
|
||||
if (boost is BoostPreview p)
|
||||
bp = p;
|
||||
|
||||
int hue = boost.Hue, bellID = 10850;
|
||||
|
||||
var text = String.Empty;
|
||||
|
||||
if (boost.Value.Hours != 0)
|
||||
{
|
||||
bellID = 10810; //Blue Gem
|
||||
text = "Hour";
|
||||
}
|
||||
else if (boost.Value.Minutes != 0)
|
||||
{
|
||||
bellID = 10830; //Green Gem
|
||||
text = "Min";
|
||||
}
|
||||
else
|
||||
hue = 2999;
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(text) && boost.RawValue != 1)
|
||||
text += "s";
|
||||
|
||||
if (hue == 2999)
|
||||
{
|
||||
AddImage(xOffset + 7, 56, bellID, hue); //Left Bell
|
||||
AddImage(xOffset + 57, 56, bellID, hue); //Right Bell
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImage(xOffset + 7, 56, bellID); //Left Bell
|
||||
AddImage(xOffset + 57, 56, bellID); //Right Bell
|
||||
}
|
||||
|
||||
AddImage(xOffset, 45, 30058, hue); //Hammer
|
||||
|
||||
if (Profile != null && bp == null)
|
||||
AddButton(xOffset + 5, 65, 1417, 1417, b => SelectBoost(boost)); //Disc
|
||||
|
||||
AddImage(xOffset + 5, 65, 1417, hue); //Disc
|
||||
AddImage(xOffset + 14, 75, 5577, 2999); //Blackout
|
||||
|
||||
AddImageNumber(xOffset + 44, 99, boost.RawValue, hue, Axis.Both);
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
text = text.WrapUOHtmlSmall();
|
||||
text = text.WrapUOHtmlCenter();
|
||||
text = text.WrapUOHtmlColor(BoostTextColor, false);
|
||||
|
||||
AddHtml(xOffset + 20, 110, 50, 40, text, false, false);
|
||||
}
|
||||
|
||||
if (hue == 2999)
|
||||
AddImage(xOffset, 130, 30062, hue); //Feet
|
||||
else
|
||||
{
|
||||
if (Profile != null)
|
||||
AddBackground(xOffset + 10, 143, 70, 30, 9270); //9300
|
||||
|
||||
AddImage(xOffset, 130, 30062); //Feet
|
||||
|
||||
if (Profile != null)
|
||||
{
|
||||
text = $"{(bp?.Amount ?? Profile[boost]):N0}";
|
||||
text = text.WrapUOHtmlBold();
|
||||
text = text.WrapUOHtmlCenter();
|
||||
text = text.WrapUOHtmlColor(BoostCountColor, false);
|
||||
|
||||
AddHtml(xOffset + 12, 150, 65, 40, text, false, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public virtual void ApplyAuto(bool? state)
|
||||
{
|
||||
if (!ApplyAutoAllowed || state == null)
|
||||
ApplyAutoPreview = false;
|
||||
else if (state == true)
|
||||
ApplyAutoPreview = true;
|
||||
else if (ApplyAutoPreview)
|
||||
{
|
||||
foreach (var bp in List.OfType<BoostPreview>())
|
||||
{
|
||||
var amount = bp.Amount;
|
||||
|
||||
while (--amount >= 0 && (IsOpen || Hidden))
|
||||
{
|
||||
if (ApplyBoost(bp.Boost))
|
||||
{
|
||||
OnBoostUsed(bp.Boost);
|
||||
|
||||
if (IsOpen || Hidden)
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IsOpen && !Hidden)
|
||||
break;
|
||||
}
|
||||
|
||||
ApplyAutoPreview = false;
|
||||
}
|
||||
|
||||
if (IsOpen || Hidden)
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
public virtual void SelectBoost(ITimeBoost boost)
|
||||
{
|
||||
if (CanApplyBoost(boost))
|
||||
ApplyBoost(boost, boost.Value.TotalHours >= 6);
|
||||
else
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
public virtual void ApplyBoost(ITimeBoost boost, bool confirm)
|
||||
{
|
||||
if (CanApplyBoost(boost))
|
||||
{
|
||||
if (confirm)
|
||||
{
|
||||
new ConfirmDialogGump(User, Hide(true))
|
||||
{
|
||||
Icon = 7057,
|
||||
Title = $"Use {boost.Name}?",
|
||||
Html = $"{Title}: {SubTitle}\n{boost.RawValue} {boost.Desc}{(boost.RawValue != 1 ? "s" : String.Empty)}.\nClick OK to apply this Time Boost.",
|
||||
AcceptHandler = b => ApplyBoost(boost, false),
|
||||
CancelHandler = b => Refresh(true)
|
||||
}.Send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ApplyBoost(boost))
|
||||
OnBoostUsed(boost);
|
||||
}
|
||||
|
||||
if (IsOpen || Hidden)
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
public virtual bool ApplyBoost(ITimeBoost boost)
|
||||
{
|
||||
if (!CanApplyBoost(boost) || !Profile.Consume(boost, 1))
|
||||
return false;
|
||||
|
||||
OldTime = Time;
|
||||
Time -= boost.Value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual bool CanApplyBoost(ITimeBoost boost)
|
||||
{
|
||||
return GetTime != null && SetTime != null && Time > TimeSpan.Zero && boost != null && boost.RawValue > 0 &&
|
||||
Profile != null && Profile.Owner == User.Account && (CanApply == null || CanApply(boost));
|
||||
}
|
||||
|
||||
protected virtual void OnBoostUsed(ITimeBoost boost)
|
||||
{
|
||||
BoostUsed?.Invoke(boost);
|
||||
|
||||
LogBoostUsed(boost);
|
||||
}
|
||||
|
||||
protected virtual void LogBoostUsed(ITimeBoost boost)
|
||||
{
|
||||
var log = new StringBuilder();
|
||||
|
||||
log.AppendLine();
|
||||
log.AppendLine("UI: '{0}' : '{1}' : '{2}'", Title, SubTitle, SummaryText);
|
||||
log.AppendLine("User: {0}", User);
|
||||
log.AppendLine("Boost: {0}", boost);
|
||||
log.AppendLine("Get: {0}", GetTime.Trace());
|
||||
log.AppendLine("Set: {0}", SetTime.Trace());
|
||||
log.AppendLine("Time: {0} > {1}", OldTime, Time);
|
||||
log.AppendLine();
|
||||
|
||||
log.Log($"/TimeBoosts/{DateTime.Now.ToDirectoryName()}/{boost}.log");
|
||||
}
|
||||
|
||||
public override int SortCompare(ITimeBoost a, ITimeBoost b)
|
||||
{
|
||||
var res = 0;
|
||||
|
||||
if (a.CompareNull(b, ref res))
|
||||
return res;
|
||||
|
||||
if (a.Value < b.Value)
|
||||
return -1;
|
||||
|
||||
if (a.Value > b.Value)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected override void OnDisposed()
|
||||
{
|
||||
base.OnDisposed();
|
||||
|
||||
Profile = null;
|
||||
}
|
||||
|
||||
protected struct BoostPreview : ITimeBoost
|
||||
{
|
||||
public readonly ITimeBoost Boost;
|
||||
public readonly int Amount;
|
||||
|
||||
public int RawValue => Boost.RawValue;
|
||||
public TimeSpan Value => Boost.Value;
|
||||
public string Desc => Boost.Desc;
|
||||
public string Name => Boost.Name;
|
||||
public int Hue => Boost.Hue;
|
||||
|
||||
public BoostPreview(ITimeBoost boost, int amount)
|
||||
{
|
||||
Boost = boost;
|
||||
Amount = amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user