core/iso/IsoEntity.cs
public class IsoEntity : Component {
	[Property, RequireComponent, Change(nameof(SetActivitySet))] public SkinnedModelRenderer Renderer {get; set;}
	[Property, RequireComponent, Change(nameof(SetCollider))] public BoxCollider Collider {get; set;}
	[Button] public void SnapToGrid() {
		WorldPosition = Grid.Snap(WorldPosition);
		WorldRotation = WorldRotation.Angles().WithYaw((WorldRotation.Yaw() + 30).SnapToGrid(60) - 30);
	}
	[Property] public IsoActivitySet ActivitySet {get; set;}
	[Property] public IsoTalkerScript TalkerScript {get; set;}
	[Property] public bool NoIsoTags {get; set;}
	[Property] public int Health {get; set;} = 40;
	[Property] public int MaxHealth {get; set;} = 40;

	private void SetActivitySet() {
		if (Renderer.IsValid()) {
			ActivitySet ??= ResourceLibrary.Get<IsoActivitySet>(Renderer.Model.ResourcePath.Replace(".vmdl", ".anm"));
			TalkerScript ??= ResourceLibrary.Get<IsoTalkerScript>(Renderer.Model.ResourcePath.Replace(".vmdl", ".tlk"));
		}
	}
	private void SetCollider() {
		if (!Collider.IsValid())
			return;
		Collider.Scale = new Vector3(25,25,5);
	}

	protected override void OnAwake() {
		Tags.Add("dynamic");
		if (!NoIsoTags) {
			Tags.Add("entity");
			Tags.Add("iso_entity");
		}
		if (ActivitySet.IsValid())
			Components.GetOrCreate<NpcAnimator>().Owner = this;
		if (TalkerScript.IsValid())
			Components.GetOrCreate<NpcTalker>().Owner = this;
		base.OnAwake();
	}
}