Here are the examples of the csharp api System.Math.Max(decimal, decimal) taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
5885 Examples
19
View Source File : GaugeProcsTracker.cs
License : GNU Affero General Public License v3.0
Project Creator : 0ceal0t
License : GNU Affero General Public License v3.0
Project Creator : 0ceal0t
protected override void TickTracker() {
var playSound = false;
var procActiveCount = 0;
foreach (var proc in Procs) {
bool procActive;
if (proc.Config.Trigger.Type == ItemType.Buff) {
procActive = UIHelper.PlayerStatus.TryGetValue(proc.Config.Trigger, out var buff);
proc.RemainingTime = procActive ? Math.Max(0, buff.RemainingTime) : 0;
}
else {
procActive = !UIHelper.GetRecastActive(proc.Config.Trigger.Id, out _);
proc.RemainingTime = 0;
}
if (procActive && !proc.Active) playSound = true;
if (procActive) procActiveCount++;
proc.Active = procActive;
}
if (playSound && Config.ProcSound) UIHelper.PlaySeComplete();
State = procActiveCount == 0 ? GaugeState.Inactive : GaugeState.Active;
}
19
View Source File : GaugeConfig.cs
License : GNU Affero General Public License v3.0
Project Creator : 0ceal0t
License : GNU Affero General Public License v3.0
Project Creator : 0ceal0t
public void Draw(string id, out bool newPos, out bool newVisual, out bool reset) {
newPos = newVisual = reset = false;
if (JobBars.Config.GaugeEnabled.Draw($"Enabled{id}", Name, Enabled, out var newEnabled)) {
Enabled = newEnabled;
newVisual = true;
newPos = true;
}
if (JobBars.Config.GaugeHideInactive.Draw($"Hide When Inactive{id}", Name, HideWhenInactive, out var newHideWhenInactive)) {
HideWhenInactive = newHideWhenInactive;
}
if (JobBars.Config.GaugeIndividualScale.Draw($"Scale{id}", Name, out var newScale)) {
Scale = Math.Max(0.1f, newScale);
newVisual = true;
newPos = true;
}
if (JobBars.Config.GaugePositionType == GaugePositionType.Split) {
if (JobBars.Config.GaugeSplitPosition.Draw($"Split Position{id}", Name, out var newPosition)) {
newPos = true;
SetSplitPosition(newPosition);
}
}
else {
if (JobBars.Config.GaugeOrder.Draw($"Order{id}", Name, Order, out var newOrder)) {
Order = newOrder;
newPos = true;
}
}
var validTypes = GetValidGaugeTypes();
if (validTypes.Length > 1) {
if (JobBars.Config.GaugeType.Draw($"Type{id}", Name, validTypes, Type, out var newType)) {
SetType(newType);
reset = true;
}
}
TypeConfig.Draw(id, ref newPos, ref newVisual, ref reset);
DrawConfig(id, ref newPos, ref newVisual, ref reset);
}
19
View Source File : Ghost.cs
License : MIT License
Project Creator : 0x0ade
License : MIT License
Project Creator : 0x0ade
public void OnPlayer(Player player) {
if (!Interactive || GrabCooldown > 0f || !CelesteNetClientModule.Settings.Interactions || Context?.Main.GrabbedBy == this)
return;
if (player.StateMachine.State == Player.StNormal &&
player.Speed.Y > 0f && player.Bottom <= Top + 3f) {
Dust.Burst(player.BottomCenter, -1.57079637f, 8);
(Scene as Level)?.DirectionalShake(Vector2.UnitY, 0.05f);
Input.Rumble(RumbleStrength.Light, RumbleLength.Medium);
player.Bounce(Top + 2f);
player.Play("event:/game/general/thing_booped");
} else if (player.StateMachine.State != Player.StDash &&
player.StateMachine.State != Player.StRedDash &&
player.StateMachine.State != Player.StDreamDash &&
player.StateMachine.State != Player.StBirdDashTutorial &&
player.Speed.Y <= 0f && Bottom <= player.Top + 5f) {
player.Speed.Y = Math.Max(player.Speed.Y, 16f);
}
}
19
View Source File : GhostEmoteWheel.cs
License : MIT License
Project Creator : 0x0ade
License : MIT License
Project Creator : 0x0ade
public override void Render() {
base.Render();
string[] emotes = CelesteNetClientModule.Settings.Emotes;
// Update can halt in the pause menu.
if (Shown) {
Angle = CelesteNetClientModule.Instance.JoystickEmoteWheel.Value.Angle();
float angle = (float) ((Angle + Math.PI * 2f) % (Math.PI * 2f));
float start = (-0.5f / emotes.Length) * 2f * (float) Math.PI;
if (2f * (float) Math.PI + start < angle) {
// Angle should be start < angle < 0, but is (TAU + start) < angle < TAU
angle -= 2f * (float) Math.PI;
}
for (int i = 0; i < emotes.Length; i++) {
float min = ((i - 0.5f) / emotes.Length) * 2f * (float) Math.PI;
float max = ((i + 0.5f) / emotes.Length) * 2f * (float) Math.PI;
if (min <= angle && angle <= max) {
Selected = i;
break;
}
}
}
time += Engine.RawDeltaTime;
if (!Shown) {
Selected = -1;
}
selectedTime += Engine.RawDeltaTime;
if (PrevSelected != Selected) {
selectedTime = 0f;
PrevSelected = Selected;
}
float popupAlpha;
float popupScale;
popupTime += Engine.RawDeltaTime;
if (Shown && !popupShown) {
popupTime = 0f;
} else if ((Shown && popupTime > 1f) ||
(!Shown && popupTime < 1f)) {
popupTime = 1f;
}
popupShown = Shown;
if (popupTime < 0.1f) {
float t = popupTime / 0.1f;
// Pop in.
popupAlpha = Ease.CubeOut(t);
popupScale = Ease.ElasticOut(t);
} else if (popupTime < 1f) {
// Stay.
popupAlpha = 1f;
popupScale = 1f;
} else {
float t = (popupTime - 1f) / 0.2f;
// Fade out.
popupAlpha = 1f - Ease.CubeIn(t);
popupScale = 1f - 0.2f * Ease.CubeIn(t);
}
float alpha = Alpha * popupAlpha;
if (alpha <= 0f)
return;
if (Tracking == null)
return;
Level level = SceneAs<Level>();
if (level == null)
return;
popupScale *= level.GetScreenScale();
Vector2 pos = Tracking.Position;
pos.Y -= 8f;
pos = level.WorldToScreen(pos);
float radius = BG.Width * 0.5f * 0.75f * popupScale;
pos = pos.Clamp(
0f + radius, 0f + radius,
1920f - radius, 1080f - radius
);
// Draw.Circle(pos, radius, Color.Black * 0.8f * alpha * alpha, radius * 0.6f * (1f + 0.2f * (float) Math.Sin(time)), 8);
BG.DrawCentered(
pos,
Color.White * alpha * alpha * alpha,
Vector2.One * popupScale
);
Indicator.DrawCentered(
pos,
Color.White * alpha * alpha * alpha,
Vector2.One * popupScale,
Angle
);
float selectedScale = 1.2f - 0.2f * Calc.Clamp(Ease.CubeOut(selectedTime / 0.1f), 0f, 1f) + (float) Math.Sin(time * 1.8f) * 0.05f;
for (int i = 0; i < emotes.Length; i++) {
Line.DrawCentered(
pos,
Color.White * alpha * alpha * alpha,
Vector2.One * popupScale,
((i + 0.5f) / emotes.Length) * 2f * (float) Math.PI
);
string emote = emotes[i];
if (string.IsNullOrEmpty(emote))
continue;
float a = (i / (float) emotes.Length) * 2f * (float) Math.PI;
Vector2 emotePos = pos + new Vector2(
(float) Math.Cos(a),
(float) Math.Sin(a)
) * radius;
if (GhostEmote.IsIcon(emote)) {
MTexture icon = GhostEmote.GetIcon(emote, Selected == i ? selectedTime : 0f);
if (icon == null)
continue;
Vector2 iconSize = new(icon.Width, icon.Height);
float iconScale = (GhostEmote.Size / Math.Max(iconSize.X, iconSize.Y)) * 0.24f * popupScale;
icon.DrawCentered(
emotePos,
Color.White * (Selected == i ? (Calc.BetweenInterval(selectedTime, 0.1f) ? 0.9f : 1f) : 0.7f) * alpha,
Vector2.One * (Selected == i ? selectedScale : 1f) * iconScale
);
} else {
Vector2 textSize = CelesteNetClientFont.Measure(emote);
float textScale = (GhostEmote.Size / Math.Max(textSize.X, textSize.Y)) * 0.24f * popupScale;
CelesteNetClientFont.DrawOutline(
emote,
emotePos,
new(0.5f, 0.5f),
Vector2.One * (Selected == i ? selectedScale : 1f) * textScale,
(Selected == i ? (Calc.BetweenInterval(selectedTime, 0.1f) ? TextSelectColorA : TextSelectColorB) : Color.LightSlateGray) * alpha,
2f,
Color.Black * alpha * alpha * alpha
);
}
19
View Source File : GhostEmote.cs
License : MIT License
Project Creator : 0x0ade
License : MIT License
Project Creator : 0x0ade
public override void Render() {
base.Render();
if (Scene is not Level level)
return;
float popupScale = PopupScale * level.GetScreenScale();
MTexture icon = null;
string text = null;
if (IsIcon(Value))
icon = GetIcon(Value, Time);
else
text = Value;
float alpha = Alpha * PopupAlpha;
if (alpha <= 0f || (icon == null && string.IsNullOrWhiteSpace(text)))
return;
if (Tracking == null)
return;
Vector2 pos = level.WorldToScreen(Position);
if (Float)
pos.Y -= (float) Math.Sin(Time * 2f) * 4f;
if (icon != null) {
Vector2 size = new(icon.Width, icon.Height);
float scale = (Size / Math.Max(size.X, size.Y)) * 0.5f * popupScale;
size *= scale;
pos = pos.Clamp(
0f + size.X * 0.5f + 64f, 0f + size.Y * 1f + 64f,
1920f - size.X * 0.5f - 64f, 1080f - 64f
);
icon.DrawJustified(
pos,
new(0.5f, 1f),
Color.White * alpha,
Vector2.One * scale
);
} else {
Vector2 size = CelesteNetClientFont.Measure(text);
float scale = (Size / Math.Max(size.X, size.Y)) * 0.5f * popupScale;
size *= scale;
pos = pos.Clamp(
0f + size.X * 0.5f, 0f + size.Y * 1f,
1920f - size.X * 0.5f, 1080f
);
CelesteNetClientFont.DrawOutline(
text,
pos,
new(0.5f, 1f),
Vector2.One * scale,
Color.White * alpha,
2f,
Color.Black * alpha * alpha * alpha
);
}
}
19
View Source File : RCEPControl.cs
License : MIT License
Project Creator : 0x0ade
License : MIT License
Project Creator : 0x0ade
[RCEndpoint(false, "/chatlog", "?count={count}&detailed={true|false}", "?count=20&detailed=false", "Chat Log", "Basic chat log.")]
public static void ChatLog(Frontend f, HttpRequestEventArgs c) {
bool auth = f.IsAuthorized(c);
NameValueCollection args = f.ParseQueryString(c.Request.RawUrl);
if (!int.TryParse(args["count"], out int count) || count <= 0)
count = 20;
if (!auth && count > 100)
count = 100;
if (!bool.TryParse(args["detailed"], out bool detailed))
detailed = false;
ChatModule chat = f.Server.Get<ChatModule>();
List<object> log = new();
RingBuffer<DataChat?> buffer = chat.ChatBuffer;
lock (buffer) {
for (int i = Math.Max(-buffer.Moved, -count); i < 0; i++) {
DataChat? msg = buffer[i];
if (msg != null && (msg.Target == null || auth))
log.Add(detailed ? msg.ToDetailedFrontendChat() : msg.ToFrontendChat());
}
}
f.RespondJSON(c, log);
}
19
View Source File : CelesteNetPlayerListComponent.cs
License : MIT License
Project Creator : 0x0ade
License : MIT License
Project Creator : 0x0ade
protected override void Render(GameTime gameTime, bool toBuffer) {
float scale = Scale;
float y = 50f * scale;
SpeedrunTimerDisplay timer = Engine.Scene?.Enreplacedies.FindFirst<SpeedrunTimerDisplay>();
if (timer != null) {
switch (global::Celeste.Settings.Instance?.SpeedrunClock ?? SpeedrunType.Off) {
case SpeedrunType.Off:
break;
case SpeedrunType.Chapter:
if (timer.CompleteTimer < 3f)
y += 104f;
break;
case SpeedrunType.File:
default:
y += 104f + 24f;
break;
}
}
List<Blob> list = List;
int textScaleTry = 0;
float textScale = scale;
RetryLineScale:
Vector2 sizeAll = Vector2.Zero;
foreach (Blob blob in list) {
blob.DynScale = Calc.LerpClamp(scale, textScale, blob.ScaleFactor);
blob.DynY = sizeAll.Y;
Vector2 size = CelesteNetClientFont.Measure(blob.Text) * blob.DynScale;
sizeAll.X = Math.Max(sizeAll.X, size.X);
sizeAll.Y += size.Y + 10f * scale;
if (((sizeAll.X + 100f * scale) > UI_WIDTH * 0.7f || (sizeAll.Y + 90f * scale) > UI_HEIGHT * 0.7f) && textScaleTry < 5) {
textScaleTry++;
textScale -= scale * 0.1f;
goto RetryLineScale;
}
}
Context.RenderHelper.Rect(25f * scale, y - 25f * scale, sizeAll.X + 50f * scale, sizeAll.Y + 40f * scale, Color.Black * 0.8f);
foreach (Blob blob in list) {
CelesteNetClientFont.Draw(
blob.Text,
new(50f * scale, y + blob.DynY),
Vector2.Zero,
new(blob.DynScale, blob.DynScale),
blob.Color
);
}
}
19
View Source File : GmicPipeServer.cs
License : GNU General Public License v3.0
Project Creator : 0xC0000054
License : GNU General Public License v3.0
Project Creator : 0xC0000054
private string GetMaxLayerSize(InputMode inputMode)
{
int width = 0;
int height = 0;
switch (inputMode)
{
case InputMode.NoInput:
case InputMode.AllHiddenLayers:
case InputMode.AllHiddenLayersDescending:
break;
case InputMode.ActiveLayer:
case InputMode.ActiveAndBelow:
// The last layer in the list is always the layer the user has selected in Paint.NET,
// so it will be treated as the active layer.
// The clipboard layer (if present) will be placed above the active layer.
GmicLayer activeLayer = layers[layers.Count - 1];
width = activeLayer.Width;
height = activeLayer.Height;
break;
case InputMode.AllLayers:
case InputMode.ActiveAndAbove:
case InputMode.AllVisibleLayers:
case InputMode.AllVisibleLayersDescending:
foreach (GmicLayer layer in layers)
{
width = Math.Max(width, layer.Width);
height = Math.Max(height, layer.Height);
}
break;
default:
throw new InvalidOperationException("Unsupported InputMode: " + inputMode.ToString());
}
return width.ToString(CultureInfo.InvariantCulture) + "," + height.ToString(CultureInfo.InvariantCulture);
}
19
View Source File : GmicPipeServer.cs
License : GNU General Public License v3.0
Project Creator : 0xC0000054
License : GNU General Public License v3.0
Project Creator : 0xC0000054
private void WaitForConnectionCallback(IAsyncResult result)
{
if (server == null)
{
return;
}
try
{
server.EndWaitForConnection(result);
}
catch (ObjectDisposedException)
{
return;
}
byte[] replySizeBuffer = new byte[sizeof(int)];
server.ProperRead(replySizeBuffer, 0, replySizeBuffer.Length);
int messageLength = BitConverter.ToInt32(replySizeBuffer, 0);
byte[] messageBytes = new byte[messageLength];
server.ProperRead(messageBytes, 0, messageLength);
List<string> parameters = DecodeMessageBuffer(messageBytes);
if (!TryGetValue(parameters[0], "command=", out string command))
{
throw new InvalidOperationException("The first item must be a command.");
}
if (command.Equals("gmic_qt_get_max_layer_size", StringComparison.Ordinal))
{
if (!TryGetValue(parameters[1], "mode=", out string mode))
{
throw new InvalidOperationException("The second item must be the input mode.");
}
InputMode inputMode = ParseInputMode(mode);
#if DEBUG
System.Diagnostics.Debug.WriteLine("'gmic_qt_get_max_layer_size' received. mode=" + inputMode.ToString());
#endif
string reply = GetMaxLayerSize(inputMode);
SendMessage(server, reply);
}
else if (command.Equals("gmic_qt_get_cropped_images", StringComparison.Ordinal))
{
if (!TryGetValue(parameters[1], "mode=", out string mode))
{
throw new InvalidOperationException("The second item must be the input mode.");
}
if (!TryGetValue(parameters[2], "croprect=", out string packedCropRect))
{
throw new InvalidOperationException("The third item must be the crop rectangle.");
}
InputMode inputMode = ParseInputMode(mode);
RectangleF cropRect = GetCropRectangle(packedCropRect);
#if DEBUG
System.Diagnostics.Debug.WriteLine(string.Format(CultureInfo.InvariantCulture,
"'gmic_qt_get_cropped_images' received. mode={0}, cropRect={1}",
inputMode.ToString(), cropRect.ToString()));
#endif
string reply = PrepareCroppedLayers(inputMode, cropRect);
SendMessage(server, reply);
}
else if (command.Equals("gmic_qt_output_images", StringComparison.Ordinal))
{
if (!TryGetValue(parameters[1], "mode=", out string mode))
{
throw new InvalidOperationException("The second item must be the output mode.");
}
OutputMode outputMode = ParseOutputMode(mode);
#if DEBUG
System.Diagnostics.Debug.WriteLine("'gmic_qt_output_images' received. mode=" + outputMode.ToString());
#endif
List<string> outputLayers = parameters.GetRange(2, parameters.Count - 2);
string reply = ProcessOutputImage(outputLayers, outputMode);
SendMessage(server, reply);
}
else if (command.Equals("gmic_qt_release_shared_memory", StringComparison.Ordinal))
{
#if DEBUG
System.Diagnostics.Debug.WriteLine("'gmic_qt_release_shared_memory' received.");
#endif
for (int i = 0; i < memoryMappedFiles.Count; i++)
{
memoryMappedFiles[i].Dispose();
}
memoryMappedFiles.Clear();
SendMessage(server, "done");
}
else if (command.Equals("gmic_qt_get_max_layer_data_length", StringComparison.Ordinal))
{
// This command is used to prevent images larger than 4GB from being used on a 32-bit version of G'MIC.
// Attempting to map an image that size into memory would cause an integer overflow when casting a 64-bit
// integer to the unsigned 32-bit size_t type.
long maxDataLength = 0;
foreach (GmicLayer layer in layers)
{
maxDataLength = Math.Max(maxDataLength, layer.Surface.Scan0.Length);
}
server.Write(BitConverter.GetBytes(sizeof(long)), 0, 4);
server.Write(BitConverter.GetBytes(maxDataLength), 0, 8);
}
// Wait for the acknowledgment that the client is done reading.
if (server.IsConnected)
{
byte[] doneMessageBuffer = new byte[4];
int bytesRead = 0;
int bytesToRead = doneMessageBuffer.Length;
do
{
int n = server.Read(doneMessageBuffer, bytesRead, bytesToRead);
bytesRead += n;
bytesToRead -= n;
} while (bytesToRead > 0 && server.IsConnected);
}
// Start a new server and wait for the next connection.
server.Dispose();
server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
server.BeginWaitForConnection(WaitForConnectionCallback, null);
}
19
View Source File : DbSetAsync.cs
License : MIT License
Project Creator : 2881099
License : MIT License
Project Creator : 2881099
async Task<int> DbContextBetchRemoveAsync(EnreplacedyState[] dels) {
if (dels.Any() == false) return 0;
var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync();
return Math.Max(dels.Length, affrows);
}
19
View Source File : DbSetSync.cs
License : MIT License
Project Creator : 2881099
License : MIT License
Project Creator : 2881099
int DbContextBetchRemove(EnreplacedyState[] dels) {
if (dels.Any() == false) return 0;
var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows();
return Math.Max(dels.Length, affrows);
}
19
View Source File : RecordStream.cs
License : MIT License
Project Creator : a1q123456
License : MIT License
Project Creator : a1q123456
private async void HandleAudioMessage(AudioMessage message)
{
try
{
_currentTimestamp = Math.Max(_currentTimestamp, message.MessageHeader.Timestamp);
await SaveMessage(message);
}
catch
{
RtmpSession.Close();
}
}
19
View Source File : RecordStream.cs
License : MIT License
Project Creator : a1q123456
License : MIT License
Project Creator : a1q123456
private async void HandleVideoMessage(VideoMessage message)
{
try
{
_currentTimestamp = Math.Max(_currentTimestamp, message.MessageHeader.Timestamp);
var head = message.Data.Span[0];
var data = FlvDemuxer.DemultiplexVideoData(message);
if (data.FrameType == FrameType.KeyFrame)
{
_keyframeTimes.Add((double)message.MessageHeader.Timestamp / 1000);
_keyframeFilePositions.Add((double)_recordFileData.Position);
}
await SaveMessage(message);
}
catch
{
RtmpSession.Close();
}
}
19
View Source File : RecordStream.cs
License : MIT License
Project Creator : a1q123456
License : MIT License
Project Creator : a1q123456
private async Task PlayRecordFileNoLock(CancellationToken ct)
{
var message = await ReadMessage(ct);
if (message is AudioMessage)
{
await MessageStream.SendMessageAsync(AudioChunkStream, message);
}
else if (message is VideoMessage)
{
await MessageStream.SendMessageAsync(VideoChunkStream, message);
}
else if (message is DataMessage data)
{
data.Data.Insert(0, "@setDataFrame");
_metaData = data;
await MessageStream.SendMessageAsync(ChunkStream, data);
}
_currentTimestamp = Math.Max(_currentTimestamp, message.MessageHeader.Timestamp);
}
19
View Source File : InsightWindow.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
protected override void OnSourceInitialized(EventArgs e)
{
Rect caret = this.TextArea.Caret.CalculateCaretRectangle();
Point pointOnScreen = this.TextArea.TextView.PointToScreen(caret.Location - this.TextArea.TextView.ScrollOffset);
Rect workingArea = System.Windows.Forms.Screen.FromPoint(pointOnScreen.ToSystemDrawing()).WorkingArea.ToWpf().TransformFromDevice(this);
MaxHeight = workingArea.Height;
MaxWidth = Math.Min(workingArea.Width, Math.Max(1000, workingArea.Width * 0.6));
base.OnSourceInitialized(e);
}
19
View Source File : SimpleSegment.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
public static SimpleSegment GetOverlap(ISegment segment1, ISegment segment2)
{
int start = Math.Max(segment1.Offset, segment2.Offset);
int end = Math.Min(segment1.EndOffset, segment2.EndOffset);
if (end < start)
return SimpleSegment.Invalid;
else
return new SimpleSegment(start, end - start);
}
19
View Source File : EditingCommandHandler.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
static ExecutedRoutedEventHandler OnDelete(CaretMovementType caretMovement)
{
return (target, args) => {
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Doreplacedent != null) {
if (textArea.Selection.IsEmpty) {
TextViewPosition startPos = textArea.Caret.Position;
bool enableVirtualSpace = textArea.Options.EnableVirtualSpace;
// When pressing delete; don't move the caret further into virtual space - instead delete the newline
if (caretMovement == CaretMovementType.CharRight)
enableVirtualSpace = false;
double desiredXPos = textArea.Caret.DesiredXPos;
TextViewPosition endPos = CaretNavigationCommandHandler.GetNewCaretPosition(
textArea.TextView, startPos, caretMovement, enableVirtualSpace, ref desiredXPos);
// GetNewCaretPosition may return (0,0) as new position,
// thus we need to validate endPos before using it in the selection.
if (endPos.Line < 1 || endPos.Column < 1)
endPos = new TextViewPosition(Math.Max(endPos.Line, 1), Math.Max(endPos.Column, 1));
// Don't do anything if the number of lines of a rectangular selection would be changed by the deletion.
if (textArea.Selection is RectangleSelection && startPos.Line != endPos.Line)
return;
// Don't select the text to be deleted; just reuse the ReplaceSelectionWithText logic
// Reuse the existing selection, so that we continue using the same logic
textArea.Selection.StartSelectionOrSetEndpoint(startPos, endPos)
.ReplaceSelectionWithText(string.Empty);
} else {
textArea.RemoveSelectedText();
}
textArea.Caret.BringCaretToView();
args.Handled = true;
}
};
}
19
View Source File : EditingCommandHandler.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
static void OnDeleteLine(object target, ExecutedRoutedEventArgs args)
{
TextArea textArea = GetTextArea(target);
if (textArea != null && textArea.Doreplacedent != null) {
int firstLineIndex, lastLineIndex;
if (textArea.Selection.Length == 0) {
// There is no selection, simply delete current line
firstLineIndex = lastLineIndex = textArea.Caret.Line;
} else {
// There is a selection, remove all lines affected by it (use Min/Max to be independent from selection direction)
firstLineIndex = Math.Min(textArea.Selection.StartPosition.Line, textArea.Selection.EndPosition.Line);
lastLineIndex = Math.Max(textArea.Selection.StartPosition.Line, textArea.Selection.EndPosition.Line);
}
DoreplacedentLine startLine = textArea.Doreplacedent.GetLineByNumber(firstLineIndex);
DoreplacedentLine endLine = textArea.Doreplacedent.GetLineByNumber(lastLineIndex);
textArea.Selection = Selection.Create(textArea, startLine.Offset, endLine.Offset + endLine.TotalLength);
textArea.RemoveSelectedText();
args.Handled = true;
}
}
19
View Source File : TextRangeProvider.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
void SetEndpoint(TextPatternRangeEndpoint endpoint, int targetOffset)
{
if (endpoint == TextPatternRangeEndpoint.Start) {
// set start of this range to targetOffset
segment = new AnchorSegment(doc, targetOffset, Math.Max(0, segment.EndOffset - targetOffset));
} else {
// set end of this range to targetOffset
int newStart = Math.Min(segment.Offset, targetOffset);
segment = new AnchorSegment(doc, newStart, targetOffset - newStart);
}
}
19
View Source File : TextRangeProvider.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
public int MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count)
{
Log("{0}.MoveEndpointByUnit({1}, {2}, {3})", ID, endpoint, unit, count);
int offset = GetEndpoint(endpoint);
switch (unit) {
case TextUnit.Character:
offset = MoveOffset(offset, CaretPositioningMode.Normal, count);
break;
case TextUnit.Format:
case TextUnit.Word:
offset = MoveOffset(offset, CaretPositioningMode.WordStart, count);
break;
case TextUnit.Line:
case TextUnit.Paragraph:
int line = doc.GetLineByOffset(offset).LineNumber;
int newLine = Math.Max(1, Math.Min(doc.LineCount, line + count));
offset = doc.GetLineByNumber(newLine).Offset;
break;
case TextUnit.Doreplacedent:
offset = count < 0 ? 0 : doc.TextLength;
break;
}
SetEndpoint(endpoint, offset);
return count;
}
19
View Source File : ColumnRulerRenderer.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
public void Draw(TextView textView, System.Windows.Media.DrawingContext drawingContext)
{
if (column < 1) return;
double offset = textView.WideSpaceWidth * column;
Size pixelSize = PixelSnapHelpers.GetPixelSize(textView);
double markerXPos = PixelSnapHelpers.PixelAlign(offset, pixelSize.Width);
markerXPos -= textView.ScrollOffset.X;
Point start = new Point(markerXPos, 0);
Point end = new Point(markerXPos, Math.Max(textView.DoreplacedentHeight, textView.ActualHeight));
drawingContext.DrawLine(pen, start, end);
}
19
View Source File : VisualLine.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
public int GetNextCaretPosition(int visualColumn, LogicalDirection direction, CaretPositioningMode mode, bool allowVirtualSpace)
{
if (!HreplacedtopsInVirtualSpace(mode))
allowVirtualSpace = false;
if (elements.Count == 0) {
// special handling for empty visual lines:
if (allowVirtualSpace) {
if (direction == LogicalDirection.Forward)
return Math.Max(0, visualColumn + 1);
else if (visualColumn > 0)
return visualColumn - 1;
else
return -1;
} else {
// even though we don't have any elements,
// there's a single caret stop at visualColumn 0
if (visualColumn < 0 && direction == LogicalDirection.Forward)
return 0;
else if (visualColumn > 0 && direction == LogicalDirection.Backward)
return 0;
else
return -1;
}
}
int i;
if (direction == LogicalDirection.Backward) {
// Search Backwards:
// If the last element doesn't handle line borders, return the line end as caret stop
if (visualColumn > this.VisualLength && !elements[elements.Count - 1].HandlesLineBorders && HasImplicitStopAtLineEnd(mode)) {
if (allowVirtualSpace)
return visualColumn - 1;
else
return this.VisualLength;
}
// skip elements that start after or at visualColumn
for (i = elements.Count - 1; i >= 0; i--) {
if (elements[i].VisualColumn < visualColumn)
break;
}
// search last element that has a caret stop
for (; i >= 0; i--) {
int pos = elements[i].GetNextCaretPosition(
Math.Min(visualColumn, elements[i].VisualColumn + elements[i].VisualLength + 1),
direction, mode);
if (pos >= 0)
return pos;
}
// If we've found nothing, and the first element doesn't handle line borders,
// return the line start as normal caret stop.
if (visualColumn > 0 && !elements[0].HandlesLineBorders && HasImplicitStopAtLineStart(mode))
return 0;
} else {
// Search Forwards:
// If the first element doesn't handle line borders, return the line start as caret stop
if (visualColumn < 0 && !elements[0].HandlesLineBorders && HasImplicitStopAtLineStart(mode))
return 0;
// skip elements that end before or at visualColumn
for (i = 0; i < elements.Count; i++) {
if (elements[i].VisualColumn + elements[i].VisualLength > visualColumn)
break;
}
// search first element that has a caret stop
for (; i < elements.Count; i++) {
int pos = elements[i].GetNextCaretPosition(
Math.Max(visualColumn, elements[i].VisualColumn - 1),
direction, mode);
if (pos >= 0)
return pos;
}
// if we've found nothing, and the last element doesn't handle line borders,
// return the line end as caret stop
if ((allowVirtualSpace || !elements[elements.Count - 1].HandlesLineBorders) && HasImplicitStopAtLineEnd(mode)) {
if (visualColumn < this.VisualLength)
return this.VisualLength;
else if (allowVirtualSpace)
return visualColumn + 1;
}
}
// we've found nothing, return -1 and let the caret search continue in the next line
return -1;
}
19
View Source File : SnippetReplaceableTextElement.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
string GetText()
{
if (start.IsDeleted || end.IsDeleted)
return string.Empty;
else
return context.Doreplacedent.GetText(start.Offset, Math.Max(0, end.Offset - start.Offset));
}
19
View Source File : TextEditor.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
public void ScrollTo(int line, int column, VisualYPosition yPositionMode, double referencedVerticalViewPortOffset, double minimumScrollFraction)
{
TextView textView = textArea.TextView;
TextDoreplacedent doreplacedent = textView.Doreplacedent;
if (scrollViewer != null && doreplacedent != null) {
if (line < 1)
line = 1;
if (line > doreplacedent.LineCount)
line = doreplacedent.LineCount;
IScrollInfo scrollInfo = textView;
if (!scrollInfo.CanHorizontallyScroll) {
// Word wrap is enabled. Ensure that we have up-to-date info about line height so that we scroll
// to the correct position.
// This avoids that the user has to repeat the ScrollTo() call several times when there are very long lines.
VisualLine vl = textView.GetOrConstructVisualLine(doreplacedent.GetLineByNumber(line));
double remainingHeight = referencedVerticalViewPortOffset;
while (remainingHeight > 0) {
DoreplacedentLine prevLine = vl.FirstDoreplacedentLine.PreviousLine;
if (prevLine == null)
break;
vl = textView.GetOrConstructVisualLine(prevLine);
remainingHeight -= vl.Height;
}
}
Point p = textArea.TextView.GetVisualPosition(new TextViewPosition(line, Math.Max(1, column)), yPositionMode);
double verticalPos = p.Y - referencedVerticalViewPortOffset;
if (Math.Abs(verticalPos - scrollViewer.VerticalOffset) > minimumScrollFraction * scrollViewer.ViewportHeight) {
scrollViewer.ScrollToVerticalOffset(Math.Max(0, verticalPos));
}
if (column > 0) {
if (p.X > scrollViewer.ViewportWidth - Caret.MinimumDistanceToViewBorder * 2) {
double horizontalPos = Math.Max(0, p.X - scrollViewer.ViewportWidth / 2);
if (Math.Abs(horizontalPos - scrollViewer.HorizontalOffset) > minimumScrollFraction * scrollViewer.ViewportWidth) {
scrollViewer.ScrollToHorizontalOffset(horizontalPos);
}
} else {
scrollViewer.ScrollToHorizontalOffset(0);
}
}
}
}
19
View Source File : ImeNativeWrapper.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
public static bool SetCompositionWindow(HwndSource source, IntPtr hIMC, TextArea textArea)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
Rect textViewBounds = textArea.TextView.GetBounds(source);
Rect characterBounds = textArea.TextView.GetCharacterBounds(textArea.Caret.Position, source);
CompositionForm form = new CompositionForm();
form.dwStyle = 0x0020;
form.ptCurrentPos.x = (int)Math.Max(characterBounds.Left, textViewBounds.Left);
form.ptCurrentPos.y = (int)Math.Max(characterBounds.Top, textViewBounds.Top);
form.rcArea.left = (int)textViewBounds.Left;
form.rcArea.top = (int)textViewBounds.Top;
form.rcArea.right = (int)textViewBounds.Right;
form.rcArea.bottom = (int)textViewBounds.Bottom;
return ImmSetCompositionWindow(hIMC, ref form);
}
19
View Source File : SelectionMouseHandler.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
void ExtendSelectionToMouse(MouseEventArgs e)
{
TextViewPosition oldPosition = textArea.Caret.Position;
if (mode == MouseSelectionMode.Normal || mode == MouseSelectionMode.Rectangular) {
SetCaretOffsetToMousePosition(e);
if (mode == MouseSelectionMode.Normal && textArea.Selection is RectangleSelection)
textArea.Selection = new SimpleSelection(textArea, oldPosition, textArea.Caret.Position);
else if (mode == MouseSelectionMode.Rectangular && !(textArea.Selection is RectangleSelection))
textArea.Selection = new RectangleSelection(textArea, oldPosition, textArea.Caret.Position);
else
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
} else if (mode == MouseSelectionMode.WholeWord || mode == MouseSelectionMode.WholeLine) {
var newWord = (mode == MouseSelectionMode.WholeLine) ? GetLineAtMousePosition(e) : GetWordAtMousePosition(e);
if (newWord != SimpleSegment.Invalid) {
textArea.Selection = Selection.Create(textArea,
Math.Min(newWord.Offset, startWord.Offset),
Math.Max(newWord.EndOffset, startWord.EndOffset));
// moves caret to start or end of selection
if (newWord.Offset < startWord.Offset)
textArea.Caret.Offset = newWord.Offset;
else
textArea.Caret.Offset = Math.Max(newWord.EndOffset, startWord.EndOffset);
}
}
textArea.Caret.BringCaretToView(5.0);
}
19
View Source File : SimpleSelection.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
public override Selection UpdateOnDoreplacedentChange(DoreplacedentChangeEventArgs e)
{
if (e == null)
throw new ArgumentNullException("e");
int newStartOffset, newEndOffset;
if (startOffset <= endOffset) {
newStartOffset = e.GetNewOffset(startOffset, AnchorMovementType.Default);
newEndOffset = Math.Max(newStartOffset, e.GetNewOffset(endOffset, AnchorMovementType.BeforeInsertion));
} else {
newEndOffset = e.GetNewOffset(endOffset, AnchorMovementType.Default);
newStartOffset = Math.Max(newEndOffset, e.GetNewOffset(startOffset, AnchorMovementType.BeforeInsertion));
}
return Selection.Create(
textArea,
new TextViewPosition(textArea.Doreplacedent.GetLocation(newStartOffset), start.VisualColumn),
new TextViewPosition(textArea.Doreplacedent.GetLocation(newEndOffset), end.VisualColumn)
);
}
19
View Source File : BackgroundGeometryBuilder.cs
License : MIT License
Project Creator : Abdesol
License : MIT License
Project Creator : Abdesol
static IEnumerable<Rect> ProcessTextLines(TextView textView, VisualLine visualLine, int segmentStartVC, int segmentEndVC)
{
TextLine lastTextLine = visualLine.TextLines.Last();
Vector scrollOffset = textView.ScrollOffset;
for (int i = 0; i < visualLine.TextLines.Count; i++) {
TextLine line = visualLine.TextLines[i];
double y = visualLine.GetTextLineVisualYPosition(line, VisualYPosition.LineTop);
int visualStartCol = visualLine.GetTextLineVisualStartColumn(line);
int visualEndCol = visualStartCol + line.Length;
if (line == lastTextLine)
visualEndCol -= 1; // 1 position for the TextEndOfParagraph
else
visualEndCol -= line.TrailingWhitespaceLength;
if (segmentEndVC < visualStartCol)
break;
if (lastTextLine != line && segmentStartVC > visualEndCol)
continue;
int segmentStartVCInLine = Math.Max(segmentStartVC, visualStartCol);
int segmentEndVCInLine = Math.Min(segmentEndVC, visualEndCol);
y -= scrollOffset.Y;
Rect lastRect = Rect.Empty;
if (segmentStartVCInLine == segmentEndVCInLine) {
// GetTextBounds crashes for length=0, so we'll handle this case with GetDistanceFromCharacterHit
// We need to return a rectangle to ensure empty lines are still visible
double pos = visualLine.GetTextLineVisualXPosition(line, segmentStartVCInLine);
pos -= scrollOffset.X;
// The following special cases are necessary to get rid of empty rectangles at the end of a TextLine if "Show Spaces" is active.
// If not excluded once, the same rectangle is calculated (and added) twice (since the offset could be mapped to two visual positions; end/start of line), if there is no trailing whitespace.
// Skip this TextLine segment, if it is at the end of this line and this line is not the last line of the VisualLine and the selection continues and there is no trailing whitespace.
if (segmentEndVCInLine == visualEndCol && i < visualLine.TextLines.Count - 1 && segmentEndVC > segmentEndVCInLine && line.TrailingWhitespaceLength == 0)
continue;
if (segmentStartVCInLine == visualStartCol && i > 0 && segmentStartVC < segmentStartVCInLine && visualLine.TextLines[i - 1].TrailingWhitespaceLength == 0)
continue;
lastRect = new Rect(pos, y, textView.EmptyLineSelectionWidth, line.Height);
} else {
if (segmentStartVCInLine <= visualEndCol) {
foreach (TextBounds b in line.GetTextBounds(segmentStartVCInLine, segmentEndVCInLine - segmentStartVCInLine)) {
double left = b.Rectangle.Left - scrollOffset.X;
double right = b.Rectangle.Right - scrollOffset.X;
if (!lastRect.IsEmpty)
yield return lastRect;
// left>right is possible in RTL languages
lastRect = new Rect(Math.Min(left, right), y, Math.Abs(right - left), line.Height);
}
}
}
// If the segment ends in virtual space, extend the last rectangle with the rectangle the portion of the selection
// after the line end.
// Also, when word-wrap is enabled and the segment continues into the next line, extend lastRect up to the end of the line.
if (segmentEndVC > visualEndCol) {
double left, right;
if (segmentStartVC > visualLine.VisualLengthWithEndOfLineMarker) {
// segmentStartVC is in virtual space
left = visualLine.GetTextLineVisualXPosition(lastTextLine, segmentStartVC);
} else {
// Otherwise, we already processed the rects from segmentStartVC up to visualEndCol,
// so we only need to do the remainder starting at visualEndCol.
// For word-wrapped lines, visualEndCol doesn't include the whitespace hidden by the wrap,
// so we'll need to include it here.
// For the last line, visualEndCol already includes the whitespace.
left = (line == lastTextLine ? line.WidthIncludingTrailingWhitespace : line.Width);
}
if (line != lastTextLine || segmentEndVC == int.MaxValue) {
// If word-wrap is enabled and the segment continues into the next line,
// or if the extendToFullWidthAtLineEnd option is used (segmentEndVC == int.MaxValue),
// we select the full width of the viewport.
right = Math.Max(((IScrollInfo)textView).ExtentWidth, ((IScrollInfo)textView).ViewportWidth);
} else {
right = visualLine.GetTextLineVisualXPosition(lastTextLine, segmentEndVC);
}
Rect extendSelection = new Rect(Math.Min(left, right), y, Math.Abs(right - left), line.Height);
if (!lastRect.IsEmpty) {
if (extendSelection.IntersectsWith(lastRect)) {
lastRect.Union(extendSelection);
yield return lastRect;
} else {
// If the end of the line is in an RTL segment, keep lastRect and extendSelection separate.
yield return lastRect;
yield return extendSelection;
}
} else
yield return extendSelection;
} else
yield return lastRect;
}
}
19
View Source File : HololensLaserPointerDetection.cs
License : Apache License 2.0
Project Creator : abist-co-ltd
License : Apache License 2.0
Project Creator : abist-co-ltd
private Mat getROI(Mat img)
{
int w = img.width();
int h = img.height();
int ROIwidth = Math.Max(0, Math.Min(w, ((int) Math.Round(w * detectionArea.x * 0.5 )) * 2));
int ROIheight = Math.Max(0, Math.Min(h, ((int)Math.Round(h * detectionArea.y * 0.5)) * 2));
Rect ROI = new Rect((w - ROIwidth) / 2, (h - ROIheight) / 2, ROIwidth, ROIheight);
return new Mat(img, ROI);
}
19
View Source File : BoxAnnotation3D.cs
License : MIT License
Project Creator : ABTSoftware
License : MIT License
Project Creator : ABTSoftware
void inverseTransform()
{
var xCoordinateCalculator = this.RootSceneEnreplacedy.Viewport3D.ParentSurface.XAxis.GetCurrentCoordinateCalculator();
var yCoordinateCalculator = this.RootSceneEnreplacedy.Viewport3D.ParentSurface.YAxis.GetCurrentCoordinateCalculator();
var zCoordinateCalculator = this.RootSceneEnreplacedy.Viewport3D.ParentSurface.ZAxis.GetCurrentCoordinateCalculator();
var worldCenter = getWorldCenter();
var rangeXStart = xCoordinateCalculator.GetDataValue(_topLeft.x + worldCenter.x);
var rangeXEnd = xCoordinateCalculator.GetDataValue(_bottomRight.x + worldCenter.x);
RangeX = new DoubleRange(Math.Min(rangeXStart, rangeXEnd), Math.Max(rangeXStart, rangeXEnd));
var rangeYStart = yCoordinateCalculator.GetDataValue(_topLeft.y + worldCenter.y);
var rangeYEnd = yCoordinateCalculator.GetDataValue(_bottomRight.y + worldCenter.y);
RangeY = new DoubleRange(Math.Min(rangeYStart, rangeYEnd), Math.Max(rangeYStart, rangeYEnd));
var rangeZStart = zCoordinateCalculator.GetDataValue(_topLeft.z + worldCenter.z);
var rangeZEnd = zCoordinateCalculator.GetDataValue(_bottomRight.z + worldCenter.z);
RangeZ = new DoubleRange(Math.Min(rangeZStart, rangeZEnd), Math.Max(rangeZStart, rangeZEnd));
worldCenter.Dispose();
}
19
View Source File : ScrollingViewportManager.cs
License : MIT License
Project Creator : ABTSoftware
License : MIT License
Project Creator : ABTSoftware
protected override IRange OnCalculateNewXRange(IAxis xAxis)
{
// The Current XAxis VisibleRange
var currentVisibleRange = xAxis.VisibleRange.AsDoubleRange();
if (ParentSurface.ZoomState == ZoomStates.UserZooming)
return currentVisibleRange; // Don't scroll if user is zooming
// The MaxXRange is the VisibleRange on the XAxis if we were to zoom to fit all data
var maxXRange = xAxis.GetMaximumRange().AsDoubleRange();
double xMax = Math.Max(maxXRange.Max, currentVisibleRange.Max);
// Scroll showing latest window size
return new DoubleRange(xMax - _windowSize, xMax);
}
19
View Source File : ScrollingViewportManager.cs
License : MIT License
Project Creator : ABTSoftware
License : MIT License
Project Creator : ABTSoftware
protected override IRange OnCalculateNewXRange(IAxis xAxis)
{
// The Current XAxis VisibleRange
var currentVisibleRange = xAxis.VisibleRange.AsDoubleRange();
if (ParentSurface.ZoomState == ZoomStates.UserZooming)
return currentVisibleRange; // Don't scroll if user is zooming
// The MaxXRange is the VisibleRange on the XAxis if we were to zoom to fit all data
var maxXRange = xAxis.GetMaximumRange().AsDoubleRange();
double xMax = Math.Max(maxXRange.Max, currentVisibleRange.Max);
// Scroll showing latest window size
return new DoubleRange(xMax - _windowSize, xMax);
}
19
View Source File : AutoRangeViewportManager.cs
License : MIT License
Project Creator : ABTSoftware
License : MIT License
Project Creator : ABTSoftware
protected override IRange OnCalculateNewXRange(IAxis xAxis)
{
// The current XAxis VisibleRange
var currentVisibleRange = xAxis.VisibleRange.AsDoubleRange();
if (ParentSurface.ZoomState == ZoomStates.UserZooming)
return currentVisibleRange; // Stop auto-ranging if user is zooming
// The MaxXRange is the VisibleRange on the XAxis if we were to zoom to fit all data
var maxXRange = xAxis.GetMaximumRange().AsDoubleRange();
var xMax = Math.Max(maxXRange.Max, currentVisibleRange.Max);
// Auto-ranging on the XAxis
return new DoubleRange(0.0, xMax);
}
19
View Source File : AdminStatCommands.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
[CommandHandler("landblockperformance", AccessLevel.Advocate, CommandHandlerFlag.None, 0, "Displays a summary of landblock performance statistics")]
public static void HandleLandblockPerformance(Session session, params string[] parameters)
{
var sb = new StringBuilder();
var loadedLandblocks = LandblockManager.GetLoadedLandblocks();
// Filter out landblocks that haven't recorded a certain amount of events
var sortedBy5mAverage = loadedLandblocks.Where(r => r.Monitor5m.EventHistory.TotalEvents >= 10).OrderByDescending(r => r.Monitor5m.EventHistory.AverageEventDuration).Take(10).ToList();
var sortedBy1hrAverage = loadedLandblocks.Where(r => r.Monitor1h.EventHistory.TotalEvents >= 1000).OrderByDescending(r => r.Monitor1h.EventHistory.AverageEventDuration).Take(10).ToList();
var combinedByAverage = sortedBy5mAverage.Concat(sortedBy1hrAverage).Distinct().OrderByDescending(r => Math.Max(r.Monitor5m.EventHistory.AverageEventDuration, r.Monitor1h.EventHistory.AverageEventDuration)).Take(10);
sb.Append($"Most Busy Landblock - By Average{'\n'}");
sb.Append($"~5m Hits Avg Long Last - ~1h Hits Avg Long Last - Location Players Creatures{'\n'}");
foreach (var entry in combinedByAverage)
{
int players = 0, creatures = 0;
foreach (var worldObject in entry.GetAllWorldObjectsForDiagnostics())
{
if (worldObject is Player)
players++;
else if (worldObject is Creature)
creatures++;
}
sb.Append($"{entry.Monitor5m.EventHistory.TotalEvents.ToString().PadLeft(7)} {entry.Monitor5m.EventHistory.AverageEventDuration:N4} {entry.Monitor5m.EventHistory.LongestEvent:N3} {entry.Monitor5m.EventHistory.LastEvent:N3} - " +
$"{entry.Monitor1h.EventHistory.TotalEvents.ToString().PadLeft(7)} {entry.Monitor1h.EventHistory.AverageEventDuration:N4} {entry.Monitor1h.EventHistory.LongestEvent:N3} {entry.Monitor1h.EventHistory.LastEvent:N3} - " +
$"0x{entry.Id.Raw:X8} {players.ToString().PadLeft(7)} {creatures.ToString().PadLeft(9)}{'\n'}");
}
var sortedBy5mLong = loadedLandblocks.OrderByDescending(r => r.Monitor5m.EventHistory.LongestEvent).Take(10);
var sortedBy1hrLong = loadedLandblocks.OrderByDescending(r => r.Monitor1h.EventHistory.LongestEvent).Take(10);
var combinedByLong = sortedBy5mLong.Concat(sortedBy1hrLong).Distinct().OrderByDescending(r => Math.Max(r.Monitor5m.EventHistory.LongestEvent, r.Monitor1h.EventHistory.LongestEvent)).Take(10);
sb.Append($"Most Busy Landblock - By Longest{'\n'}");
sb.Append($"~5m Hits Avg Long Last - ~1h Hits Avg Long Last - Location Players Creatures{'\n'}");
foreach (var entry in combinedByLong)
{
int players = 0, creatures = 0;
foreach (var worldObject in entry.GetAllWorldObjectsForDiagnostics())
{
if (worldObject is Player)
players++;
else if (worldObject is Creature)
creatures++;
}
sb.Append($"{entry.Monitor5m.EventHistory.TotalEvents.ToString().PadLeft(7)} {entry.Monitor5m.EventHistory.AverageEventDuration:N4} {entry.Monitor5m.EventHistory.LongestEvent:N3} {entry.Monitor5m.EventHistory.LastEvent:N3} - " +
$"{entry.Monitor1h.EventHistory.TotalEvents.ToString().PadLeft(7)} {entry.Monitor1h.EventHistory.AverageEventDuration:N4} {entry.Monitor1h.EventHistory.LongestEvent:N3} {entry.Monitor1h.EventHistory.LastEvent:N3} - " +
$"0x{entry.Id.Raw:X8} {players.ToString().PadLeft(7)} {creatures.ToString().PadLeft(9)}{'\n'}");
}
CommandHandlerHelper.WriteOutputInfo(session, sb.ToString());
}
19
View Source File : Fellowship.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public double GetDistanceScalar(Player earner, Player fellow, XpType xpType)
{
if (earner == null || fellow == null)
return 0.0f;
if (xpType == XpType.Quest)
return 1.0f;
// https://asheron.fandom.com/wiki/Announcements_-_2004/01_-_Mirror,_Mirror#Rollout_Article
// If they are indoors while you are outdoors, or vice-versa.
if (earner.Location.Indoors != fellow.Location.Indoors)
return 0.0f;
// If you are both indoors but in different landblocks.
if (earner.Location.Indoors && fellow.Location.Indoors && earner.Location.Landblock != fellow.Location.Landblock)
return 0.0f;
var dist = earner.Location.Distance2D(fellow.Location);
if (dist >= MaxDistance * 2.0f)
return 0.0f;
if (dist <= MaxDistance)
return 1.0f;
var scalar = 1.0f - (dist - MaxDistance) / MaxDistance;
return Math.Max(0.0f, scalar);
}
19
View Source File : LandblockGroup.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public int BoundaryDistance(Landblock landblock)
{
return (int)Math.Max(
Math.Abs(xCenter - landblock.Id.LandblockX) - (width + 1) / 2.0,
Math.Abs(yCenter - landblock.Id.LandblockY) - (height + 1) / 2.0);
}
19
View Source File : PositionExtensions.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public static uint CellDist(this Position p1, Position p2)
{
if (!p1.Indoors && !p2.Indoors)
{
return Math.Max(p1.GlobalCellX, p1.GlobalCellY);
}
// handle dungeons
/*var block1 = LScape.get_landblock(p1.LandblockId.Raw);
var block2 = LScape.get_landblock(p2.LandblockId.Raw);
if (block1.IsDungeon || block2.IsDungeon)
{
// 2 separate dungeons = infinite distance
if (block1.ID != block2.ID)
return uint.MaxValue;
return GetDungeonCellDist(p1, p2);
}*/
var _p1 = new Position(p1);
var _p2 = new Position(p2);
if (_p1.Indoors)
_p1.LandblockId = new LandblockId(_p1.GetOutdoorCell());
if (_p2.Indoors)
_p2.LandblockId = new LandblockId(_p2.GetIndoorCell());
return Math.Max(_p1.GlobalCellX, _p2.GlobalCellY);
}
19
View Source File : CantripChance.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public static void ApplyNumCantripsMod(bool showResults = true)
{
// scales NumCantrips, no chance vs. chance, relative to each other
var cantrip_drop_rate = (float)Math.Max(0.0f, PropertyManager.GetDouble("cantrip_drop_rate").Item);
if (cantrip_drop_rate != 1.0f)
{
var newTable = new List<ChanceTable<int>>();
foreach (var entry in _numCantrips)
{
var newEntry = ScaleNumCantrips(entry, cantrip_drop_rate);
newTable.Add(newEntry);
}
numCantrips = newTable;
}
else
numCantrips = _numCantrips;
if (showResults)
{
log.Info($"ApplyNumCantripsMod({cantrip_drop_rate})");
log.Info("");
ShowTables(numCantrips);
}
}
19
View Source File : CantripChance.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public static void ApplyCantripLevelsMod(bool showResults = true)
{
// scales CantripLevels, relative to each other
var minor_cantrip_drop_rate = (float)Math.Max(0.0f, PropertyManager.GetDouble("minor_cantrip_drop_rate").Item);
var major_cantrip_drop_rate = (float)Math.Max(0.0f, PropertyManager.GetDouble("major_cantrip_drop_rate").Item);
var epic_cantrip_drop_rate = (float)Math.Max(0.0f, PropertyManager.GetDouble("epic_cantrip_drop_rate").Item);
var legendary_cantrip_drop_rate = (float)Math.Max(0.0f, PropertyManager.GetDouble("legendary_cantrip_drop_rate").Item);
if (minor_cantrip_drop_rate != 1.0f || major_cantrip_drop_rate != 1.0f || epic_cantrip_drop_rate != 1.0f || legendary_cantrip_drop_rate != 1.0f)
{
var newTable = new List<ChanceTable<int>>();
foreach (var entry in _cantripLevels)
{
var newEntry = ScaleCantripLevels(entry, minor_cantrip_drop_rate, major_cantrip_drop_rate, epic_cantrip_drop_rate, legendary_cantrip_drop_rate);
newTable.Add(newEntry);
}
cantripLevels = newTable;
}
else
cantripLevels = _cantripLevels;
if (showResults)
{
log.Info($"ApplyCantripLevelsMod({minor_cantrip_drop_rate}, {major_cantrip_drop_rate}, {epic_cantrip_drop_rate}, {legendary_cantrip_drop_rate})");
log.Info("");
ShowTables(cantripLevels);
}
}
19
View Source File : LootGenerationFactory_Clothing.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
private static void MutateValue_Armor(WorldObject wo)
{
var bulkMod = wo.BulkMod ?? 1.0f;
var sizeMod = wo.SizeMod ?? 1.0f;
var armorLevel = wo.ArmorLevel ?? 0;
// from the py16 mutation scripts
//wo.Value += (int)(armorLevel * armorLevel / 10.0f * bulkMod * sizeMod);
// still probably not how retail did it
// modified for armor values to match closer to retail pcaps
var minRng = (float)Math.Min(bulkMod, sizeMod);
var maxRng = (float)Math.Max(bulkMod, sizeMod);
var rng = ThreadSafeRandom.Next(minRng, maxRng);
wo.Value += (int)(armorLevel * armorLevel / 10.0f * rng);
}
19
View Source File : WeaponProfile.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public uint GetDamage(WorldObject weapon)
{
var baseDamage = weapon.GetProperty(PropertyInt.Damage) ?? 0;
var damageBonus = weapon.EnchantmentManager.GetDamageBonus();
var auraDamageBonus = weapon.Wielder != null && (weapon.WeenieType != WeenieType.Ammunition || PropertyManager.GetBool("show_ammo_buff").Item) ? weapon.Wielder.EnchantmentManager.GetDamageBonus() : 0;
Enchantment_Damage = weapon.IsEnchantable ? damageBonus + auraDamageBonus : damageBonus;
return (uint)Math.Max(0, baseDamage + Enchantment_Damage);
}
19
View Source File : WeaponProfile.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public uint GetWeaponSpeed(WorldObject weapon)
{
var baseSpeed = weapon.GetProperty(PropertyInt.WeaponTime) ?? 0; // safe to replacedume defaults here?
var speedMod = weapon.EnchantmentManager.GetWeaponSpeedMod();
var auraSpeedMod = weapon.Wielder != null ? weapon.Wielder.EnchantmentManager.GetWeaponSpeedMod() : 0;
Enchantment_WeaponTime = weapon.IsEnchantable ? speedMod + auraSpeedMod : speedMod;
return (uint)Math.Max(0, baseSpeed + Enchantment_WeaponTime);
}
19
View Source File : DamageEvent.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
private float DoCalculateDamage(Creature attacker, Creature defender, WorldObject damageSource)
{
var playerAttacker = attacker as Player;
var playerDefender = defender as Player;
var pkBattle = playerAttacker != null && playerDefender != null;
Attacker = attacker;
Defender = defender;
CombatType = damageSource.ProjectileSource == null ? CombatType.Melee : CombatType.Missile;
DamageSource = damageSource;
Weapon = damageSource.ProjectileSource == null ? attacker.GetEquippedMeleeWeapon() : (damageSource.ProjectileLauncher ?? damageSource.ProjectileAmmo);
AttackType = attacker.AttackType;
AttackHeight = attacker.AttackHeight ?? AttackHeight.Medium;
// check lifestone protection
if (playerDefender != null && playerDefender.UnderLifestoneProtection)
{
LifestoneProtection = true;
playerDefender.HandleLifestoneProtection();
return 0.0f;
}
if (defender.Invincible)
return 0.0f;
// overpower
if (attacker.Overpower != null)
Overpower = Creature.GetOverpower(attacker, defender);
// evasion chance
if (!Overpower)
{
EvasionChance = GetEvadeChance(attacker, defender);
if (EvasionChance > ThreadSafeRandom.Next(0.0f, 1.0f))
{
Evaded = true;
return 0.0f;
}
}
// get base damage
if (playerAttacker != null)
GetBaseDamage(playerAttacker);
else
GetBaseDamage(attacker, AttackMotion ?? MotionCommand.Invalid, AttackHook);
if (DamageType == DamageType.Undef && !AllowDamageTypeUndef.Contains(damageSource.WeenieClreplacedId))
{
log.Error($"DamageEvent.DoCalculateDamage({attacker?.Name} ({attacker?.Guid}), {defender?.Name} ({defender?.Guid}), {damageSource?.Name} ({damageSource?.Guid})) - DamageType == DamageType.Undef");
GeneralFailure = true;
}
if (GeneralFailure) return 0.0f;
// get damage modifiers
PowerMod = attacker.GetPowerMod(Weapon);
AttributeMod = attacker.GetAttributeMod(Weapon);
SlayerMod = WorldObject.GetWeaponCreatureSlayerModifier(Weapon, attacker, defender);
// ratings
DamageRatingBaseMod = Creature.GetPositiveRatingMod(attacker.GetDamageRating());
RecklessnessMod = Creature.GetRecklessnessMod(attacker, defender);
SneakAttackMod = attacker.GetSneakAttackMod(defender);
HeritageMod = attacker.GetHeritageBonus(Weapon) ? 1.05f : 1.0f;
DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, RecklessnessMod, SneakAttackMod, HeritageMod);
if (pkBattle)
{
PkDamageMod = Creature.GetPositiveRatingMod(attacker.GetPKDamageRating());
DamageRatingMod = Creature.AdditiveCombine(DamageRatingMod, PkDamageMod);
}
// damage before mitigation
DamageBeforeMitigation = BaseDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod;
// critical hit?
var attackSkill = attacker.GetCreatureSkill(attacker.GetCurrentWeaponSkill());
CriticalChance = WorldObject.GetWeaponCriticalChance(Weapon, attacker, attackSkill, defender);
// https://asheron.fandom.com/wiki/Announcements_-_2002/08_-_Atonement
// It should be noted that any time a character is logging off, PK or not, all physical attacks against them become automatically critical.
// (Note that spells do not share this behavior.) We hope this will stress the need to log off in a safe place.
if (playerDefender != null && (playerDefender.IsLoggingOut || playerDefender.PKLogout))
CriticalChance = 1.0f;
if (CriticalChance > ThreadSafeRandom.Next(0.0f, 1.0f))
{
if (playerDefender != null && playerDefender.AugmentationCriticalDefense > 0)
{
var criticalDefenseMod = playerAttacker != null ? 0.05f : 0.25f;
var criticalDefenseChance = playerDefender.AugmentationCriticalDefense * criticalDefenseMod;
if (criticalDefenseChance > ThreadSafeRandom.Next(0.0f, 1.0f))
CriticalDefended = true;
}
if (!CriticalDefended)
{
IsCritical = true;
// verify: CriticalMultiplier only applied to the additional crit damage,
// whereas CD/CDR applied to the total damage (base damage + additional crit damage)
CriticalDamageMod = 1.0f + WorldObject.GetWeaponCritDamageMod(Weapon, attacker, attackSkill, defender);
CriticalDamageRatingMod = Creature.GetPositiveRatingMod(attacker.GetCritDamageRating());
// recklessness excluded from crits
RecklessnessMod = 1.0f;
DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, CriticalDamageRatingMod, SneakAttackMod, HeritageMod);
if (pkBattle)
DamageRatingMod = Creature.AdditiveCombine(DamageRatingMod, PkDamageMod);
DamageBeforeMitigation = BaseDamageMod.MaxDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod * CriticalDamageMod;
}
}
// armor rending and cleaving
var armorRendingMod = 1.0f;
if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.ArmorRending))
armorRendingMod = WorldObject.GetArmorRendingMod(attackSkill);
var armorCleavingMod = attacker.GetArmorCleavingMod(Weapon);
var ignoreArmorMod = Math.Min(armorRendingMod, armorCleavingMod);
// get body part / armor pieces / armor modifier
if (playerDefender != null)
{
// select random body part @ current attack height
GetBodyPart(AttackHeight);
// get player armor pieces
Armor = attacker.GetArmorLayers(playerDefender, BodyPart);
// get armor modifiers
ArmorMod = attacker.GetArmorMod(playerDefender, DamageType, Armor, Weapon, ignoreArmorMod);
}
else
{
// determine height quadrant
Quadrant = GetQuadrant(Defender, Attacker, AttackHeight, DamageSource);
// select random body part @ current attack height
GetBodyPart(Defender, Quadrant);
if (Evaded)
return 0.0f;
Armor = CreaturePart.GetArmorLayers(PropertiesBodyPart.Key);
// get target armor
ArmorMod = CreaturePart.GetArmorMod(DamageType, Armor, Attacker, Weapon, ignoreArmorMod);
}
if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.IgnoreAllArmor))
ArmorMod = 1.0f;
// get resistance modifiers
WeaponResistanceMod = WorldObject.GetWeaponResistanceModifier(Weapon, attacker, attackSkill, DamageType);
if (playerDefender != null)
{
ResistanceMod = playerDefender.GetResistanceMod(DamageType, Attacker, Weapon, WeaponResistanceMod);
}
else
{
var resistanceType = Creature.GetResistanceType(DamageType);
ResistanceMod = (float)Math.Max(0.0f, defender.GetResistanceMod(resistanceType, Attacker, Weapon, WeaponResistanceMod));
}
// damage resistance rating
DamageResistanceRatingMod = DamageResistanceRatingBaseMod = defender.GetDamageResistRatingMod(CombatType);
if (IsCritical)
{
CriticalDamageResistanceRatingMod = Creature.GetNegativeRatingMod(defender.GetCritDamageResistRating());
DamageResistanceRatingMod = Creature.AdditiveCombine(DamageResistanceRatingBaseMod, CriticalDamageResistanceRatingMod);
}
if (pkBattle)
{
PkDamageResistanceMod = Creature.GetNegativeRatingMod(defender.GetPKDamageResistRating());
DamageResistanceRatingMod = Creature.AdditiveCombine(DamageResistanceRatingMod, PkDamageResistanceMod);
}
// get shield modifier
ShieldMod = defender.GetShieldMod(attacker, DamageType, Weapon);
// calculate final output damage
Damage = DamageBeforeMitigation * ArmorMod * ShieldMod * ResistanceMod * DamageResistanceRatingMod;
DamageMitigated = DamageBeforeMitigation - Damage;
return Damage;
}
19
View Source File : ParticleEmitterInfo.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public double GetRandomLifespan()
{
var result = ThreadSafeRandom.Next(-1.0f, 1.0f) * LifeSpanRand + LifeSpan;
result = Math.Max(0.0f, result);
return result;
}
19
View Source File : CreatureAttribute.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public uint GetCurrent(bool enchanted)
{
var multipliers = enchanted ? creature.EnchantmentManager.GetAttributeMod_Multiplier(Attribute) : 1.0f;
var additives = enchanted ? creature.EnchantmentManager.GetAttributeMod_Additive(Attribute) : 0;
var total = (int)Base * multipliers + additives;
total = total.Round();
return (uint)Math.Max(total, 10); // minimum value for an attribute: 10
}
19
View Source File : CreatureVital.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public uint GetMaxValue(bool enchanted)
{
var attr = AttributeFormula.GetFormula(creature, Vital, true);
uint total = StartingValue + Ranks + attr;
var player = creature as Player;
if (player != null)
{
// Enlightenment and GearMaxHealth didn't work like other additives
// most additives (ie. from enchantments) were added in *after* multipliers,
// but Enlightenment and GearMaxHealth were an exception, and added in beforehand
// this means Enlightenment and GearMaxHealth would get scaled by multipliers,
// including Asheron's Benediction, and oddly enough, vitae as well
// it's also possible these were considered "base"
if (Vital == PropertyAttribute2nd.MaxHealth)
total += (uint)(player.Enlightenment * 2 + player.GetGearMaxHealth());
}
// apply multiplicative enchantments first
var multiplier = enchanted ? creature.EnchantmentManager.GetVitalMod_Multiplier(this) : 1.0f;
var fTotal = total * multiplier;
if (player != null)
{
var vitae = player.Vitae;
if (vitae != 1.0f)
fTotal *= vitae;
}
// everything beyond this point does not get scaled by vitae
var additives = enchanted ? creature.EnchantmentManager.GetVitalMod_Additives(this) : 0;
var iTotal = (fTotal + additives).Round();
iTotal = Math.Max(iTotal, 5); // a creature cannot fall below 5 MaxVital from vitae
return (uint)iTotal;
}
19
View Source File : Corpse.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public void RecalculateDecayTime(Player player)
{
// empty corpses decay faster
if (Inventory.Count == 0)
TimeToRot = EmptyDecayTime;
else
// a player corpse decays after 5 mins * playerLevel with a minimum of 1 hour
TimeToRot = Math.Max(3600, (player.Level ?? 1) * 300);
var dtTimeToRot = DateTime.UtcNow.AddSeconds(TimeToRot ?? 0);
var tsDecay = dtTimeToRot - DateTime.UtcNow;
Level = player.Level ?? 1;
log.Debug($"[CORPSE] {Name}.RecalculateDecayTime({player.Name}) 0x{Guid}: Player Level: {player.Level} | Inventory.Count: {Inventory.Count} | TimeToRot: {TimeToRot} | CreationTimestamp: {CreationTimestamp} ({Time.GetDateTimeFromTimestamp(CreationTimestamp ?? 0).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss")}) | Corpse should not decay before: {dtTimeToRot.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss")}, {tsDecay.ToString("%d")} day(s), {tsDecay.ToString("%h")} hours, {tsDecay.ToString("%m")} minutes, and {tsDecay.ToString("%s")} seconds from now.");
}
19
View Source File : Lock.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public static int? GetResistLockpick(WorldObject wo)
{
if (!(wo is Lock)) return null;
// if base ResistLockpick without enchantments is unpickable,
// do not apply enchantments
var isPickable = IsPickable(wo);
if (!isPickable)
return wo.ResistLockpick;
var resistLockpick = wo.ResistLockpick.Value;
var enchantmentMod = wo.EnchantmentManager.GetResistLockpick();
var difficulty = resistLockpick + enchantmentMod;
// minimum 0 difficulty
difficulty = Math.Max(0, difficulty);
return difficulty;
}
19
View Source File : ManaStone.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public override void HandleActionUseOnTarget(Player player, WorldObject target)
{
WorldObject invTarget;
var useResult = WeenieError.None;
if (player.IsOlthoiPlayer)
{
player.SendUseDoneEvent(WeenieError.OlthoiCannotInteractWithThat);
return;
}
if (player != target)
{
invTarget = player.FindObject(target.Guid.Full, Player.SearchLocations.MyInventory | Player.SearchLocations.MyEquippedItems);
if (invTarget == null)
{
// Haven't looked to see if an error was sent for this case; however, this one fits
player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, WeenieError.YouDoNotOwnThareplacedem));
return;
}
target = invTarget;
}
if (!ItemCurMana.HasValue)
{
if (target == player)
useResult = WeenieError.ActionCancelled;
else if (target.ItemCurMana.HasValue && target.ItemCurMana.Value > 0 && target.ItemMaxMana.HasValue && target.ItemMaxMana.Value > 0)
{
// absorb mana from the item
if (target.Retained)
useResult = WeenieError.ActionCancelled;
else
{
if (!player.TryConsumeFromInventoryWithNetworking(target, 1) && !player.TryDequipObjectWithNetworking(target.Guid, out _, Player.DequipObjectAction.ConsumeItem))
{
log.Error($"Failed to remove {target.Name} from player inventory.");
player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, WeenieError.ActionCancelled));
return;
}
//The Mana Stone drains 5,253 points of mana from the Wand.
//The Wand is destroyed.
//The Mana Stone drains 4,482 points of mana from the Pantaloons.
//The Pantaloons is destroyed.
var manaDrained = (int)Math.Round(Efficiency.Value * target.ItemCurMana.Value);
ItemCurMana = manaDrained;
player.Session.Network.EnqueueSend(new GameMessageSystemChat($"The Mana Stone drains {ItemCurMana:N0} points of mana from the {target.Name}.\nThe {target.Name} is destroyed.", ChatMessageType.Broadcast));
SetUiEffect(player, ACE.Enreplacedy.Enum.UiEffects.Magical);
}
}
else
{
useResult = WeenieError.ItemDoesntHaveEnoughMana;
}
}
else if (ItemCurMana.Value > 0)
{
if (target == player)
{
// dump mana into equipped items
var origItemsNeedingMana = player.EquippedObjects.Values.Where(k => k.ItemCurMana.HasValue && k.ItemMaxMana.HasValue && k.ItemCurMana < k.ItemMaxMana).ToList();
var itemsGivenMana = new Dictionary<WorldObject, int>();
while (ItemCurMana > 0)
{
var itemsNeedingMana = origItemsNeedingMana.Where(k => k.ItemCurMana < k.ItemMaxMana).ToList();
if (itemsNeedingMana.Count < 1)
break;
var ration = Math.Max(ItemCurMana.Value / itemsNeedingMana.Count, 1);
foreach (var item in itemsNeedingMana)
{
var manaNeededForTopoff = (int)(item.ItemMaxMana - item.ItemCurMana);
var adjustedRation = Math.Min(ration, manaNeededForTopoff);
ItemCurMana -= adjustedRation;
if (player.LumAugItemManaGain != 0)
{
adjustedRation = (int)Math.Round(adjustedRation * Creature.GetPositiveRatingMod(player.LumAugItemManaGain * 5));
if (adjustedRation > manaNeededForTopoff)
{
var diff = adjustedRation - manaNeededForTopoff;
adjustedRation = manaNeededForTopoff;
ItemCurMana += diff;
}
}
item.ItemCurMana += adjustedRation;
if (!itemsGivenMana.ContainsKey(item))
itemsGivenMana[item] = adjustedRation;
else
itemsGivenMana[item] += adjustedRation;
if (ItemCurMana <= 0)
break;
}
}
if (itemsGivenMana.Count < 1)
{
player.Session.Network.EnqueueSend(new GameMessageSystemChat("You have no items equipped that need mana.", ChatMessageType.Broadcast));
useResult = WeenieError.ActionCancelled;
}
else
{
//The Mana Stone gives 4,496 points of mana to the following items: Fire Compound Crossbow, Qafiya, Celdon Sleeves, Amuli Leggings, Messenger's Collar, Heavy Bracelet, Scalemail Bracers, Olthoi Alduressa Gauntlets, Studded Leather Girth, Shoes, Chainmail Greaves, Loose Pants, Mechanical Scarab, Ring, Ring, Heavy Bracelet
//Your items are fully charged.
//The Mana Stone gives 1,921 points of mana to the following items: Haebrean Girth, Chiran Helm, Ring, Baggy Breeches, Scalemail Greaves, Alduressa Boots, Heavy Bracelet, Heavy Bracelet, Lorica Breastplate, Pocket Watch, Heavy Necklace
//You need 2,232 more mana to fully charge your items.
var additionalManaNeeded = origItemsNeedingMana.Sum(k => k.ItemMaxMana.Value - k.ItemCurMana.Value);
var additionalManaText = (additionalManaNeeded > 0) ? $"\nYou need {additionalManaNeeded:N0} more mana to fully charge your items." : "\nYour items are fully charged.";
var msg = $"The Mana Stone gives {itemsGivenMana.Values.Sum():N0} points of mana to the following items: {itemsGivenMana.Select(c => c.Key.Name).Aggregate((a, b) => a + ", " + b)}.{additionalManaText}";
player.Session.Network.EnqueueSend(new GameMessageSystemChat(msg, ChatMessageType.Broadcast));
if (!DoDestroyDiceRoll(player) && !UnlimitedUse)
{
ItemCurMana = null;
SetUiEffect(player, ACE.Enreplacedy.Enum.UiEffects.Undef);
}
if (UnlimitedUse && ItemMaxMana.HasValue)
ItemCurMana = ItemMaxMana;
}
}
else if (target.ItemMaxMana.HasValue && target.ItemMaxMana.Value > 0)
{
var targereplacedemCurMana = target.ItemCurMana ?? 0;
if (targereplacedemCurMana >= target.ItemMaxMana)
{
player.Session.Network.EnqueueSend(new GameMessageSystemChat($"The {target.Name} is already full of mana.", ChatMessageType.Broadcast));
}
else
{
// The Mana Stone gives 3,502 points of mana to the Focusing Stone.
// The Mana Stone gives 3,267 points of mana to the Protective Drudge Charm.
var targetManaNeeded = target.ItemMaxMana.Value - targereplacedemCurMana;
var manaToPour = Math.Min(targetManaNeeded, ItemCurMana.Value);
if (player.LumAugItemManaGain != 0)
{
manaToPour = (int)Math.Round(manaToPour * Creature.GetPositiveRatingMod(player.LumAugItemManaGain * 5));
manaToPour = Math.Min(targetManaNeeded, manaToPour);
}
target.ItemCurMana = targereplacedemCurMana + manaToPour;
var msg = $"The Mana Stone gives {manaToPour:N0} points of mana to the {target.Name}.";
player.Session.Network.EnqueueSend(new GameMessageSystemChat(msg, ChatMessageType.Broadcast));
if (!DoDestroyDiceRoll(player) && !UnlimitedUse)
{
ItemCurMana = null;
SetUiEffect(player, ACE.Enreplacedy.Enum.UiEffects.Undef);
}
}
}
else
{
useResult = WeenieError.ActionCancelled;
}
}
player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, useResult));
}
19
View Source File : Monster_Combat.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator
public virtual uint TakeDamage(WorldObject source, DamageType damageType, float amount, bool crit = false)
{
var tryDamage = (int)Math.Round(amount);
var damage = -UpdateVitalDelta(Health, -tryDamage);
// TODO: update monster stamina?
// source should only be null for combined DoT ticks from multiple sources
if (source != null)
{
if (damage >= 0)
DamageHistory.Add(source, damageType, (uint)damage);
else
DamageHistory.OnHeal((uint)-damage);
}
if (Health.Current <= 0)
{
OnDeath(DamageHistory.LastDamager, damageType, crit);
Die();
}
return (uint)Math.Max(0, damage);
}
See More Examples