fix: Fixes mutate speech character limit (#2157)

### Summary

* Fixes the accidental limitation of dead character speech (OoOo) to 256 characters.
* Optimizes it by 1.5x

```cs
| Method                  | Mean      | Error    | StdDev   | Allocated |
|------------------------ |----------:|---------:|---------:|----------:|
| ManuaLoopMutation       | 147.01 ns | 1.298 ns | 1.084 ns |         - |
| SpanLoopMutation        |  92.03 ns | 0.583 ns | 0.487 ns |         - |
```
This commit is contained in:
Kamron Batman 2025-04-13 22:55:44 -07:00 committed by GitHub
parent 61d074213b
commit 1e349f4369
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -29,6 +29,7 @@ using Server.Text;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Server.Buffers;
using CalcMoves = Server.Movement.Movement;
namespace Server;
@ -5371,13 +5372,32 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
return false;
}
using var sb = new ValueStringBuilder(stackalloc char[Math.Min(text.Length, 256)]);
for (var i = 0; i < text.Length; ++i)
ReadOnlySpan<char> ghostChars = (GhostChars ?? DefaultGhostChars).AsSpan();
var length = text.Length;
char[] rentedChars = null;
Span<char> chars = length <= 256
? stackalloc char[length]
: rentedChars = STArrayPool<char>.Shared.Rent(length);
try
{
sb.Append(text[i] != ' ' ? (GhostChars ?? DefaultGhostChars).RandomElement() : ' ');
var textSpan = text.AsSpan();
for (var i = 0; i < textSpan.Length; ++i)
{
chars[i] = textSpan[i] != ' ' ? ghostChars.RandomElement() : ' ';
}
text = new string(chars[..length]);
}
finally
{
if (rentedChars != null)
{
STArrayPool<char>.Shared.Return(rentedChars);
}
}
text = sb.ToString();
context = m_GhostMutateContext;
return true;
}
@ -5418,7 +5438,7 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
public virtual bool CheckHearsMutatedSpeech(Mobile m, object context) =>
context != m_GhostMutateContext || m.Alive && !m.CanHearGhosts;
private void AddSpeechItemsFrom(List<IEntity> list, Container cont)
private static void AddSpeechItemsFrom(List<IEntity> list, Container cont)
{
for (var i = 0; i < cont.Items.Count; ++i)
{
@ -5470,33 +5490,12 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
break;
}
case MessageType.System:
{
break;
}
case MessageType.Label:
{
break;
}
case MessageType.Focus:
{
break;
}
case MessageType.Spell:
{
break;
}
case MessageType.Guild:
{
break;
}
case MessageType.Alliance:
{
break;
}
case MessageType.Command:
{
break;
}
case MessageType.Encoded:
{
break;
@ -7988,7 +7987,7 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
public static TimeSpan GetManaRegenRate(Mobile m) => ManaRegenRateHandler?.Invoke(m) ?? DefaultManaRate;
public static char[] DefaultGhostChars = { 'o', 'O' };
public static readonly char[] DefaultGhostChars = ['o', 'O'];
public Prompt BeginPrompt(PromptCallback callback, PromptCallback cancelCallback) =>
Prompt = new SimplePrompt(callback, cancelCallback);