339 lines
9.4 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|