Trader Compass
Wandering traders near you show on the compass. Range on Settings ▸ Mods. Console: traders.
Wandering traders near you show on the compass. Range on Settings ▸ Mods. Console: traders.
Mod id example.tradercompass, side client.
A code mod: build it with dotnet build (see Making mods) and put the output folder in the game's Mods folder.
mod.json
{
"id": "example.tradercompass",
"name": "Trader Compass",
"version": "1.1",
"author": "Seeds & Circuits",
"side": "client",
"description": "Wandering traders near you show on the compass. Range on Settings ▸ Mods. Console: traders."
}
TraderCompass.cs
using System.Collections.Generic;
using System.Linq;
using SeedsAndCircuits.DebugConsole;
using SeedsAndCircuits.Mods;
using SeedsAndCircuits.Player;
using SeedsAndCircuits.Player.UI;
using SeedsAndCircuits.Town;
using UnityEngine;
using Compass = SeedsAndCircuits.Player.UI.Compass; // UnityEngine has a Compass too (the device sensor)
namespace TraderCompass
{
/// <summary>
/// Shows wandering traders near the player on the compass, as gold diamonds. Side "client": it only changes this
/// player's screen, so it works on any host (and a host offers it to players who join).
/// </summary>
public sealed class TraderCompass : Mod
{
static readonly Color Gold = new Color(1f, 0.78f, 0.25f, 1f);
static ModSlider s_Range;
Sprite _icon;
Texture2D _texture;
public override void OnLoad()
{
_icon = MakeDiamond(out _texture);
// Settings ▸ Mods: how far away traders show.
s_Range = AddSlider("range", "Show traders within (m)", 50f, 1000f, 300f, 50f);
Compass.CollectMarkers += AddTraders;
}
public override void OnUnload()
{
Compass.CollectMarkers -= AddTraders;
if (_icon != null)
Object.Destroy(_icon);
if (_texture != null)
Object.Destroy(_texture);
}
void AddTraders(List<Compass.ExtraMarker> markers)
{
PlayerSpawn local = PlayerSpawn.Local;
if (local == null)
return;
Vector3 me = local.Feet;
foreach (TownNpc npc in NearbyTraders(me))
markers.Add(new Compass.ExtraMarker(npc.transform.position, Gold, _icon));
}
/// <summary>Wandering traders (traders without a home) within range, nearest first.</summary>
static IEnumerable<TownNpc> NearbyTraders(Vector3 from) =>
TownNpc.All.Where(npc => npc != null && npc.HomeId == 0 && npc.Character != null && npc.Character.IsTrader &&
(npc.transform.position - from).sqrMagnitude <= Range * Range)
.OrderBy(npc => (npc.transform.position - from).sqrMagnitude);
static float Range => s_Range != null ? s_Range.Value : 300f;
/// <summary>A small gold diamond, drawn in code (no image files needed).</summary>
static Sprite MakeDiamond(out Texture2D texture)
{
const int size = 32;
texture = new Texture2D(size, size, TextureFormat.RGBA32, false) { name = "Trader Diamond", filterMode = FilterMode.Bilinear };
var pixels = new Color32[size * size];
float c = (size - 1) * 0.5f;
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
float d = Mathf.Abs(x - c) + Mathf.Abs(y - c);
float a = Mathf.Clamp01(c - d); // soft edge
pixels[y * size + x] = new Color(1f, 1f, 1f, a);
}
}
texture.SetPixels32(pixels);
texture.Apply();
return Sprite.Create(texture, new Rect(0, 0, size, size), new Vector2(0.5f, 0.5f), 100f);
}
[ConsoleCommandAttribute("traders", "Wandering traders near you, nearest first.", Local = true)]
static string List()
{
PlayerSpawn local = PlayerSpawn.Local;
if (local == null)
return "Not in a world.";
List<TownNpc> traders = NearbyTraders(local.Feet).ToList();
if (traders.Count == 0)
return $"No wandering traders within {Range:0} m.";
return string.Join("\n", traders.Select(npc =>
$"{npc.NpcName}: {Vector3.Distance(npc.transform.position, local.Feet):0} m"));
}
[ConsoleCommandAttribute("traders.range", "How far away (m) traders show on the compass (also on Settings ▸ Mods).", Usage = "[meters]", Local = true)]
static string RangeCommand(ConsoleArgs args)
{
if (args.Count > 0 && s_Range != null)
s_Range.Value = args.Float(0);
return $"Traders show within {Range:0} m.";
}
}
}
TraderCompass.csproj
<Project Sdk="Microsoft.NET.Sdk">
<!-- Build settings and game references: ../Mod.props. Output: bin/Trader Compass/ -->
<PropertyGroup>
<AssemblyName>TraderCompass</AssemblyName>
<ModFolder>Trader Compass</ModFolder>
</PropertyGroup>
<Import Project="../Mod.props" />
</Project>