Cleanup and adds configuration for crashguard (#240)

This commit is contained in:
Kamron Batman 2020-09-12 01:57:07 -07:00 • committed by GitHub
parent 55ae0f8778
commit 7dbfa086bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 1248 additions and 97 deletions

View file

@ -33,7 +33,9 @@ namespace Server.Ethics
if ((item.SavedFlags & 0x100) != 0)
{
if (item.Hue == Hero.Definition.PrimaryHue)
{
return Hero;
}
item.SavedFlags &= ~0x100;
}
@ -41,7 +43,9 @@ namespace Server.Ethics
if ((item.SavedFlags & 0x200) != 0)
{
if (item.Hue == Evil.Definition.PrimaryHue)
{
return Evil;
}
item.SavedFlags &= ~0x200;
}
@ -54,12 +58,18 @@ namespace Server.Ethics
var itemEthic = Find(item);
if (itemEthic == null || Find(newOwner) == itemEthic)
{
return true;
}
if (itemEthic == Hero)
{
(from == newOwner ? to : from).SendMessage("Only heros may receive this item.");
}
else if (itemEthic == Evil)
{
(from == newOwner ? to : from).SendMessage("Only the evil may receive this item.");
}
return false;
}
@ -69,12 +79,18 @@ namespace Server.Ethics
var itemEthic = Find(item);
if (itemEthic == null || Find(from) == itemEthic)
{
return true;
}
if (itemEthic == Hero)
{
from.SendMessage("Only heros may wear this item.");
}
else if (itemEthic == Evil)
{
from.SendMessage("Only the evil may wear this item.");
}
return false;
}
@ -84,28 +100,43 @@ namespace Server.Ethics
public static bool IsImbued(Item item, bool recurse)
{
if (Find(item) != null)
{
return true;
}
if (recurse)
{
foreach (var child in item.Items)
{
if (IsImbued(child, true))
{
return true;
}
}
}
return false;
}
public static void Initialize()
public static void Configure()
{
Enabled = ServerConfiguration.GetOrUpdateSetting("ethics.enable", false);
}
public static void Initialize()
{
if (Enabled)
{
EventSink.Speech += EventSink_Speech;
}
}
public static void EventSink_Speech(SpeechEventArgs e)
{
if (e.Blocked || e.Handled)
{
return;
}
var pl = Player.Find(e.Mobile);
@ -116,13 +147,19 @@ namespace Server.Ethics
var ethic = Ethics[i];
if (!ethic.IsEligible(e.Mobile))
{
continue;
}
if (!Insensitive.Equals(ethic.Definition.JoinPhrase.String, e.Speech))
{
continue;
}
if (!e.Mobile.GetItemsInRange(2).Any(item => item is AnkhNorth || item is AnkhWest))
{
continue;
}
pl = new Player(ethic, e.Mobile);
@ -138,7 +175,9 @@ namespace Server.Ethics
else
{
if (e.Mobile is PlayerMobile mobile && mobile.DuelContext != null)
{
return;
}
var ethic = pl.Ethic;
@ -147,10 +186,14 @@ namespace Server.Ethics
var power = ethic.Definition.Powers[i];
if (!Insensitive.Equals(power.Definition.Phrase.String, e.Speech))
{
continue;
}
if (!power.CheckInvoke(pl))
{
continue;
}
power.BeginInvoke(pl);
e.Handled = true;
@ -169,16 +212,26 @@ namespace Server.Ethics
var pl = Player.Find(mob);
if (pl != null)
{
return pl.Ethic;
}
if (inherit && mob is BaseCreature bc)
{
if (bc.Controlled)
{
return Find(bc.ControlMaster, false);
}
if (bc.Summoned)
{
return Find(bc.SummonMaster, false);
}
if (allegiance)
{
return bc.EthicAllegiance;
}
}
return null;
@ -201,7 +254,9 @@ namespace Server.Ethics
var pl = new Player(this, reader);
if (pl.Mobile != null)
{
Timer.DelayCall(pl.CheckAttach);
}
}
break;
@ -216,7 +271,9 @@ namespace Server.Ethics
writer.WriteEncodedInt(m_Players.Count);
for (var i = 0; i < m_Players.Count; ++i)
{
m_Players[i].Serialize(writer);
}
}
}
}

View file

