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
Binary file removed 4.0.0/MiniMapLibrary.dll
Binary file not shown.
Binary file removed 4.0.0/MiniMapMod.dll
Binary file not shown.
10 changes: 0 additions & 10 deletions 4.0.0/manifest.json

This file was deleted.

Binary file added 4.2.0/MiniMapLibrary.dll
Binary file not shown.
Binary file added 4.2.0/MiniMapMod.dll
Binary file not shown.
31 changes: 27 additions & 4 deletions 4.0.0/README.md → 4.2.0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ Adds a contemporary Minimap to the game.

- Implements a Mini Map In-Game.
- Show interactable items, shrines, teleporters, enemies and more.
- Shows dropped items and equipment as small cyan dots.
- Single and Multiplayer Compatible.
- Every icon is configurable for color, size and can be toggled on/off.
- Works with all DLCs (Survivors of the Void, Seekers of the Storm, Alloyed Collective, Hallowed Concepts).

#### Available Icons
| Icon | Available | Configurable |
Expand All @@ -32,27 +34,33 @@ Adds a contemporary Minimap to the game.
| Fans/Special | ✔ | ✔ |
| Portals | ✔ | ✔ |
| Totems | ✔ | ✔ |
| Dropped Items | ✔ | ✔ |
| Dropped Items / Equipment / Lunar Coins | ✔ | ✔ |
| Command Cubes / Void Potentials | ✔ | ✔ |
| Newt Altar | ✔ | ✔ |
| Timed Chests | ❌ | ❌ |
| Stealth Chests | ❌ | ❌ |
| Timed Chests | ✔ (off by default) | ✔ |
| Stealth Chests | ✔ (off by default) | ✔ |

### Showcase

