ModernUO/Projects/UOContent/Mobiles/ChampionTitleInfo.cs

339 lines
9.4 KiB
C#

using System;
using System.Runtime.CompilerServices;
using Server.Engines.CannedEvil;
namespace Server.Mobiles
{
[PropertyObject]
public class ChampionTitleInfo
{
private const int LossAmount = 90;
private static TimeSpan LossDelay = TimeSpan.FromDays(1.0);
private TitleInfo[] m_Values;
public ChampionTitleInfo()
{
}
public ChampionTitleInfo(IGenericReader reader)
{
var version = reader.ReadEncodedInt();
switch (version)
{
case 0:
{
Harrower = reader.ReadEncodedInt();
var length = reader.ReadEncodedInt();
if (length == 0)
{
break;
}
m_Values = new TitleInfo[length];
for (var i = 0; i < length; i++)
{
m_Values[i] = new TitleInfo(reader);
}
if (m_Values.Length != ChampionSpawnInfo.Table.Length)
{
var oldValues = m_Values;
m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length];
for (var i = 0; i < m_Values.Length && i < oldValues.Length; i++)
{
m_Values[i] = oldValues[i];
}
}
break;
}
}
}
[CommandProperty(AccessLevel.GameMaster)]
public int Pestilence
{
get => GetValue(ChampionSpawnType.Pestilence);
set => SetValue(ChampionSpawnType.Pestilence, value);
}
[CommandProperty(AccessLevel.GameMaster)]
public int Abyss
{
get => GetValue(ChampionSpawnType.Abyss);
set => SetValue(ChampionSpawnType.Abyss, value);
}
[CommandProperty(AccessLevel.GameMaster)]
public int Arachnid
{
get => GetValue(ChampionSpawnType.Arachnid);
set => SetValue(ChampionSpawnType.Arachnid, value);
}
[CommandProperty(AccessLevel.GameMaster)]
public int ColdBlood
{
get => GetValue(ChampionSpawnType.ColdBlood);
set => SetValue(ChampionSpawnType.ColdBlood, value);
}
[CommandProperty(AccessLevel.GameMaster)]
public int ForestLord
{
get => GetValue(ChampionSpawnType.ForestLord);
set => SetValue(ChampionSpawnType.ForestLord, value);
}
[CommandProperty(AccessLevel.GameMaster)]
public int SleepingDragon
{
get => GetValue(ChampionSpawnType.SleepingDragon);
set => SetValue(ChampionSpawnType.SleepingDragon, value);
}
[CommandProperty(AccessLevel.GameMaster)]
public int UnholyTerror
{
get => GetValue(ChampionSpawnType.UnholyTerror);
set => SetValue(ChampionSpawnType.UnholyTerror, value);
}
[CommandProperty(AccessLevel.GameMaster)]
public int VerminHorde
{
get => GetValue(ChampionSpawnType.VerminHorde);
set => SetValue(ChampionSpawnType.VerminHorde, value);
}
[CommandProperty(AccessLevel.GameMaster)]
public int Harrower { get; set; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetValue(ChampionSpawnType type) => GetValue((int)type);
public int GetValue(int index)
{
if (index < 0 || index >= m_Values?.Length)
{
return 0;
}
return m_Values?[index]?.Value ?? 0;
}
public DateTime GetLastDecay(int index)
{
if (index < 0 || index >= m_Values?.Length)
{
return DateTime.MinValue;
}
return m_Values?[index]?.LastDecay ?? DateTime.MinValue;
}
public void SetValue(ChampionSpawnType type, int value)
{
var index = (int)type;
if (index < 0 || index >= ChampionSpawnInfo.Table.Length)
{
return;
}
m_Values ??= new TitleInfo[ChampionSpawnInfo.Table.Length];
var title = m_Values[index];
if (title == null)
{
if (value > 0)
{
m_Values[index] = new TitleInfo(value, Core.Now);
}
return;
}
title.Value = Math.Max(value, 0);
title.LastDecay = title.Value == 0 ? DateTime.MinValue : Core.Now;
}
public void Award(ChampionSpawnType type, int value)
{
var index = (int)type;
if (value <= 0 || index < 0 || index >= ChampionSpawnInfo.Table.Length)
{
return;
}
m_Values ??= new TitleInfo[ChampionSpawnInfo.Table.Length];
var title = m_Values[index];
if (title == null)
{
m_Values[index] = new TitleInfo(value, Core.Now);
return;
}
title.Value += value;
if (title.LastDecay == DateTime.MinValue)
{
title.LastDecay = Core.Now;
}
}
public void Atrophy(int index, int value)
{
if (value <= 0 || index < 0 || index >= ChampionSpawnInfo.Table.Length)
{
return;
}
var title = m_Values?[index];
if (title == null)
{
return;
}
var before = title.Value;
title.Value -= Math.Min(value, title.Value);
if (before != title.Value)
{
title.LastDecay = Core.Now;
}
}
public override string ToString() => "...";
public static void Serialize(IGenericWriter writer, ChampionTitleInfo titles)
{
writer.WriteEncodedInt(0); // version
writer.WriteEncodedInt(titles.Harrower);
var length = titles.m_Values?.Length ?? 0;
writer.WriteEncodedInt(length);
for (var i = 0; i < length; i++)
{
titles.m_Values![i] ??= new TitleInfo();
TitleInfo.Serialize(writer, titles.m_Values[i]);
}
}
public static bool ShouldAtrophy(PlayerMobile pm)
{
var t = pm.ChampionTitles;
if (t?.m_Values == null)
{
return false;
}
for (var i = 0; i < t.m_Values.Length; i++)
{
var decay = t.GetLastDecay(i);
if (decay > DateTime.MinValue && decay + LossDelay < Core.Now)
{
return true;
}
}
return false;
}
public static void CheckAtrophy(PlayerMobile pm)
{
var t = pm.ChampionTitles;
if (t?.m_Values == null)
{
return;
}
for (var i = 0; i < t.m_Values.Length; i++)
{
var decay = t.GetLastDecay(i);
if (decay > DateTime.MinValue && decay + LossDelay < Core.Now)
{
t.Atrophy(i, LossAmount);
}
}
}
// Called when killing a harrower. Will give a minimum of 1 point.
public static void AwardHarrowerTitle(PlayerMobile pm)
{
var t = pm.ChampionTitles;
if (t == null)
{
return;
}
if (t.m_Values == null)
{
if (t.Harrower == 0)
{
t.Harrower = 1;
}
return;
}
t.m_Values ??= new TitleInfo[ChampionSpawnInfo.Table.Length];
var count = 1;
for (var i = 0; i < t.m_Values.Length; i++)
{
if (t.m_Values[i].Value > 900)
{
count++;
}
}
t.Harrower = Math.Max(count, t.Harrower); // Harrower titles never decay.
}
private class TitleInfo
{
public TitleInfo()
{
}
public TitleInfo(int value, DateTime lastDecay)
{
Value = value;
LastDecay = lastDecay;
}
public TitleInfo(IGenericReader reader)
{
var version = reader.ReadEncodedInt();
switch (version)
{
case 0:
{
Value = reader.ReadEncodedInt();
LastDecay = reader.ReadDateTime();
break;
}
}
}
public int Value { get; set; }
public DateTime LastDecay { get; set; }
public static void Serialize(IGenericWriter writer, TitleInfo info)
{
writer.WriteEncodedInt(0); // version
writer.WriteEncodedInt(info.Value);
writer.Write(info.LastDecay);
}
}
}
}