@ -41,7 +41,7 @@ namespace Server.Factions
if (faction == null && from.AccessLevel < AccessLevel.GameMaster)
return; // TODO: Message?
if (m_Town.Owner == null || @from.AccessLevel < AccessLevel.GameMaster && faction != m_Town.Owner)
if (m_Town.Owner == null || from.AccessLevel < AccessLevel.GameMaster && faction != m_Town.Owner)
from.SendLocalizedMessage(1010332); // Your faction does not control this town
else if (!m_Town.Owner.IsCommander(from))
from.SendLocalizedMessage(1005242); // Only faction Leaders can use townstones

View file

@ -43,7 +43,9 @@ namespace Server.Engines.MLQuests
while ((line = sr.ReadLine()) != null)
{
if (line.Length == 0 || line.StartsWith("#"))
{
continue;
}
var split = line.Split('\t');
@ -52,11 +54,13 @@ namespace Server.Engines.MLQuests
if (type == null || !baseQuestType.IsAssignableFrom(type))
{
if (Debug)
{
Console.WriteLine(
"Warning: {1} quest type '{0}'",
split[0],
type == null ? "Unknown" : "Invalid"
);
}
continue;
}
@ -73,7 +77,9 @@ namespace Server.Engines.MLQuests
}
if (quest == null)
{
continue;
}
Register(type, quest);
@ -84,11 +90,13 @@ namespace Server.Engines.MLQuests
if (questerType == null || !baseQuesterType.IsAssignableFrom(questerType))
{
if (Debug)
{
Console.WriteLine(
"Warning: {1} quester type '{0}'",
split[i],
questerType == null ? "Unknown" : "Invalid"
);
}
continue;
}
@ -115,7 +123,9 @@ namespace Server.Engines.MLQuests
private static void RegisterQuestGiver(MLQuest quest, Type questerType)
{
if (!QuestGivers.TryGetValue(questerType, out var questList))
{
QuestGivers[questerType] = questList = new List<MLQuest>();
}
questList.Add(quest);
}
@ -125,20 +135,33 @@ namespace Server.Engines.MLQuests
Register(quest.GetType(), quest);
foreach (var questerType in questerTypes)
{
RegisterQuestGiver(quest, questerType);
}
}
public static void Configure()
{
Enabled = ServerConfiguration.GetOrUpdateSetting("questSystem.enableMLQuests", Core.ML);
}
public static void Initialize()
{
Enabled = ServerConfiguration.GetOrUpdateSetting("questSystem.enableMLQuests", Core.ML);
if (!Enabled)
{
return;
}
if (AutoGenerateNew)
{
foreach (var quest in Quests.Values)
{
if (quest?.Deserialized == false)
{
quest.Generate();
}
}
}
MLQuestPersistence.EnsureExistence();
@ -205,9 +228,11 @@ namespace Server.Engines.MLQuests
m.SendMessage("Serialization for quest {0} is now {1}.", quest.GetType().Name, enable ? "enabled" : "disabled");
if (AutoGenerateNew && !enable)
{
m.SendMessage(
"Please note that automatic generation of new quests is ON. This quest will be regenerated on the next server start."
);
}
}
[Usage("SaveAllQuests [saveEnabled=true]")]
@ -225,14 +250,18 @@ namespace Server.Engines.MLQuests
var enable = e.Length == 1 ? e.GetBoolean(0) : true;
foreach (var quest in Quests.Values)
{
quest.SaveEnabled = enable;
}
m.SendMessage("Serialization for all quests is now {0}.", enable ? "enabled" : "disabled");
if (AutoGenerateNew && !enable)
{
m.SendMessage(
"Please note that automatic generation of new quests is ON. All quests will be regenerated on the next server start."
);
}
}
[Usage("InvalidQuestItems")]
@ -244,19 +273,29 @@ namespace Server.Engines.MLQuests
var found = new List<object>();
foreach (var item in World.Items.Values)
{
if (item.QuestItem)
{
if (item.Parent is Backpack pack)
{
if (pack.Parent is PlayerMobile player && player.Backpack == pack)
{
continue;
}
}
found.Add(item);
}
}
if (found.Count == 0)
{
m.SendMessage("No matching objects found.");
}
else
{
m.SendGump(new InterfaceGump(m, new[] { "Object" }, found, 0, null));
}
}
private static bool FindQuest(
@ -272,6 +311,7 @@ namespace Server.Engines.MLQuests
// 1. Check quests in progress with this NPC (overriding deliveries is intended)
if (context != null)
{
foreach (var questEntry in quests)
{
var instance = context.FindInstance(questEntry);
@ -284,6 +324,7 @@ namespace Server.Engines.MLQuests
return true;
}
}
}
// 2. Check deliveries (overriding chain offers is intended)
if ((entry = HandleDelivery(pm, quester, questerType)) != null)
@ -294,12 +335,16 @@ namespace Server.Engines.MLQuests
// 3. Check chain quest offers
if (context != null)
{
foreach (var questEntry in quests)
{
if (questEntry.IsChainTriggered && context.ChainOffers.Contains(questEntry))
{
quest = questEntry;
return true;
}
}
}
// 4. Random quest
quest = RandomStarterQuest(quester, pm, context);
@ -310,7 +355,9 @@ namespace Server.Engines.MLQuests
public static void OnDoubleClick(IQuestGiver quester, PlayerMobile pm)
{
if (quester.Deleted || !pm.Alive)
{
return;
}
var context = GetContext(pm);
@ -325,13 +372,22 @@ namespace Server.Engines.MLQuests
TurnToFace(quester, pm);
if (entry.Failed)
{
return; // Note: OSI sends no gump at all for failed quests, they have to be cancelled in the quest overview
}
if (entry.ClaimReward)
{
entry.SendRewardOffer();
}
else if (entry.IsCompleted())
{
entry.SendReportBackGump();
}
else
{
entry.SendProgressGump();
}
}
else if (quest.CanOffer(quester, pm, context, true))
{
@ -346,9 +402,15 @@ namespace Server.Engines.MLQuests
var context = GetContext(pm);
if (context != null)
{
foreach (var quest in context.QuestInstances)
{
if (!quest.ClaimReward && quest.AllowsQuestItem(item, type))
{
return true;
}
}
}
return false;
}
@ -358,7 +420,9 @@ namespace Server.Engines.MLQuests
var context = GetContext(pm);
if (context == null)
{
return;
}
var instances = context.QuestInstances;
@ -368,14 +432,18 @@ namespace Server.Engines.MLQuests
var instance = instances[i];
if (instance.ClaimReward)
{
continue;
}
foreach (var objective in instance.Objectives)
{
if (!objective.Expired && objective.AllowsQuestItem(item, type))
{
objective.CheckComplete(); // yes, this can happen multiple times (for multiple quests)
break;
}
}
}
}
@ -399,7 +467,9 @@ namespace Server.Engines.MLQuests
var context = GetContext(pm);
if (context == null)
{
return;
}
var instances = context.QuestInstances;
@ -408,15 +478,19 @@ namespace Server.Engines.MLQuests
var instance = instances[i];
if (instance.ClaimReward)
{
continue;
}
foreach (var objective in instance.Objectives)
{
if (!objective.Expired && objective is GainSkillObjectiveInstance objectiveInstance &&
objectiveInstance.Handles(skill))
{
objectiveInstance.CheckComplete();
break;
}
}
}
}
@ -425,7 +499,9 @@ namespace Server.Engines.MLQuests
var context = GetContext(pm);
if (context == null)
{
return;
}
var instances = context.QuestInstances;
@ -436,13 +512,16 @@ namespace Server.Engines.MLQuests
var instance = instances[i];
if (instance.ClaimReward)
{
continue;
}
/* A kill only counts for a single objective within a quest,
* but it can count for multiple quests. This is something not
* currently observable on OSI, so it is assumed behavior.
*/
foreach (var objective in instance.Objectives)
{
if (!objective.Expired && objective is KillObjectiveInstance kill)
{
type ??= mob.GetType();
@ -453,6 +532,7 @@ namespace Server.Engines.MLQuests
break;
}
}
}
}
}
@ -461,7 +541,9 @@ namespace Server.Engines.MLQuests
var context = GetContext(pm);
if (context == null)
{
return null;
}
var instances = context.QuestInstances;
MLQuestInstance deliverInstance = null;
@ -476,6 +558,7 @@ namespace Server.Engines.MLQuests
foreach (var objective in instance.Objectives)
// Note: On OSI, expired deliveries can still be completed. Bug?
{
if (!objective.Expired && objective is DeliverObjectiveInstance deliver &&
deliver.IsDestination(quester, questerType))
{
@ -492,6 +575,7 @@ namespace Server.Engines.MLQuests
break; // don't return, we may have to complete more deliveries
}
}
}
return deliverInstance;
@ -507,7 +591,9 @@ namespace Server.Engines.MLQuests
public static MLQuestContext GetOrCreateContext(PlayerMobile pm)
{
if (!Contexts.TryGetValue(pm, out var context))
{
Contexts[pm] = context = new MLQuestContext(pm);
}
return context;
}
@ -541,7 +627,9 @@ namespace Server.Engines.MLQuests
var instance = instances[i];
if (instance.Quester == quester)
{
instance.OnQuesterDeleted();
}
}
}
}
@ -549,7 +637,9 @@ namespace Server.Engines.MLQuests
public static void EventSink_QuestGumpRequest(Mobile m)
{
if (!Enabled || !(m is PlayerMobile pm))
{
return;
}
pm.SendGump(new QuestLogGump(pm));
}
@ -559,7 +649,9 @@ namespace Server.Engines.MLQuests
var quests = quester.MLQuests;
if (quests.Count == 0)
{
return null;
}
m_EligiblePool.Clear();
MLQuest fallback = null;
@ -567,7 +659,9 @@ namespace Server.Engines.MLQuests
foreach (var quest in quests)
{
if (quest.IsChainTriggered || context?.IsDoingQuest(quest) == true)
{
continue;
}
/*
* Save first quest that reaches the CanOffer call.
@ -576,7 +670,9 @@ namespace Server.Engines.MLQuests
fallback ??= quest;
if (quest.CanOffer(quester, pm, context, false))
{
m_EligiblePool.Add(quest);
}
}
return m_EligiblePool.Count == 0 ? fallback : m_EligiblePool.RandomElement();
@ -585,7 +681,9 @@ namespace Server.Engines.MLQuests
public static void TurnToFace(IQuestGiver quester, Mobile mob)
{
if (quester is Mobile m)
{
m.Direction = m.GetDirectionTo(mob);
}
}
public static void Tell(IQuestGiver quester, PlayerMobile pm, int cliloc)
@ -593,11 +691,17 @@ namespace Server.Engines.MLQuests
TurnToFace(quester, pm);
if (quester is Mobile mobile)
{
mobile.PrivateOverheadMessage(MessageType.Regular, SpeechColor, cliloc, pm.NetState);
}
else if (quester is Item item)
{
MessageHelper.SendLocalizedMessageTo(item, pm, cliloc, SpeechColor);
}
else
{
pm.SendLocalizedMessage(cliloc);
}
}
public static void Tell(IQuestGiver quester, PlayerMobile pm, int cliloc, string args)
@ -605,11 +709,17 @@ namespace Server.Engines.MLQuests
TurnToFace(quester, pm);
if (quester is Mobile mobile)
{
mobile.PrivateOverheadMessage(MessageType.Regular, SpeechColor, cliloc, args, pm.NetState);
}
else if (quester is Item item)
{
MessageHelper.SendLocalizedMessageTo(item, pm, cliloc, args, SpeechColor);
}
else
{
pm.SendLocalizedMessage(cliloc, args);
}
}
public static void Tell(IQuestGiver quester, PlayerMobile pm, string message)
@ -617,22 +727,34 @@ namespace Server.Engines.MLQuests
TurnToFace(quester, pm);
if (quester is Mobile mobile)
{
mobile.PrivateOverheadMessage(MessageType.Regular, SpeechColor, false, message, pm.NetState);
}
else if (quester is Item item)
{
MessageHelper.SendMessageTo(item, pm, message, SpeechColor);
}
else
{
pm.SendMessage(SpeechColor, message);
}
}
public static void TellDef(IQuestGiver quester, PlayerMobile pm, TextDefinition def)
{
if (def == null)
{
return;
}
if (def.Number > 0)
{
Tell(quester, pm, def.Number);
}
else if (def.String != null)
{
Tell(quester, pm, def.String);
}
}
public static void WriteQuestRef(IGenericWriter writer, MLQuest quest)
@ -645,12 +767,16 @@ namespace Server.Engines.MLQuests
var typeName = reader.ReadString();
if (typeName == null)
{
return null; // not serialized
}
var questType = AssemblyHandler.FindFirstTypeForName(typeName);
if (questType == null)
{
return null; // no longer a type
}
return FindQuest(questType);
}
@ -713,9 +839,13 @@ namespace Server.Engines.MLQuests
public override void Execute(CommandEventArgs e, object obj)
{
if (!(obj is PlayerMobile pm))
{
LogFailure("They have no ML quest context.");
}
else
{
e.Mobile.SendGump(new PropertiesGump(e.Mobile, GetOrCreateContext(pm)));
}
}
}
}

View file

@ -18,38 +18,38 @@ namespace Server.Engines.PartySystem
if (from == m)
{
@from.SendLocalizedMessage(1005439); // You cannot add yourself to a party.
from.SendLocalizedMessage(1005439); // You cannot add yourself to a party.
}
else if (p != null && p.Leader != from)
{
@from.SendLocalizedMessage(1005453); // You may only add members to the party if you are the leader.
from.SendLocalizedMessage(1005453); // You may only add members to the party if you are the leader.
}
else if (m.Party is Mobile)
{
}
else if (p != null && p.Members.Count + p.Candidates.Count >= Party.Capacity)
{
@from.SendLocalizedMessage(1008095); // You may only have 10 in your party (this includes candidates).
from.SendLocalizedMessage(1008095); // You may only have 10 in your party (this includes candidates).
}
else if (!m.Player && m.Body.IsHuman)
{
m.SayTo(@from, 1005443); // Nay, I would rather stay here and watch a nail rust.
m.SayTo(from, 1005443); // Nay, I would rather stay here and watch a nail rust.
}
else if (!m.Player)
{
@from.SendLocalizedMessage(1005444); // The creature ignores your offer.
from.SendLocalizedMessage(1005444); // The creature ignores your offer.
}
else if (mp != null && mp == p)
{
@from.SendLocalizedMessage(1005440); // This person is already in your party!
from.SendLocalizedMessage(1005440); // This person is already in your party!
}
else if (mp != null)
{
@from.SendLocalizedMessage(1005441); // This person is already in a party!
from.SendLocalizedMessage(1005441); // This person is already in a party!
}
else
{
Party.Invite(@from, m);
Party.Invite(from, m);
}
}
else

View file

@ -24,7 +24,7 @@ namespace Server
public IPoint3D Goal { get; }
public static void Initialize()
public static void Configure()
{
Enabled = ServerConfiguration.GetOrUpdateSetting("pathfinding.enable", true);
}

View file

@ -284,8 +284,8 @@ namespace Server.Engines.Plants
}
public bool IsUsableBy(Mobile from) =>
IsChildOf(from.Backpack) || IsChildOf(from.FindBankNoCreate()) || IsLockedDown && IsAccessibleTo(@from) ||
RootParent is Item root && root.IsSecure && root.IsAccessibleTo(@from);
IsChildOf(from.Backpack) || IsChildOf(from.FindBankNoCreate()) || IsLockedDown && IsAccessibleTo(from) ||
RootParent is Item root && root.IsSecure && root.IsAccessibleTo(from);
public override void OnDoubleClick(Mobile from)
{

View file

@ -95,7 +95,7 @@ namespace Server.Engines.Quests.Doom
);
Effects.PlaySound(loc, Map, 0x1FE);
Chyloth = new Chyloth { Direction = (Direction)(7 & (4 + (int)@from.GetDirectionTo(loc))) };
Chyloth = new Chyloth { Direction = (Direction)(7 & (4 + (int)from.GetDirectionTo(loc))) };
Chyloth.MoveToWorld(loc, Map);

View file

@ -22,7 +22,9 @@ namespace Server.Engines.VeteranRewards
get
{
if (m_Categories == null)
{
SetupRewardTables();
}
return m_Categories;
}
@ -33,7 +35,9 @@ namespace Server.Engines.VeteranRewards
get
{
if (m_Lists == null)
{
SetupRewardTables();
}
return m_Lists;
}
@ -45,15 +49,22 @@ namespace Server.Engines.VeteranRewards
for (var j = 0; j < entries.Count; ++j)
// RewardEntry entry = entries[j];
{
if (HasAccess(mob, entries[j]))
{
return true;
}
}
return false;
}
public static bool HasAccess(Mobile mob, RewardEntry entry)
{
if (Core.Expansion < entry.RequiredExpansion)
{
return false;
}
return HasAccess(mob, entry.List, out var _);
}
@ -77,7 +88,9 @@ namespace Server.Engines.VeteranRewards
ts = list.Age - totalTime;
if (ts <= TimeSpan.Zero)
{
return true;
}
return false;
}
@ -85,7 +98,9 @@ namespace Server.Engines.VeteranRewards
public static int GetRewardLevel(Mobile mob)
{
if (!(mob.Account is Account acct))
{
return 0;
}
return GetRewardLevel(acct);
}
@ -100,7 +115,9 @@ namespace Server.Engines.VeteranRewards
public static bool HasHalfLevel(Mobile mob)
{
if (!(mob.Account is Account acct))
{
return false;
}
return HasHalfLevel(acct);
}
@ -119,10 +136,14 @@ namespace Server.Engines.VeteranRewards
ComputeRewardInfo(mob, out var cur, out var max);
if (cur >= max)
{
return false;
}
if (!(mob.Account is Account acct))
{
return false;
}
// if (mob.AccessLevel < AccessLevel.GameMaster)
acct.SetTag("numRewardsChosen", (cur + 1).ToString());
@ -154,14 +175,22 @@ namespace Server.Engines.VeteranRewards
var tag = acct.GetTag("numRewardsChosen");
if (string.IsNullOrEmpty(tag))
{
cur = 0;
}
else
{
cur = Utility.ToInt32(tag);
}
if (level >= 6)
{
max = 9 + (level - 6) * 2;
}
else
{
max = 2 + level;
}
}
public static bool CheckIsUsableBy(Mobile from, Item item, object[] args = null)
@ -178,12 +207,16 @@ namespace Server.Engines.VeteranRewards
for (var j = 0; j < entries.Length; ++j)
{
if (entries[j].ItemType != type)
{
continue;
}
if (args == null && entries[j].Args.Length == 0)
{
if (isRelaxedRules && i <= 0 || HasAccess(from, list, out var ts))
{
return true;
}
from.SendLocalizedMessage(
1008126,
@ -195,17 +228,23 @@ namespace Server.Engines.VeteranRewards
}
if (args?.Length != entries[j].Args.Length)
{
continue;
}
var match = true;
for (var k = 0; match && k < args.Length; ++k)
{
match = args[k].Equals(entries[j].Args[k]);
}
if (match)
{
if (isRelaxedRules && i <= 0 || HasAccess(from, list, out var ts))
{
return true;
}
from.SendLocalizedMessage(
1008126,
@ -240,22 +279,30 @@ namespace Server.Engines.VeteranRewards
var entries = list.Entries;
for (var j = 0; j < entries.Length; ++j)
{
if (entries[j].ItemType == type)
{
if (args == null && entries[j].Args.Length == 0)
{
return i + 1;
}
if (args?.Length == entries[j].Args.Length)
{
var match = true;
for (var k = 0; match && k < args.Length; ++k)
{
match = args[k].Equals(entries[j].Args[k]);
}
if (match)
{
return i + 1;
}
}
}
}
}
// no entry?
@ -532,20 +579,27 @@ namespace Server.Engines.VeteranRewards
};
}
public static void Initialize()
public static void Configure()
{
Enabled = ServerConfiguration.GetOrUpdateSetting("vetRewards.enable", true);
SkillCapRewards = ServerConfiguration.GetOrUpdateSetting("vetRewards.skillCapRewards", true);
RewardInterval = ServerConfiguration.GetOrUpdateSetting("vetRewards.rewardInterval", TimeSpan.FromDays(30.0));
}
public static void Initialize()
{
if (Enabled)
{
EventSink.Login += EventSink_Login;
}
}
private static void EventSink_Login(Mobile m)
{
if (!m.Alive)
{
return;
}
ComputeRewardInfo(m, out var cur, out var max, out var level);
@ -555,9 +609,13 @@ namespace Server.Engines.VeteranRewards
level = Math.Clamp(level, 0, 4);
if (SkillCapRewards)
{
m.SkillsCap = 7000 + level * 50;
}
else
{
m.SkillsCap = 7000;
}
}
if (Core.ML && m is PlayerMobile pm && !pm.HasStatReward && HasHalfLevel(pm))
@ -567,7 +625,9 @@ namespace Server.Engines.VeteranRewards
}
if (cur < max)
{
m.SendGump(new RewardNoticeGump(m));
}
}
}