![](https://i.imgur.com/f4VwvNF.jpg)

### Dependencies
- BepInEx
- HookGenPatcher
- RoR2BepInExPack

### Manual Installation
- Place MiniMapLibrary.dll into your BepInEx/plugins folder.
- Place MiniMapMod.dll into your BepInEx/plugins folder.
- BepInExPack 5.4.2122 needs Newtonsoft.Json, which the game doesn't ship anymore. RoR2BepInExPack provides it, so install that too (mod managers do this automatically).

### How to Use
- Use 'M' to hide or show the minimap.
- Use 'M' to hide or show the minimap.
- Use '=' and '-' to zoom in and out.

### Troubleshooting
- Toggle 'M' to hide and show minimap to force a refresh and/or a re-draw if something wonky is happening on the minimap.
- Set `LogLevel = debug` under `[Settings.General]` in the config and play a stage. Every few seconds the log shows what the minimap found and drew, which helps a lot with bug reports.

### Config
BepInEx Config. Each icon is individually configurable.
Expand All @@ -67,6 +75,8 @@ BepInEx Config. Each icon is individually configurable.
- Elevation Marker Height
- Elevation Marker Offset

Map size, position, camera rotation, zoom keys and scan intervals are configurable too.

### Upcoming Changes
None - Final Release

Expand All @@ -76,8 +86,21 @@ If you have an issue, discover a bug, or have a recommendation please file an is
### Collaborators
Huge thanks to these awesome people who assisted in creating awesome features for this mod
[Arcafanetiz](https://github.com/Arcafanetiz)
[winterofhell](https://github.com/winterofhell)

### Change Log
Release 4.2.0
- updated for the current game version and all DLCs (Seekers of the Storm, Alloyed Collective, Hallowed Concepts)
- dropped items, equipment, lunar coins, command cubes and void potentials now show up as small light-cyan dots, and disappear as soon as they're picked up
- all icons are about 10% bigger, old configs that still use the default sizes get the new ones automatically
- objects are now tracked through the game's own registries instead of rescanning the whole scene, so no more stutter every few seconds
- timed and stealth chests can be turned on in the config (still off by default)
- added End of the Cycle enemies
- map no longer overlaps the objective panel
- added map size, position and rotation settings
- added debug logging for bug reports
- fixed duplicate icons and icons sticking around after objects were destroyed

Release 4.0.0
- Finally added newt altars to the search, since everyone has been begging for it for literally years

Expand Down
File renamed without changes
11 changes: 11 additions & 0 deletions 4.2.0/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "MiniMapMod",
"version_number": "4.2.0",
"website_url": "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/artyredd/MiniMapMod",
"description": "A configurable HUD minimap showing chests, shops, shrines, teleporters, drones, players, enemies and dropped items, with elevation arrows and zoom. Supports all DLCs.",
"dependencies": [
"bbepis-BepInExPack-5.4.2122",
"RiskofThunder-HookGenPatcher-1.2.9",
"RiskofThunder-RoR2BepInExPack-1.46.0"
]
}
4 changes: 4 additions & 0 deletions MiniMapLibrary/Basic/Dimension2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public float Width
get => _Width;
set
{
if (_Width == value)
return;
_Width = value;
OnChanged?.Invoke(this);
}
Expand All @@ -24,6 +26,8 @@ public float Height
get => _Height;
set
{
if (_Height == value)
return;
_Height = value;
OnChanged?.Invoke(this);
}
Expand Down
51 changes: 51 additions & 0 deletions MiniMapLibrary/Basic/MapProjection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using UnityEngine;

namespace MiniMapLibrary
{
public static class MapProjection
{
// Use one scale on both axes so bearings remain accurate on narrow stages.
public static float GetScale(Range3D bounds, Dimension2D size, float zoom, float worldRadius = 0f)
{
float width = Numeric.Clamp(size.Width, 1f, 4096f, 180f);
float height = Numeric.Clamp(size.Height, 1f, 4096f, 180f);
zoom = Numeric.Clamp(zoom, 0.1f, 20f, 1f);

if (Numeric.IsFinite(worldRadius) && worldRadius > 0f)
return Math.Min(width, height) * zoom / (2f * Math.Max(worldRadius, 1f));

float xSpan = Numeric.Clamp(bounds?.X.Difference ?? 0f, 100f, 1000000f, 100f);
float zSpan = Numeric.Clamp(bounds?.Z.Difference ?? 0f, 100f, 1000000f, 100f);
return Math.Min(width / xSpan, height / zSpan) * zoom;
}

public static Vector2 ProjectOffset(Vector3 position, Vector3 origin, float scale)
{
return new Vector2((position.x - origin.x) * scale, (position.z - origin.z) * scale);
}

public static bool TryProject(Vector3 position, Vector3 origin, float scale, float sine, float cosine, out Vector2 result)
{
result = Vector2.zero;
if (!Numeric.IsFinite(position.x) || !Numeric.IsFinite(position.y) || !Numeric.IsFinite(position.z)
|| !Numeric.IsFinite(origin.x) || !Numeric.IsFinite(origin.y) || !Numeric.IsFinite(origin.z)
|| !Numeric.IsFinite(scale) || scale <= 0f || !Numeric.IsFinite(sine) || !Numeric.IsFinite(cosine))
return false;
result = Rotate(ProjectOffset(position, origin, scale), sine, cosine);
return Numeric.IsFinite(result.x) && Numeric.IsFinite(result.y);
}

public static bool IsInside(Vector2 position, float sine, float cosine, float halfWidth, float halfHeight, float padding)
{
return IsInside(Rotate(position, sine, cosine), halfWidth, halfHeight, padding);
}

public static Vector2 Rotate(Vector2 position, float sine, float cosine) => new(
position.x * cosine - position.y * sine, position.x * sine + position.y * cosine);

public static bool IsInside(Vector2 position, float halfWidth, float halfHeight, float padding) =>
Numeric.IsFinite(position.x) && Numeric.IsFinite(position.y)
&& Math.Abs(position.x) <= halfWidth + padding && Math.Abs(position.y) <= halfHeight + padding;
}
}
14 changes: 14 additions & 0 deletions MiniMapLibrary/Basic/Numeric.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;

namespace MiniMapLibrary
{
public static class Numeric
{
public static bool IsFinite(float value) => !float.IsNaN(value) && !float.IsInfinity(value);

public static float Clamp(float value, float minimum, float maximum, float fallback)
{
return IsFinite(value) ? Math.Max(minimum, Math.Min(maximum, value)) : fallback;
}
}
}
34 changes: 10 additions & 24 deletions MiniMapLibrary/Basic/Range.cs
Original file line number Diff line number Diff line change
@@ -1,43 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace MiniMapLibrary
{
public class Range1D
{
public float Min { get; set; }

public float Max { get; set; }
public float Min { get; set; } = float.PositiveInfinity;
public float Max { get; set; } = float.NegativeInfinity;

/// <summary>
/// Equivalent to <see cref="Range1D.Max"/> - <see cref="Min"/>
/// </summary>
public float Difference => Max - Min;

/// <summary>
/// Equivalent to -<see cref="Min"/>(neg)
/// </summary>
public float Offset => -Min;
public bool IsValid => Numeric.IsFinite(Min) && Numeric.IsFinite(Max) && Min <= Max;
public float Difference => IsValid ? Max - Min : 0f;
public float Offset => IsValid ? -Min : 0f;

public void CheckValue(float value)
{
if (!Numeric.IsFinite(value))
return;

if (value < Min)
{
Min = value;
return;
}
if (value > Max)
{
Max = value;
return;
}
}

public void Clear()
{
Min = float.MaxValue;
Max = float.MinValue;
Min = float.PositiveInfinity;
Max = float.NegativeInfinity;
}
}
}
13 changes: 4 additions & 9 deletions MiniMapLibrary/Basic/Range3D.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

namespace MiniMapLibrary
{
public class Range3D
{
public Range1D X { get; set; } = new Range1D();

public Range1D Y { get; set; } = new Range1D();

public Range1D Z { get; set; } = new Range1D();
public Range1D X { get; set; } = new();
public Range1D Y { get; set; } = new();
public Range1D Z { get; set; } = new();

public void CheckValue(Vector3 position)
{
X.CheckValue(position.x);
//Y.CheckValue(position.y);
Y.CheckValue(position.y);
Z.CheckValue(position.z);
}

Expand Down
54 changes: 28 additions & 26 deletions MiniMapLibrary/Basic/Timer.cs
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
using System;
using System.Collections.Generic;
using System.Text;
using System;

#nullable enable
namespace MiniMapLibrary
{
public class Timer
{
public float Duration { get; private set; } = 1.0f;
public float Duration { get; }
public float Value { get; set; }
public event Action<object?>? OnFinished;
public object? State { get; set; }
public bool AutoReset { get; set; }
public bool Started { get; set; } = true;
public bool Expired => Value <= 0;
public bool Expired => Value <= 0f;

public Timer(float duration, bool autoReset = true)
{
if (!Numeric.IsFinite(duration) || duration <= 0f)
throw new ArgumentOutOfRangeException(nameof(duration));

Duration = duration;
this.AutoReset = autoReset;
AutoReset = autoReset;
Value = duration;
}

public void Update(float deltaTime)
{
if (Started)
if (!Started || !Numeric.IsFinite(deltaTime) || deltaTime <= 0f)
return;

Value -= deltaTime;
if (!Expired)
return;

if (AutoReset)
{
// Keep fractional time without firing repeatedly after a long frame.
Value = Duration + Value % Duration;
if (Value <= 0f)
Value = Duration;
}
else
{
Value -= deltaTime;

if (Expired)
{
if (AutoReset)
{
Reset();
}
else
{
Started = false;
}

OnFinished?.Invoke(State);
}
Value = 0f;
Started = false;
}

OnFinished?.Invoke(State);
}

public void Start() => Started = true;
Expand All @@ -51,9 +56,6 @@ public void Reset()
Started = AutoReset;
}

public override string ToString()
{
return $"{typeof(Timer).Name} [{Value}/{Duration}s] [{nameof(AutoReset)}: {AutoReset}] [{nameof(Started)}: {Started}] [{nameof(Expired)}: {Expired}]";
}
public override string ToString() => $"Timer [{Value}/{Duration}s] [AutoReset: {AutoReset}] [Started: {Started}]";
}
}
7 changes: 7 additions & 0 deletions MiniMapLibrary/Config/Interfaces/IMutableConfigEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace MiniMapLibrary.Config
{
public interface IMutableConfigEntry<T> : IConfigEntry<T>
{
new T Value { get; set; }
}
}
10 changes: 4 additions & 6 deletions MiniMapLibrary/Helpers/Sprites.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,17 @@ public static class Sprites
{
public static GameObject CreateIcon(Sprite sprite, float width, float height, Color color)
{
GameObject icon = new GameObject();

var transform = icon.AddComponent<RectTransform>();
GameObject icon = new GameObject("Icon", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
var transform = (RectTransform)icon.transform;

transform.sizeDelta = new Vector2(width, height);

icon.AddComponent<CanvasRenderer>();

var image = icon.AddComponent<Image>();
var image = icon.GetComponent<Image>();

image.sprite = sprite;

image.color = color;
image.raycastTarget = false;

return icon;
}
Expand Down
Loading