Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion IconsBuilder/Icons/BaseIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,11 @@ public BaseIcon(Entity entity)
public Func<bool> Show { get; set; }
public Func<bool> Hidden { get; protected set; } = () => false;
public HudTexture MainTexture { get; protected set; }
public System.Drawing.Color? BorderColor { get; protected set; } = null;
public Color? BorderColor { get; protected set; } = null;
public IconPriority Priority { get; protected set; }
public MonsterRarity Rarity { get; protected set; }
public string Text { get; protected set; }
public Color? TextColor { get; protected set; } = null;
public Color? BackgroundColor { get; protected set; } = null;
public string RenderName => Entity.RenderName;
}
50 changes: 33 additions & 17 deletions IconsBuilder/Icons/MonsterIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@
using ExileCore.Shared.Enums;
using ExileCore.Shared.Helpers;
using GameOffsets.Native;
using MinimapIcons;

namespace MinimapIcons.IconsBuilder.Icons;

public class MonsterIcon : BaseIcon
{
public MonsterIcon(Entity entity, IconsBuilderSettings settings, Dictionary<string, Vector2i> modIcons)
public MonsterIcon(Entity entity, IconsBuilderSettings settings, Dictionary<string, Vector2i> modIcons, MapIconsSettings mapSettings)
: base(entity)
{
Update(entity, settings, modIcons);
Update(entity, settings, modIcons, mapSettings);
}

public void Update(Entity entity, IconsBuilderSettings settings, Dictionary<string, Vector2i> modIcons)
public void Update(Entity entity, IconsBuilderSettings settings, Dictionary<string, Vector2i> modIcons, MapIconsSettings mapSettings)
{
Show = () => entity.IsAlive;
if(entity.IsHidden && settings.HideBurriedMonsters)
Expand All @@ -43,10 +44,11 @@ public void Update(Entity entity, IconsBuilderSettings settings, Dictionary<stri
MainTexture.Size *= 2;
}

if (_HasIngameIcon &&
entity.TryGetComponent<MinimapIcon>(out var mI) &&
if (_HasIngameIcon &&
entity.TryGetComponent<MinimapIcon>(out var mI) &&
mI.Name != "NPC" &&
!isMonsterWithIcon)
!isMonsterWithIcon &&
!mapSettings.MonstersIgnoreMinimapIconComponent)
return;
if (!entity.IsHostile)
{
Expand All @@ -73,9 +75,7 @@ public void Update(Entity entity, IconsBuilderSettings settings, Dictionary<stri
}

if (settings.HighlightEldritchMonsters &&
(entity.Path.StartsWith("Metadata/Monsters/AtlasInvaders/BlackStarMonsters/", StringComparison.Ordinal) ||
entity.Path.StartsWith("Metadata/Monsters/AtlasInvaders/CleansingMonsters/", StringComparison.Ordinal)||
entity.Path.StartsWith("Metadata/Monsters/AtlasInvaders/DoomMonsters/", StringComparison.Ordinal)))
entity.Path.StartsWith("Metadata/Monsters/AtlasInvaders/", StringComparison.Ordinal))
{
BorderColor = settings.EldritchMonstersColor.Value.ToSystem();
}
Expand All @@ -91,29 +91,45 @@ public void Update(Entity entity, IconsBuilderSettings settings, Dictionary<stri
switch (Rarity)
{
case MonsterRarity.White:
if (!isMonsterWithIcon)
MainTexture.UV = SpriteHelper.GetUV(MapIconsIndex.LootFilterLargeRedCircle);
if (!isMonsterWithIcon) MainTexture.UV = SpriteHelper.GetUV(MapIconsIndex.LootFilterLargeRedCircle);
if (settings.MonsterRarityNames.ShowNormalNames)
{
Text = RenderName.Split(',').FirstOrDefault();
TextColor = settings.MonsterRarityNames.TextColor.Value.ToSystem();
if (settings.MonsterRarityNames.NameBackground) BackgroundColor = settings.MonsterRarityNames.BackgroundColor.Value.ToSystem();
}

break;
case MonsterRarity.Magic:
if (!isMonsterWithIcon)
MainTexture.UV = SpriteHelper.GetUV(MapIconsIndex.LootFilterLargeBlueCircle);
if (!isMonsterWithIcon) MainTexture.UV = SpriteHelper.GetUV(MapIconsIndex.LootFilterLargeBlueCircle);
if (settings.MonsterRarityNames.ShowMagicNames)
{
Text = RenderName.Split(',').FirstOrDefault();
TextColor = settings.MonsterRarityNames.TextColor.Value.ToSystem();
if (settings.MonsterRarityNames.NameBackground) BackgroundColor = settings.MonsterRarityNames.BackgroundColor.Value.ToSystem();
}

break;
case MonsterRarity.Rare:
if (!isMonsterWithIcon)
MainTexture.UV = SpriteHelper.GetUV(MapIconsIndex.LootFilterLargeYellowCircle);
if (!isMonsterWithIcon) MainTexture.UV = SpriteHelper.GetUV(MapIconsIndex.LootFilterLargeYellowCircle);
if (settings.MonsterRarityNames.ShowRareNames)
{
Text = RenderName.Split(',').FirstOrDefault();
TextColor = settings.MonsterRarityNames.TextColor.Value.ToSystem();
if (settings.MonsterRarityNames.NameBackground) BackgroundColor = settings.MonsterRarityNames.BackgroundColor.Value.ToSystem();
}

break;
case MonsterRarity.Unique:
if (!isMonsterWithIcon)
MainTexture.UV = SpriteHelper.GetUV(MapIconsIndex.LootFilterLargeWhiteHexagon);
if (!isMonsterWithIcon) MainTexture.UV = SpriteHelper.GetUV(MapIconsIndex.LootFilterLargeWhiteHexagon);
MainTexture.Color = Color.DarkOrange;
if (settings.MonsterRarityNames.ShowUniqueNames)
{
Text = RenderName.Split(',').FirstOrDefault();
TextColor = settings.MonsterRarityNames.TextColor.Value.ToSystem();
if (settings.MonsterRarityNames.NameBackground) BackgroundColor = settings.MonsterRarityNames.BackgroundColor.Value.ToSystem();
}

break;
default:
throw new ArgumentOutOfRangeException(
Expand Down
11 changes: 6 additions & 5 deletions IconsBuilder/IconsBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -85,7 +85,7 @@ public void AreaChange(AreaInstance area)

public bool Initialise()
{
Settings.ResetIcons.OnPressed = () => { IconVersion++; };
Settings.ReloadIcons.OnPressed = () => { IconVersion++; };
ReadAlertFile();
ReadIgnoreFile();
return true;
Expand Down Expand Up @@ -158,8 +158,9 @@ worldItem.Icon is var icon &&

if (Settings.UseReplacementsForGameIconsWhenOutOfRange &&
entity.TryGetComponent<MinimapIcon>(out var minimapIconComponent) &&
(!minimapIconComponent.IsHide || _plugin.Settings.IgnoreHiddenStatusMinimapIcons.Content.Any(x => GetRegex(x.Value).IsMatch(entity.Path))) &&
!Settings.MonstersWithIcons.Content.Any(x => GetRegex(x.Value).IsMatch(entity.Path)))
(!minimapIconComponent.IsHide || _plugin.Settings.IgnoreHiddenStatusMinimapIcons.Content.Any(x => GetRegex(x.Value).IsMatch(entity.Path))) &&
!Settings.MonstersWithIcons.Content.Any(x => GetRegex(x.Value).IsMatch(entity.Path)) &&
!(entity.Type == EntityType.Monster && _plugin.Settings.MonstersIgnoreMinimapIconComponent))
{
var name = minimapIconComponent.Name;
if (!string.IsNullOrEmpty(name))
Expand All @@ -178,7 +179,7 @@ worldItem.Icon is var icon &&
if (entity.League == LeagueType.Delirium)
return new DeliriumIcon(entity, Settings, AlertEntitiesWithIconSize);

return new MonsterIcon(entity, Settings, AlertEntitiesWithIconSize);
return new MonsterIcon(entity, Settings, AlertEntitiesWithIconSize, _plugin.Settings);
}

//NPC
Expand Down
5 changes: 4 additions & 1 deletion IconsBuilder/IconsBuilderSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public class IconsBuilderSettings
public RangeNode<int> SizeShrineIcon { get; set; } = new RangeNode<int>(10, 1, 50);

[JsonIgnore]
public ButtonNode ResetIcons { get; set; } = new();
public ButtonNode ReloadIcons { get; set; } = new();

[Menu(null, CollapsedByDefault = true)]
public ContentNode<TextNode> MonstersWithIcons { get; set; } =
Expand Down Expand Up @@ -113,6 +113,9 @@ public class MonsterNameSettings
public ToggleNode ShowMagicNames { get; set; } = new ToggleNode(false);
public ToggleNode ShowRareNames { get; set; } = new ToggleNode(false);
public ToggleNode ShowUniqueNames { get; set; } = new ToggleNode(true);
public ToggleNode NameBackground { get; set; } = new ToggleNode(true);
public ColorNode TextColor { get; set; } = new ColorNode(Color.White);
public ColorNode BackgroundColor { get; set; } = new ColorNode(new Color(0, 0, 0, 150));
}

[Submenu]
Expand Down
3 changes: 2 additions & 1 deletion MapIconsSettings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using ExileCore.Shared.Attributes;
using ExileCore.Shared.Attributes;
using ExileCore.Shared.Interfaces;
using ExileCore.Shared.Nodes;
using MinimapIcons.IconsBuilder;
Expand All @@ -20,6 +20,7 @@ public class MapIconsSettings : ISettings
public ToggleNode Enable { get; set; } = new ToggleNode(true);
public RangeNode<int> IconListRefreshPeriod { get; set; } = new RangeNode<int>(100, 0, 1000);
public ToggleNode HighlightHiddenMonsters { get; set; } = new ToggleNode(true);
public ToggleNode MonstersIgnoreMinimapIconComponent { get; set; } = new ToggleNode(false);

[Menu(null, CollapsedByDefault = true)]
public ContentNode<TextNode> AlwaysShownIngameIcons { get; set; } =
Expand Down
144 changes: 56 additions & 88 deletions MinimapIcons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Linq;
using ExileCore;
using ExileCore.PoEMemory.Components;
using ExileCore.PoEMemory.Elements;
using ExileCore.PoEMemory.MemoryObjects;
using ExileCore.Shared.Cache;
using ExileCore.Shared.Enums;
Expand Down Expand Up @@ -159,9 +158,6 @@ public class MinimapIcons : BaseSettingsPlugin<MapIconsSettings>

private IngameUIElements _ingameUi;
private bool? _largeMap;
private float _mapScale;
private Vector2 _mapCenter;
private SubMap LargeMapWindow => GameController.Game.IngameState.IngameUi.Map.LargeMap;
private CachedValue<List<BaseIcon>> _iconListCache;
private IconsBuilder.IconsBuilder _iconsBuilder;
private IconsBuilder.IconsBuilder IconsBuilder => _iconsBuilder ??= new IconsBuilder.IconsBuilder(this);
Expand Down Expand Up @@ -207,17 +203,11 @@ public override Job Tick()
var smallMiniMap = _ingameUi.Map.SmallMiniMap;
if (smallMiniMap.IsValid && smallMiniMap.IsVisibleLocal)
{
var mapRect = smallMiniMap.GetClientRectCache;
_mapCenter = mapRect.Center.ToVector2Num();
_largeMap = false;
_mapScale = smallMiniMap.MapScale;
}
else if (_ingameUi.Map.LargeMap.IsVisibleLocal)
{
var largeMapWindow = LargeMapWindow;
_mapCenter = largeMapWindow.MapCenter;
_largeMap = true;
_mapScale = largeMapWindow.MapScale;
}
else
{
Expand All @@ -229,94 +219,72 @@ public override Job Tick()

public override void Render()
{
if (_largeMap == null ||
!GameController.InGame ||
Settings.DrawOnlyOnLargeMap && _largeMap != true)
return;
if (_largeMap == null || !GameController.InGame || Settings.DrawOnlyOnLargeMap && _largeMap != true) return;

if (!Settings.IgnoreFullscreenPanels &&
_ingameUi.FullscreenPanels.Any(x => x.IsVisible) ||
!Settings.IgnoreLargePanels &&
_ingameUi.LargePanels.Any(x => x.IsVisible))
return;

var playerRender = GameController?.Player?.GetComponent<Render>();
if (playerRender == null) return;
var playerPos = playerRender.PosNum.WorldToGrid();
var playerHeight = -playerRender.UnclampedHeight;

if (LargeMapWindow == null) return;
if (!Settings.IgnoreFullscreenPanels && _ingameUi.FullscreenPanels.Any(x => x.IsVisible) || !Settings.IgnoreLargePanels && _ingameUi.LargePanels.Any(x => x.IsVisible)) return;

var baseIcons = _iconListCache.Value;
if (baseIcons == null) return;

foreach (var icon in baseIcons)
using (Graphics.MapSurfaceClip())
{
if (icon?.Entity == null) continue;

if (!Settings.DrawMonsters && icon.Entity.Type == EntityType.Monster)
continue;

if (IgnoreCache.GetOrAdd(icon.Entity.Path, () => Ignored.Any(x => icon.Entity.Path.StartsWith(x))))
continue;

if (icon.Entity.Path.StartsWith(
"Metadata/Monsters/AtlasExiles/BasiliskInfluenceMonsters/BasiliskBurrowingViper", StringComparison.Ordinal)
&& icon.Entity.Rarity != MonsterRarity.Unique)
continue;

if (!icon.Show())
continue;

if (icon.HasIngameIcon &&
icon is not CustomIcon &&
(!Settings.DrawReplacementsForGameIconsWhenOutOfRange || icon.Entity.IsValid) &&
!Settings.AlwaysShownIngameIcons.Content.Any(x => global::MinimapIcons.IconsBuilder.IconsBuilder.GetRegex(x.Value).IsMatch(icon.Entity.Path)))
continue;

var iconGridPos = icon.GridPosition();
var position = _mapCenter +
DeltaInWorldToMinimapDelta(iconGridPos - playerPos,
(playerHeight + GameController.IngameState.Data.GetTerrainHeightAt(iconGridPos)) * PoeMapExtension.WorldToGridConversion);

var iconValueMainTexture = icon.MainTexture;
var size = iconValueMainTexture.Size;
var halfSize = size / 2f;
icon.DrawRect = new RectangleF(position.X - halfSize, position.Y - halfSize, size, size);
var drawRect = icon.DrawRect;
if (_largeMap == false && !_ingameUi.Map.SmallMiniMap.GetClientRectCache.Contains(drawRect))
continue;

Graphics.DrawImage(iconValueMainTexture.FileName, drawRect, iconValueMainTexture.UV, iconValueMainTexture.Color.ToSharpDx());
if (icon.BorderColor is { } borderColor)
{
Graphics.DrawFrame(drawRect, borderColor.ToSharpDx(), 1);
}

if (Settings.HighlightHiddenMonsters && icon.Hidden())
foreach (var icon in baseIcons)
{
var s = drawRect.Width * 0.1f;
drawRect.Inflate(-s, -s);

Graphics.DrawImage("Icons.png", drawRect,
SpriteHelper.GetUV(MapIconsIndex.LootFilterSmallWhiteCircle), Color.White);

drawRect.Inflate(s, s);
if (icon?.Entity == null) continue;

if (!Settings.DrawMonsters && icon.Entity.Type == EntityType.Monster) continue;

if (IgnoreCache.GetOrAdd(icon.Entity.Path, () => Ignored.Any(x => icon.Entity.Path.StartsWith(x)))) continue;

if (icon.Entity.Path.StartsWith("Metadata/Monsters/AtlasExiles/BasiliskInfluenceMonsters/BasiliskBurrowingViper", StringComparison.Ordinal) &&
icon.Entity.Rarity != MonsterRarity.Unique) continue;

if (!icon.Show()) continue;

if (icon.HasIngameIcon &&
icon is not CustomIcon &&
(!Settings.DrawReplacementsForGameIconsWhenOutOfRange || icon.Entity.IsValid) &&
!Settings.AlwaysShownIngameIcons.Content.Any(x => global::MinimapIcons.IconsBuilder.IconsBuilder.GetRegex(x.Value).IsMatch(icon.Entity.Path)) &&
!(icon.Entity.Type == EntityType.Monster && Settings.MonstersIgnoreMinimapIconComponent)) continue;

var iconValueMainTexture = icon.MainTexture;
var size = iconValueMainTexture.Size;
var halfSize = size / 2f;
var mapScreenPos = Graphics.GridToMap(icon.Entity.PosNum);

icon.DrawRect = new RectangleF(mapScreenPos.X - halfSize, mapScreenPos.Y - halfSize, size, size);
var drawRect = icon.DrawRect;

Graphics.DrawImageMap(iconValueMainTexture.FileName, iconValueMainTexture.UV, iconValueMainTexture.Color.ToSharpDx(), icon.Entity.PosNum, size);
if (icon.BorderColor is { } borderColor)
Graphics.DrawFrame(drawRect, borderColor.ToSharpDx(), 1);

if (Settings.HighlightHiddenMonsters && icon.Hidden())
{
var inset = size * 0.1f;
Graphics.DrawImageMap("Icons.png", SpriteHelper.GetUV(MapIconsIndex.LootFilterSmallWhiteCircle), Color.White, icon.Entity.PosNum, size - 2f * inset);
}

if (!string.IsNullOrEmpty(icon.Text))
{
var textPos = mapScreenPos.Translate(0, Settings.ZForText);
if (icon.BackgroundColor is { } bg)
{
var textColor = icon.TextColor?.ToSharpDx() ?? Color.White;
Graphics.DrawTextWithBackground(icon.Text, textPos, textColor, FontAlign.Center, bg.ToSharpDx());
}
else if (icon.TextColor is { } tc)
{
Graphics.DrawText(icon.Text, textPos, tc.ToSharpDx(), FontAlign.Center);
}
else
{
Graphics.DrawText(icon.Text, textPos, FontAlign.Center);
}
}
}

if (!string.IsNullOrEmpty(icon.Text))
Graphics.DrawText(icon.Text, position.Translate(0, Settings.ZForText), FontAlign.Center);
}
}

private const float CameraAngle = 38.7f * MathF.PI / 180;
private static readonly float CameraAngleCos = MathF.Cos(CameraAngle);
private static readonly float CameraAngleSin = MathF.Sin(CameraAngle);

private Vector2 DeltaInWorldToMinimapDelta(Vector2 delta, float deltaZ)
{
return _mapScale * Vector2.Multiply(new Vector2(delta.X - delta.Y, deltaZ - (delta.X + delta.Y)), new Vector2(CameraAngleCos, CameraAngleSin));
}
}

public static class Extensions
Expand Down