using System.Numerics; using Roboto.Core; using MemEntity = Roboto.Memory.Entity; namespace Roboto.Data; /// /// Maps raw Memory.Entity → Core.EntitySnapshot. Single source of truth for entity mapping. /// public static class EntityMapper { public static EntitySnapshot MapEntity(MemEntity e, Vector2 playerPos) { var pos = e.HasPosition ? new Vector2(e.X, e.Y) : Vector2.Zero; var dist = e.HasPosition ? Vector2.Distance(pos, playerPos) : float.MaxValue; var category = EntityClassifier.Classify(e.Path, e.Components); var rarity = (MonsterRarity)e.Rarity; return new EntitySnapshot { Id = e.Id, Path = e.Path, Metadata = e.Metadata, Category = category, ThreatLevel = MapThreatLevel(category, rarity), Rarity = rarity, Position = pos, Z = e.Z, DistanceToPlayer = dist, IsAlive = e.IsAlive || !e.HasVitals, LifeCurrent = e.LifeCurrent, LifeTotal = e.LifeTotal, IsTargetable = e.IsTargetable, Components = e.Components, ModNames = e.ModNames, TransitionName = AreaNameLookup.Resolve(e.TransitionName) ?? e.TransitionName, TransitionState = e.TransitionState, ActionId = e.ActionId, IsAttacking = e.IsAttacking, IsMoving = e.IsMoving, ItemBaseName = e.ItemBaseName, IsQuestItem = e.IsQuestItem, LabelOffset = e.LabelOffset, }; } public static MonsterThreatLevel MapThreatLevel(EntityCategory category, MonsterRarity rarity) { if (category != EntityCategory.Monster) return MonsterThreatLevel.None; return rarity switch { MonsterRarity.White => MonsterThreatLevel.Normal, MonsterRarity.Magic => MonsterThreatLevel.Magic, MonsterRarity.Rare => MonsterThreatLevel.Rare, MonsterRarity.Unique => MonsterThreatLevel.Unique, _ => MonsterThreatLevel.Normal, }; } }